1 {-# LANGUAGE RankNTypes
5 module Test
.ValueSimplex
where
6 import Prelude
hiding (all)
7 import Control
.Applicative
((<$>), (<*>))
8 import Data
.Foldable
(all)
9 import Data
.Function
(on
)
11 import qualified Data
.Map
as Map
12 import Data
.Maybe (fromJust)
13 import Data
.Ratio ((%))
15 import qualified Data
.Set
as Set
16 import Numeric
.Matrix
(MatrixElement
)
17 import Test
.QuickCheck
18 import Test
.QuickCheck
.All
21 import Util
.Function
((.!), (....))
22 import Util
.Monad
((>>=*))
23 import Util
.Set
(distinctPairs
, distinctPairsOneWay
)
26 --------------------------------------------------------------------------------
28 instance Fractional a
=> Fractional
(Positive a
) where
29 Positive x
/ Positive y
= Positive
$ x
/ y
30 recip (Positive x
) = Positive
$ recip x
31 fromRational = Positive
. fromRational
33 liftEquivToValueSimplex
:: (Ord a
, Num b
) =>
34 (b
-> b
-> Bool) -> ValueSimplex a b
-> ValueSimplex a b
-> Bool
35 liftEquivToValueSimplex eq vs vs
' = let xs
= nodes vs
37 && ( flip all (distinctPairs xs
) $ \(x
, y
) ->
38 vsLookup vs x y `eq` vsLookup vs
' x y
41 instance (Ord a
, Num b
, RelApproxEq b
) => RelApproxEq
(ValueSimplex a b
) where
42 (~~
=) = liftEquivToValueSimplex
(~~
=)
44 validify
:: (Ord a
, Fractional b
) => a
-> (a
-> a
-> b
) -> a
-> a
-> b
46 if y
< z || y
== x || z
== x
48 else f z y
* f y x
* f x z
/ (f z x
* f x y
)
51 (Arbitrary a
, CoArbitrary a
, Ord a
, Arbitrary b
, Ord b
, Fractional b
) =>
52 Arbitrary
(ValueSimplex a b
) where
56 xs
<- arbitrarySetOfSizeSqrtOrMin
2
57 return $ fromFunction
(validify x
$ getPositive
.! f
) xs
59 --------------------------------------------------------------------------------
61 withArbitraryNode
:: (Ord a
, Show a
, Testable p
)
62 => ValueSimplex a b
-> (a
-> p
) -> Property
63 withArbitraryNode
= withArbitraryElement
. nodes
65 with2ArbitraryNodes
:: (Ord a
, Show a
, Testable p
)
66 => ValueSimplex a b
-> (a
-> a
-> p
) -> Property
67 with2ArbitraryNodes
= with2ArbitraryElements
. nodes
69 testList
:: Testable p
=> [a
-> p
] -> a
-> Property
70 testList ts x
= foldr (.&&.) (property
True) $ map ($ x
) ts
72 --------------------------------------------------------------------------------
74 vsLookup_fromFunction
::
75 (Arbitrary a
, CoArbitrary a
, Ord a
, Show a
, Arbitrary b
, Eq b
, Num b
) =>
76 Blind
(a
-> a
-> b
) -> Property
77 vsLookup_fromFunction
(Blind f
) = forAll arbitrarySetOfSizeSqrt
$ \xs
->
78 with2ArbitraryElements xs
$ \x y
->
79 vsLookup
(fromFunction f xs
) x y
== f x y
81 prop_vsLookup_fromFunction_Double
::
82 (Arbitrary a
, CoArbitrary a
, Ord a
, Show a
) =>
83 Blind
(a
-> a
-> Double) -> Property
84 prop_vsLookup_fromFunction_Double
= vsLookup_fromFunction
87 (Arbitrary a
, CoArbitrary a
, Ord a
, Show a
, Arbitrary b
) =>
88 Blind
(a
-> a
-> b
) -> Property
89 nodes_fromFunction
(Blind f
) = forAll
(arbitrarySetOfSizeSqrtOrMin
2) $
90 \xs
-> nodes
(fromFunction f xs
) == xs
92 prop_nodes_fromFunction_Double
:: (Arbitrary a
, CoArbitrary a
, Ord a
, Show a
)
93 => Blind
(a
-> a
-> Double) -> Property
94 prop_nodes_fromFunction_Double
= nodes_fromFunction
96 prop_empty
:: (Arbitrary a
, CoArbitrary a
, Ord a
, Show a
)
97 => Blind
(a
-> a
-> Double) -> Bool
98 prop_empty
(Blind f
) = isEmpty
$ fromFunction f Set
.empty
100 --------------------------------------------------------------------------------
102 fromFunction_vsLookup
:: (Ord a
, Eq b
, Num b
) => ValueSimplex a b
-> Bool
103 fromFunction_vsLookup vs
= fromFunction
(vsLookup vs
) (nodes vs
) == vs
105 values_positive
:: (Ord a
, Show a
, Ord b
, Num b
) => ValueSimplex a b
-> Property
106 values_positive vs
= with2ArbitraryNodes vs
$ (0 <) .! vsLookup vs
108 non_degenerate
:: Ord a
=> ValueSimplex a b
-> Bool
109 non_degenerate
= (2 <=) . Set
.size
. nodes
111 exact_ValueSimplex_validity_tests
:: (Ord a
, Show a
, Ord b
, Num b
)
112 => ValueSimplex a b
-> Property
113 exact_ValueSimplex_validity_tests
= testList
114 [ printTestCase
"fromFunction_vsLookup" . fromFunction_vsLookup
115 , printTestCase
"values_positive" . values_positive
116 , printTestCase
"non_degenerate" . non_degenerate
117 , printTestCase
"non-empty" . not . isEmpty
120 prop_exact_ValueSimplex_validity_tests_Double
:: (Ord a
, Show a
)
121 => ValueSimplex a
Double -> Property
122 prop_exact_ValueSimplex_validity_tests_Double
=
123 exact_ValueSimplex_validity_tests
125 --------------------------------------------------------------------------------
127 approx_Double_exact_Rational
::
128 forall t
. Testable t
=>
129 (forall b
. (Arbitrary b
, Ord b
, Show b
, Fractional b
, MatrixElement b
) =>
130 (b
-> b
-> Bool) -> ValueSimplex
Integer b
-> t
) ->
132 approx_Double_exact_Rational test
=
133 (test
(~~
=) :: ValueSimplex
Integer Double -> t
)
134 .&&. (test
(==) :: ValueSimplex
Integer Rational -> t
)
136 ok
:: (Ord a
, Ord b
, Num b
) => (b
-> b
-> Bool) -> ValueSimplex a b
-> Bool
137 ok
= (OK
==) .! status
139 could_have_been_arbitrary
:: (Ord a
, Show a
, Fractional b
) =>
140 (b
-> b
-> Bool) -> ValueSimplex a b
-> Property
141 could_have_been_arbitrary eq vs
= let xs
= nodes vs
in
142 withArbitraryNode vs
$ \x
->
143 liftEquivToValueSimplex eq vs
$ fromFunction
(validify x
$ vsLookup vs
) xs
145 approx_ValueSimplex_validity_tests
:: (Ord a
, Show a
, Ord b
, Fractional b
)
146 => (b
-> b
-> Bool) -> ValueSimplex a b
-> Property
147 approx_ValueSimplex_validity_tests
= curry $ testList
$ map uncurry
148 [ printTestCase
"ok" .! ok
149 , printTestCase
"could_have_been_arbitrary" .! could_have_been_arbitrary
152 prop_approx_ValueSimplex_validity_tests
:: Property
153 prop_approx_ValueSimplex_validity_tests
=
154 approx_Double_exact_Rational approx_ValueSimplex_validity_tests
156 --------------------------------------------------------------------------------
158 prop_price_self
:: (Ord a
, Show a
) => ValueSimplex a
Double -> Property
159 prop_price_self vs
= withArbitraryNode vs
$ \x
-> price vs x x
== 1
161 compoundPrice
:: (Ord a
, Eq b
, Fractional b
)
162 => ValueSimplex a b
-> a
-> a
-> a
-> b
163 compoundPrice vs x y z
= ((*) `on`
uncurry (price vs
)) (x
, y
) (y
, z
)
165 equal_values
:: (Ord a
, Show a
, Eq b
, Fractional b
) =>
166 (b
-> b
-> Bool) -> ValueSimplex a b
-> Property
167 equal_values eq vs
= with2ArbitraryNodes vs
$ \x y
->
168 (vsLookup vs x y
* price vs x y
) `eq` vsLookup vs y x
170 prop_equal_values
:: Property
171 prop_equal_values
= approx_Double_exact_Rational equal_values
173 prices_reciprocal
:: (Ord a
, Show a
, Eq b
, Fractional b
) =>
174 (b
-> b
-> Bool) -> ValueSimplex a b
-> Property
175 prices_reciprocal eq vs
= with2ArbitraryNodes vs
$ \x y
->
176 compoundPrice vs x y x `eq`
1
178 prop_prices_reciprocal
:: Property
179 prop_prices_reciprocal
= approx_Double_exact_Rational prices_reciprocal
181 price_cycle
:: (Ord a
, Show a
, Eq b
, Fractional b
) =>
182 (b
-> b
-> Bool) -> ValueSimplex a b
-> Property
183 price_cycle eq vs
= with3ArbitraryElements
(nodes vs
) $ \x y z
->
184 compoundPrice vs x y z `eq` price vs x z
186 prop_price_cycle
:: Property
187 prop_price_cycle
= approx_Double_exact_Rational price_cycle
189 prop_hybridPrice_correct
:: (Ord a
, Show a
) => ValueSimplex a
Double -> Property
190 prop_hybridPrice_correct vs
= with2ArbitraryNodes vs
$ \x y
->
191 withArbitraryNode vs
$ \z
->
192 (hybridPrice vs x y z
) ^
2 ~~
= price vs x z
* price vs y z
194 --------------------------------------------------------------------------------
196 nodeValue_correct
:: (Ord a
, Show a
, Num b
)
197 => (b
-> b
-> Bool) -> ValueSimplex a b
-> Property
198 nodeValue_correct eq vs
= let xs
= nodes vs
in
199 withArbitraryElementAndRest xs
$ \x xs
' ->
200 nodeValue vs x `eq` Set
.foldr ((+) . vsLookup vs x
) 0 xs
'
202 prop_nodeValue_correct
:: Property
203 prop_nodeValue_correct
= approx_Double_exact_Rational nodeValue_correct
205 linkValueSquared_correct
:: (Ord a
, Show a
, Eq b
, Num b
)
206 => ValueSimplex a b
-> Property
207 linkValueSquared_correct vs
= with2ArbitraryNodes vs
$ \x y
->
208 linkValueSquared vs x y
== vsLookup vs x y
* vsLookup vs y x
210 prop_linkValueSquared_correct_Double
:: (Ord a
, Show a
)
211 => ValueSimplex a
Double -> Property
212 prop_linkValueSquared_correct_Double
= linkValueSquared_correct
214 prop_halfLinkValue_correct
:: (Ord a
, Show a
)
215 => ValueSimplex a
Double -> Property
216 prop_halfLinkValue_correct vs
= with2ArbitraryNodes vs
$ \x y
->
217 (halfLinkValue vs x y
) ^
2 ~~
= linkValueSquared vs x y
219 --------------------------------------------------------------------------------
222 (Ord a
, Show a
, Arbitrary b
, Ord b
, Show b
, Fractional b
, MatrixElement b
)
223 => ValueSimplex a b
-> Property
224 sell_too_much vs
= with2ArbitraryNodes vs
$ \x0 x1
->
225 forAll
(arbitrary `suchThat`
(<= - supremumSellable vs x0 x1
)) $ \q0
->
226 property
$ \q1
-> vsLookup
(update vs x0 q0 x1 q1
) x0 x1
<= 0
228 prop_sell_too_much_Double
:: (Ord a
, Show a
)
229 => ValueSimplex a
Double -> Property
230 prop_sell_too_much_Double
= sell_too_much
233 (Ord a
, Show a
, Arbitrary b
, Ord b
, Show b
, Fractional b
, MatrixElement b
)
234 => ValueSimplex a b
-> a
-> a
-> Gen b
235 arbitrarySellable vs x0 x1
=
236 arbitrary `suchThat`
(> - supremumSellable vs x0 x1
)
238 withSomeArbitraryUpdateParameters
::
240 , Arbitrary b
, Ord b
, Show b
, Fractional b
, MatrixElement b
243 => ValueSimplex a b
-> (a
-> b
-> a
-> p
) -> Property
244 withSomeArbitraryUpdateParameters vs t
= with2ArbitraryNodes vs
$ \x0 x1
->
245 forAll
(arbitrarySellable vs x0 x1
) $ flip (t x0
) x1
247 breakEven_sellable
::
248 (Ord a
, Show a
, Arbitrary b
, Ord b
, Show b
, Fractional b
, MatrixElement b
)
249 => ValueSimplex a b
-> Property
250 breakEven_sellable vs
= withSomeArbitraryUpdateParameters vs
$ \x0 q0 x1
->
251 breakEven vs x0 q0 x1
> - supremumSellable vs x1 x0
253 prop_breakEven_sellable_Double
:: (Ord a
, Show a
)
254 => ValueSimplex a
Double -> Property
255 prop_breakEven_sellable_Double
= breakEven_sellable
258 (Ord a
, Show a
, Arbitrary b
, Ord b
, Show b
, Fractional b
, MatrixElement b
)
259 => (b
-> b
-> Bool) -> ValueSimplex a b
-> Property
260 update_symmetric eq vs
= with2ArbitraryNodes vs
$ \x0 x1
-> property
$ \q0 q1
->
261 liftEquivToValueSimplex eq
(update vs x0 q0 x1 q1
) (update vs x1 q1 x0 q0
)
263 prop_update_symmetric
:: Property
264 prop_update_symmetric
= approx_Double_exact_Rational update_symmetric
266 prop_update_zero
:: Property
267 prop_update_zero
= approx_Double_exact_Rational
$ \eq vs
->
268 with2ArbitraryNodes vs
$ \x0 x1
->
269 liftEquivToValueSimplex eq vs
$ update vs x0
0 x1
0
271 withArbitraryUpdateParameters
::
273 , Arbitrary b
, Ord b
, Show b
, Fractional b
, MatrixElement b
276 => ValueSimplex a b
-> (a
-> b
-> a
-> b
-> p
) -> Property
277 withArbitraryUpdateParameters vs t
=
278 withSomeArbitraryUpdateParameters vs
$ \x0 q0 x1
->
279 forAll
(arbitrarySellable vs x1 x0
) $ t x0 q0 x1
281 prop_update_exact_ValueSimplex_validity_tests_Double
:: (Ord a
, Show a
)
282 => ValueSimplex a
Double -> Property
283 prop_update_exact_ValueSimplex_validity_tests_Double vs
=
284 withArbitraryUpdateParameters vs
$
285 exact_ValueSimplex_validity_tests
.... update vs
287 prop_update_approx_ValueSimplex_validity_tests
:: Property
288 prop_update_approx_ValueSimplex_validity_tests
=
289 approx_Double_exact_Rational
$ \eq vs
->
290 withArbitraryUpdateParameters vs
$
291 approx_ValueSimplex_validity_tests eq
.... update vs
293 prop_update_nodes_unchanged_Double
:: (Ord a
, Show a
)
294 => ValueSimplex a
Double -> Property
295 prop_update_nodes_unchanged_Double vs
= withArbitraryUpdateParameters vs
$
296 ((nodes vs
==) . nodes
) .... update vs
298 prop_update_changed_nodeValue
:: Property
299 prop_update_changed_nodeValue
= approx_Double_exact_Rational
$ \eq vs
->
300 withArbitraryUpdateParameters vs
$ \x0 q0 x1 q1
->
301 let vs
' = update vs x0 q0 x1 q1
in
302 nodeValue vs
' x0 `eq`
(nodeValue vs x0
+ q0
)
303 && nodeValue vs
' x1 `eq`
(nodeValue vs x1
+ q1
)
305 prop_update_unchanged_nodeValue
:: Property
306 prop_update_unchanged_nodeValue
= approx_Double_exact_Rational
$ \eq vs
->
307 withArbitraryUpdateParameters vs
$ \x0 q0 x1 q1
->
308 withArbitraryElement
(Set
.difference
(nodes vs
) $ Set
.fromList
[x0
, x1
]) $
309 \x
-> nodeValue
(update vs x0 q0 x1 q1
) x `eq` nodeValue vs x
311 prop_uniform_value_change
:: Property
312 prop_uniform_value_change
= approx_Double_exact_Rational
$ \eq vs
->
313 withArbitraryUpdateParameters vs
$ \x0 q0 x1 q1
->
314 with2ArbitraryNodes vs
$ \x y
->
316 ss
= linkValueSquared vs
317 ss
' = linkValueSquared
$ update vs x0 q0 x1 q1
320 ||
compare (ss
' x y
) (ss x y
) == compare (ss
' x0 x1
) (ss x0 x1
)
322 prop_profit_Double
:: (Ord a
, Show a
) => ValueSimplex a
Double -> Property
323 prop_profit_Double vs
= withSomeArbitraryUpdateParameters vs
$ \x0 q0 x1
->
324 forAll
(arbitrary `suchThat`
(> breakEven vs x0 q0 x1
)) $ \q1
->
325 linkValueSquared
(update vs x0 q0 x1 q1
) x0 x1
> linkValueSquared vs x0 x1
327 prop_breakEven
:: Property
328 prop_breakEven
= approx_Double_exact_Rational
$ \eq vs
->
329 withSomeArbitraryUpdateParameters vs
$ \x0 q0 x1
->
330 linkValueSquared
(update vs x0 q0 x1
(breakEven vs x0 q0 x1
)) x0 x1
331 `eq` linkValueSquared vs x0 x1
333 prop_loss_Double
:: (Ord a
, Show a
) => ValueSimplex a
Double -> Property
334 prop_loss_Double vs
= withSomeArbitraryUpdateParameters vs
$ \x0 q0 x1
->
335 forAll
(choose
(- supremumSellable vs x1 x0
, breakEven vs x0 q0 x1
)) $ \q1
->
336 linkValueSquared
(update vs x0 q0 x1 q1
) x0 x1
< linkValueSquared vs x0 x1
338 arbitrarilyUpdatedValueSimplex
::
339 (Ord a
, Show a
, Arbitrary b
, Ord b
, Show b
, Fractional b
, MatrixElement b
)
340 => ValueSimplex a b
-> Gen
(ValueSimplex a b
)
341 arbitrarilyUpdatedValueSimplex vs
= let xs
= nodes vs
in
345 x0
<- elements
$ Set
.toList xs
346 x1
<- elements
$ Set
.toList
$ Set
.delete x0 xs
347 q0
<- arbitrarySellable vs x0 x1
348 q1
<- arbitrarySellable vs x1 x0
349 return $ update vs x0 q0 x1 q1
351 longrun_validity
:: (Ord a
, Show a
)
352 => (ValueSimplex a
Double -> Gen
(ValueSimplex a
Double))
353 -> ValueSimplex a
Double -> Property
354 longrun_validity upd vs
=
358 (vs
>>=* replicate k upd
)
359 $ approx_ValueSimplex_validity_tests
(~~
=)
361 prop_longrun_validity
:: (Ord a
, Show a
) => ValueSimplex a
Double -> Property
362 prop_longrun_validity
= longrun_validity arbitrarilyUpdatedValueSimplex
364 --------------------------------------------------------------------------------
366 prop_multiUpdate_nodes_unchanged
:: Ord a
367 => ValueSimplex a
Double -> Blind
(a
-> Double) -> Bool
368 prop_multiUpdate_nodes_unchanged vs
(Blind f
) =
369 nodes
(multiUpdate vs f
) == nodes vs
371 prop_multiUpdate_nodeValue
:: Property
372 prop_multiUpdate_nodeValue
= approx_Double_exact_Rational
$ \eq vs
->
373 property
$ \(Blind f
') -> let f
= getPositive
. f
' in
374 withArbitraryNode vs
$
375 eq
<$> nodeValue
(multiUpdate vs f
) <*> f
377 prop_multiUpdate_uniform_value_change
:: Property
378 prop_multiUpdate_uniform_value_change
= approx_Double_exact_Rational
$ \eq vs
->
379 property
$ \(Blind f
) ->
380 with2ArbitraryNodes vs
$ \x y
->
381 with2ArbitraryNodes vs
$ \i j
->
383 ss
= linkValueSquared vs
384 ss
' = linkValueSquared
$ multiUpdate vs
$ getPositive
. f
390 compare ss
'xy ssxy
== compare ss
'ij ssij || ss
'xy `eq` ssxy || ss
'ij `eq` ssij
392 multiUpdateWithAdjustmentList
:: (Ord a
, Ord b
, Fractional b
, MatrixElement b
)
393 => ValueSimplex a b
-> [(a
, b
)] -> ValueSimplex a b
394 multiUpdateWithAdjustmentList vs xqs
= multiUpdate vs
$ \x
->
395 nodeValue vs x
+ Map
.findWithDefault
0 x
(Map
.fromListWith
(+) xqs
)
397 generated_multiUpdate_improving
:: (Ord a
, Show a
)
398 => ValueSimplex a
Double
399 -> (Set a
-> Set
(a
, a
))
400 -> (a
-> a
-> Gen
(Double, Double))
402 generated_multiUpdate_improving vs pairf qgen
=
403 forAll
(arbitrarySubset
$ pairf
$ nodes vs
) $ \xxs
->
405 (promote
$ flip map (Set
.toList xxs
) $ \(x0
, x1
) -> do
406 (q0
, q1
) <- qgen x0 x1
407 return [(x0
, q0
), (x1
, q1
)]
409 with2ArbitraryNodes vs
$ \x y
->
410 linkValueSquared vs x y
<=
411 linkValueSquared
(multiUpdateWithAdjustmentList vs
$ concat xqs
) x y
413 prop_multiUpdate_improving
:: (Ord a
, Show a
)
414 => ValueSimplex a
Double -> Property
415 prop_multiUpdate_improving vs
=
418 ss
= linkValueSquared vs
420 generated_multiUpdate_improving vs distinctPairsOneWay
$ \x0 x1
-> do
421 q0
<- arbitrary `suchThat`
(> - s x0 x1
)
422 q1
<- arbitrary `suchThat`
423 (\q
-> (s x0 x1
+ q0
) * (s x1 x0
+ q
) >= ss x0 x1
)
426 prop_multiUpdate_exact_validity_tests
:: (Ord a
, Show a
)
427 => ValueSimplex a
Double -> Blind
(a
-> Positive
Double) -> Property
428 prop_multiUpdate_exact_validity_tests vs
(Blind f
) =
429 prop_exact_ValueSimplex_validity_tests_Double
$
430 multiUpdate vs
$ getPositive
. f
432 prop_multiUpdate_approx_validity_tests
:: Property
433 prop_multiUpdate_approx_validity_tests
=
434 approx_Double_exact_Rational
$ \eq vs
->
435 property
$ \(Blind f
) ->
436 approx_ValueSimplex_validity_tests eq
$ multiUpdate vs
$ getPositive
. f
438 --------------------------------------------------------------------------------
440 prop_linkOptimumAtPrice_optimum
:: (Ord a
, Show a
) =>
441 ValueSimplex a
Double -> Positive
Double -> Double -> Property
442 prop_linkOptimumAtPrice_optimum vs
(Positive p
) q
=
443 with2ArbitraryNodes vs
$ \x0 x1
->
446 ss
' q0 q1
= (s x0 x1
+ q0
) * (s x1 x0
+ q1
)
448 ss
' q
(-p
* q
) <= uncurry ss
' (linkOptimumAtPrice vs x0 x1 p
)
450 prop_linkOptimumAtPrice_at_price
:: Property
451 prop_linkOptimumAtPrice_at_price
= approx_Double_exact_Rational
$ \eq vs
->
452 with2ArbitraryNodes vs
$ \x0 x1
->
453 property
$ \(Positive p
) ->
454 let (q0
, q1
) = linkOptimumAtPrice vs x0 x1 p
in
457 prop_linkOptimumAtPrice_valid
:: (Ord a
, Show a
)
458 => ValueSimplex a
Double -> Positive
Double -> Property
459 prop_linkOptimumAtPrice_valid vs
(Positive p
) =
460 with2ArbitraryNodes vs
$ \x0 x1
->
462 (q0
, q1
) = linkOptimumAtPrice vs x0 x1 p
465 q0
> - s x0 x1
&& q1
> - s x1 x0
467 prop_linkOptimumAtPrice_correct_sign
:: (Ord a
, Show a
)
468 => ValueSimplex a
Double -> Positive
Double -> Property
469 prop_linkOptimumAtPrice_correct_sign vs
(Positive p
) =
470 with2ArbitraryNodes vs
$ \x0 x1
->
471 compare p
(price vs x0 x1
)
472 == compare 0 (fst $ linkOptimumAtPrice vs x0 x1 p
)
474 prop_multiUpdate_linkOptimumAtPrice_improving
:: (Ord a
, Show a
)
475 => ValueSimplex a
Double -> Property
476 prop_multiUpdate_linkOptimumAtPrice_improving vs
=
477 generated_multiUpdate_improving vs distinctPairs
$ \x0 x1
-> do
478 p
<- arbitrary `suchThat`
(>= price vs x0 x1
)
479 return $ linkOptimumAtPrice vs x0 x1 p
481 arbitrarilyMultiUpdatedWithLinkOptimumAtNearPrice
::
482 (Ord a
, Ord b
, Fractional b
, MatrixElement b
)
483 => ValueSimplex a b
-> Gen
(ValueSimplex a b
)
484 arbitrarilyMultiUpdatedWithLinkOptimumAtNearPrice vs
= do
486 xxs
<- arbitrarySubset
$ distinctPairs xs
487 return $ multiUpdateWithAdjustmentList vs
$ concat $ flip map (Set
.toList xxs
)
490 p
= 1.01 * price vs x0 x1
491 (q0
, q1
) = linkOptimumAtPrice vs x0 x1 p
495 prop_multiUpdate_linkOptimumAtNearPrice_longrun_validity
::
497 => ValueSimplex a
Double -> Property
498 prop_multiUpdate_linkOptimumAtNearPrice_longrun_validity
=
499 longrun_validity arbitrarilyMultiUpdatedWithLinkOptimumAtNearPrice
501 --------------------------------------------------------------------------------
503 prop_totalValue_correct
:: Property
504 prop_totalValue_correct
= approx_Double_exact_Rational
$ \eq vs
->
505 withArbitraryNode vs
$ \x
->
507 `eq` Set
.foldr ((+) . (\y
-> nodeValue vs y
* price vs y x
)) 0 (nodes vs
)
509 arbitraryFractionalBetween0and1
:: Fractional a
=> Gen a
510 arbitraryFractionalBetween0and1
= let precision
= 9999999999999 in
512 b
<- choose
(2, precision
)
513 a
<- choose
(1, b
- 1)
514 return $ fromRational $ a
% b
516 withArbitraryAddNodeParameters
::
517 ( Arbitrary a
, Ord a
, Show a
518 , Arbitrary b
, Ord b
, Fractional b
, Show b
521 => ValueSimplex a b
-> (a
-> b
-> a
-> b
-> p
) -> Property
522 withArbitraryAddNodeParameters vs test
=
524 Set
.notMember x
(nodes vs
) ==>
525 property
$ \(Positive q
) ->
526 withArbitraryNode vs
$ \y
->
527 forAll arbitraryFractionalBetween0and1
$ \r ->
528 test x q y
$ r
* totalValue vs y
/ q
530 withArbitrarilyAddNodedValueSimplex
::
531 ( Arbitrary a
, Ord a
, Show a
532 , Arbitrary b
, Ord b
, Fractional b
, Show b
535 => ValueSimplex a b
-> (ValueSimplex a b
-> p
) -> Property
536 withArbitrarilyAddNodedValueSimplex vs test
=
537 withArbitraryAddNodeParameters vs
$ test
.... addNode vs
539 testArbitrarilyAddNodedValueSimplex
::
540 ( Arbitrary a
, Ord a
, Show a
541 , Arbitrary b
, Ord b
, Fractional b
, Show b
544 => (ValueSimplex a b
-> p
) -> ValueSimplex a b
-> Property
545 testArbitrarilyAddNodedValueSimplex
= flip withArbitrarilyAddNodedValueSimplex
547 prop_addNode_exact_validity_tests
:: (Arbitrary a
, Ord a
, Show a
)
548 => ValueSimplex a
Double -> Property
549 prop_addNode_exact_validity_tests
=
550 testArbitrarilyAddNodedValueSimplex exact_ValueSimplex_validity_tests
552 prop_addNode_approx_validity_tests
:: Property
553 prop_addNode_approx_validity_tests
=
554 approx_Double_exact_Rational
$
555 testArbitrarilyAddNodedValueSimplex
. approx_ValueSimplex_validity_tests
557 prop_addNode_nodes
:: (Arbitrary a
, Ord a
, Show a
)
558 => ValueSimplex a
Double -> Property
559 prop_addNode_nodes vs
= withArbitraryAddNodeParameters vs
$ \x q y p
->
560 nodes
(addNode vs x q y p
) == Set
.insert x
(nodes vs
)
562 prop_addNode_nodeValue
:: Property
563 prop_addNode_nodeValue
= approx_Double_exact_Rational
$ \eq vs
->
564 withArbitraryAddNodeParameters vs
$ \x q y p
->
565 nodeValue
(addNode vs x q y p
) x `eq` q
567 prop_addNode_price
:: Property
569 approx_Double_exact_Rational
$ \eq vs
->
570 withArbitraryAddNodeParameters vs
$ \x q y p
->
571 price
(addNode vs x q y p
) x y `eq` p
573 prop_addNode_nodeValue_unchanged
:: Property
574 prop_addNode_nodeValue_unchanged
=
575 approx_Double_exact_Rational
$ \eq vs
->
576 withArbitrarilyAddNodedValueSimplex vs
$ \vs
' ->
577 withArbitraryNode vs
$ \i
->
578 nodeValue vs
' i `eq` nodeValue vs i
580 prop_addNode_price_unchanged
:: Property
581 prop_addNode_price_unchanged
=
582 approx_Double_exact_Rational
$ \eq vs
->
583 withArbitrarilyAddNodedValueSimplex vs
$ \vs
' ->
584 with2ArbitraryNodes vs
$ \i j
->
585 price vs
' i j `eq` price vs i j
587 prop_addNode_proportions_unchanged
:: Property
588 prop_addNode_proportions_unchanged
=
589 approx_Double_exact_Rational
$ \eq vs
->
590 let ss
= linkValueSquared vs
in
591 withArbitrarilyAddNodedValueSimplex vs
$ \vs
' ->
592 let ss
' = linkValueSquared vs
' in
593 with2ArbitraryNodes vs
$ \i j
->
594 with2ArbitraryNodes vs
$ \k l
->
595 (ss
' i j
/ ss
' k l
) `eq`
(ss i j
/ ss k l
)
597 --------------------------------------------------------------------------------
599 prop_strictlySuperior_irreflexive
:: Property
600 prop_strictlySuperior_irreflexive
=
601 approx_Double_exact_Rational
$ \eq vs
->
602 not $ strictlySuperior eq vs vs
604 prop_multiUpdate_strictlySuperior_one_way
:: Property
605 prop_multiUpdate_strictlySuperior_one_way
=
606 approx_Double_exact_Rational
$ \eq vs
->
607 property
$ \(Blind f
) ->
608 let vs
' = multiUpdate vs
$ getPositive
. f
in
609 not (liftEquivToValueSimplex eq vs vs
') ==>
610 strictlySuperior eq vs vs
' == not (strictlySuperior eq vs
' vs
)
612 prop_multiUpdate_linkOptimumAtNearPrice_strictlySuperior
:: Property
613 prop_multiUpdate_linkOptimumAtNearPrice_strictlySuperior
=
614 approx_Double_exact_Rational
$ \eq vs
-> property
$ do
615 vs
' <- arbitrarilyMultiUpdatedWithLinkOptimumAtNearPrice vs
616 return $ not (liftEquivToValueSimplex eq vs vs
') ==>
617 strictlySuperior eq vs
' vs
619 --------------------------------------------------------------------------------
621 arbitraryDepositFunction
:: (CoArbitrary a
, Ord a
, Arbitrary b
, Ord b
, Num b
)
622 => ValueSimplex a b
-> Gen
(a
-> b
)
623 arbitraryDepositFunction vs
= do
624 xs
<- arbitrarySubset
$ nodes vs
625 f
<- (getPositive
.) <$> arbitrary
628 then nodeValue vs x
+ f x
631 arbitrarilyDeposited
::
632 (CoArbitrary a
, Ord a
)
633 => ValueSimplex a
Double -> Gen
(ValueSimplex a
Double)
634 arbitrarilyDeposited vs
= deposit vs
<$> arbitraryDepositFunction vs
636 prop_arbitrarilyDeposited_validity_tests
:: (CoArbitrary a
, Ord a
, Show a
)
637 => ValueSimplex a
Double -> Property
638 prop_arbitrarilyDeposited_validity_tests vs
= do
639 vs
' <- arbitrarilyDeposited vs
640 exact_ValueSimplex_validity_tests vs
'
641 .&&. approx_ValueSimplex_validity_tests
(~~
=) vs
'
643 prop_arbitrarilyDeposited_nodes_unchanged
:: (CoArbitrary a
, Ord a
)
644 => ValueSimplex a
Double -> Property
645 prop_arbitrarilyDeposited_nodes_unchanged vs
= property
$
646 (nodes vs
==) . nodes
<$> arbitrarilyDeposited vs
648 prop_deposit_nodeValue
:: (CoArbitrary a
, Ord a
, Show a
)
649 => ValueSimplex a
Double -> Property
650 prop_deposit_nodeValue vs
= do
651 f
<- arbitraryDepositFunction vs
652 withArbitraryNode vs
$ \x
-> nodeValue
(deposit vs f
) x ~~
= f x
654 prop_deposit_valueEvenly
:: (CoArbitrary a
, Ord a
, Show a
)
655 => ValueSimplex a
Double -> Property
656 prop_deposit_valueEvenly vs
= do
657 let v
= halfLinkValue vs
658 v
' <- halfLinkValue
<$> arbitrarilyDeposited vs
659 with2ArbitraryNodes vs
$ \x y
-> with2ArbitraryNodes vs
$ \z w
->
660 (v
' x y
- v x y
) * hybridPrice vs x y x
661 ~~
= (v
' z w
- v z w
) * hybridPrice vs z w x
663 --------------------------------------------------------------------------------
666 allValueSimplexTests
:: IO Bool
667 allValueSimplexTests
= $(quickCheckAll
)