@@ -643,7 +643,7 @@ impl Price {
643
643
644
644
#[ cfg( test) ]
645
645
mod test {
646
- use quickcheck:: TestResult ;
646
+ // use quickcheck::TestResult;
647
647
use std:: convert:: TryFrom ;
648
648
649
649
use crate :: price:: {
@@ -2051,134 +2051,135 @@ mod test {
2051
2051
fails ( i64:: MIN , pc ( 100 , 10 , -9 ) , 0 , pc ( 0 , 12 , -9 ) , 0 , -9 ) ;
2052
2052
}
2053
2053
2054
- pub fn construct_quickcheck_affine_combination_price ( price : i64 ) -> Price {
2055
- return Price {
2056
- price : price,
2057
- conf : 0 ,
2058
- expo : -9 ,
2059
- publish_time : 0 ,
2060
- } ;
2061
- }
2062
-
2063
- // quickcheck to confirm affine_combination introduces no error if normalization done explicitly
2064
- // on prices first this quickcheck calls affine_combination with two sets of almost
2065
- // identical inputs: the first set has potentially unnormalized prices, the second set
2066
- // simply has the normalized versions of those prices this set of checks should pass because
2067
- // normalization is automatically performed on the prices before they are multiplied
2068
- // this set of checks passing indicates that it doesn't matter whether the prices passed in are
2069
- // normalized
2070
- #[ quickcheck]
2071
- fn quickcheck_affine_combination_normalize_prices (
2072
- x1_inp : i32 ,
2073
- p1 : i32 ,
2074
- x2_inp : i32 ,
2075
- p2 : i32 ,
2076
- x_query_inp : i32 ,
2077
- ) -> TestResult {
2078
- // generating xs and prices from i32 to limit the range to reasonable values and guard
2079
- // against overflow/bespoke constraint setting for quickcheck
2080
- let y1 = construct_quickcheck_affine_combination_price ( i64:: try_from ( p1) . ok ( ) . unwrap ( ) ) ;
2081
- let y2 = construct_quickcheck_affine_combination_price ( i64:: try_from ( p2) . ok ( ) . unwrap ( ) ) ;
2082
-
2083
- let x1 = i64:: try_from ( x1_inp) . ok ( ) . unwrap ( ) ;
2084
- let x2 = i64:: try_from ( x2_inp) . ok ( ) . unwrap ( ) ;
2085
- let x_query = i64:: try_from ( x_query_inp) . ok ( ) . unwrap ( ) ;
2086
-
2087
- // stick with single expo for ease of testing and generation
2088
- let pre_add_expo = -9 ;
2089
-
2090
- // require x2 > x1, as needed for affine_combination
2091
- if x1 >= x2 {
2092
- return TestResult :: discard ( ) ;
2093
- }
2094
-
2095
- // original result
2096
- let result_orig = Price :: affine_combination ( x1, y1, x2, y2, x_query, pre_add_expo) . unwrap ( ) ;
2097
-
2098
- let y1_norm = y1. normalize ( ) . unwrap ( ) ;
2099
- let y2_norm = y2. normalize ( ) . unwrap ( ) ;
2100
-
2101
- // result with normalized price inputs
2102
- let result_norm =
2103
- Price :: affine_combination ( x1, y1_norm, x2, y2_norm, x_query, pre_add_expo) . unwrap ( ) ;
2104
-
2105
- // results should match exactly
2106
- TestResult :: from_bool ( result_norm == result_orig)
2107
- }
2108
-
2109
- // quickcheck to confirm affine_combination introduces bounded error if close fraction x/y
2110
- // passed in first this quickcheck calls affine_combination with two sets of similar inputs:
2111
- // the first set has xs generated by the quickcheck generation process, leading to potentially
2112
- // inexact fractions that don't fit within 8 digits of precision the second set "normalizes"
2113
- // down to 8 digits of precision by setting x1 to 0, x2 to 100_000_000, and xquery
2114
- // proportionally based on the bounds described in the docstring of affine_combination, we
2115
- // expect error due to this to be leq 4*10^-7
2116
- #[ quickcheck]
2117
- fn quickcheck_affine_combination_normalize_fractions (
2118
- x1_inp : i32 ,
2119
- p1 : i32 ,
2120
- x2_inp : i32 ,
2121
- p2 : i32 ,
2122
- x_query_inp : i32 ,
2123
- ) -> TestResult {
2124
- // generating xs and prices from i32 to limit the range to reasonable values and guard
2125
- // against overflow/bespoke constraint setting for quickcheck
2126
- let y1 = construct_quickcheck_affine_combination_price ( i64:: try_from ( p1) . ok ( ) . unwrap ( ) ) ;
2127
- let y2 = construct_quickcheck_affine_combination_price ( i64:: try_from ( p2) . ok ( ) . unwrap ( ) ) ;
2128
-
2129
- let x1 = i64:: try_from ( x1_inp) . ok ( ) . unwrap ( ) ;
2130
- let x2 = i64:: try_from ( x2_inp) . ok ( ) . unwrap ( ) ;
2131
- let x_query = i64:: try_from ( x_query_inp) . ok ( ) . unwrap ( ) ;
2132
-
2133
- // stick with single expo for ease of testing and generation
2134
- let pre_add_expo = -9 ;
2135
-
2136
- // require x2 > x1, as needed for affine_combination
2137
- if x1 >= x2 {
2138
- return TestResult :: discard ( ) ;
2139
- }
2140
-
2141
- // constrain x_query to be within 5 interval lengths of x1 or x2
2142
- if ( x_query > x2 + 5 * ( x2 - x1) ) || ( x_query < x1 - 5 * ( x2 - x1) ) {
2143
- return TestResult :: discard ( ) ;
2144
- }
2145
-
2146
- // generate new xs based on scaling x_1 --> 0, x_2 --> 10^8
2147
- let x1_new: i64 ;
2148
- let xq_new: i64 ;
2149
- let x2_new: i64 ;
2150
-
2151
- if x2 == 0 {
2152
- x1_new = x1;
2153
- xq_new = x_query;
2154
- x2_new = x2;
2155
- } else {
2156
- let mut frac_q2 = Price :: fraction ( x_query - x1, x2 - x1) . unwrap ( ) ;
2157
- frac_q2 = frac_q2. scale_to_exponent ( -8 ) . unwrap ( ) ;
2158
-
2159
- x1_new = 0 ;
2160
- xq_new = frac_q2. price ;
2161
- x2_new = 100_000_000 as i64 ;
2162
- }
2163
-
2164
- // original result
2165
- let result_orig = Price :: affine_combination ( x1, y1, x2, y2, x_query, pre_add_expo)
2166
- . unwrap ( )
2167
- . scale_to_exponent ( -7 )
2168
- . unwrap ( ) ;
2169
-
2170
- // xs "normalized" result
2171
- let result_norm = Price :: affine_combination ( x1_new, y1, x2_new, y2, xq_new, pre_add_expo)
2172
- . unwrap ( )
2173
- . scale_to_exponent ( -7 )
2174
- . unwrap ( ) ;
2175
-
2176
- // compute difference in prices
2177
- let price_diff = result_norm. add ( & result_orig. cmul ( -1 , 0 ) . unwrap ( ) ) . unwrap ( ) ;
2178
-
2179
- // results should differ by less than 4*10^-7
2180
- TestResult :: from_bool ( ( price_diff. price < 4 ) && ( price_diff. price > -4 ) )
2181
- }
2054
+ // pub fn construct_quickcheck_affine_combination_price(price: i64) -> Price {
2055
+ // return Price {
2056
+ // price: price,
2057
+ // conf: 0,
2058
+ // expo: -9,
2059
+ // publish_time: 0,
2060
+ // };
2061
+ // }
2062
+
2063
+ // // quickcheck to confirm affine_combination introduces no error if normalization done
2064
+ // explicitly // on prices first this quickcheck calls affine_combination with two sets of
2065
+ // almost // identical inputs: the first set has potentially unnormalized prices, the second
2066
+ // set // simply has the normalized versions of those prices this set of checks should pass
2067
+ // because // normalization is automatically performed on the prices before they are
2068
+ // multiplied // this set of checks passing indicates that it doesn't matter whether the
2069
+ // prices passed in are // normalized
2070
+ // #[quickcheck]
2071
+ // fn quickcheck_affine_combination_normalize_prices(
2072
+ // x1_inp: i32,
2073
+ // p1: i32,
2074
+ // x2_inp: i32,
2075
+ // p2: i32,
2076
+ // x_query_inp: i32,
2077
+ // ) -> TestResult {
2078
+ // // generating xs and prices from i32 to limit the range to reasonable values and guard
2079
+ // // against overflow/bespoke constraint setting for quickcheck
2080
+ // let y1 = construct_quickcheck_affine_combination_price(i64::try_from(p1).ok().unwrap());
2081
+ // let y2 = construct_quickcheck_affine_combination_price(i64::try_from(p2).ok().unwrap());
2082
+
2083
+ // let x1 = i64::try_from(x1_inp).ok().unwrap();
2084
+ // let x2 = i64::try_from(x2_inp).ok().unwrap();
2085
+ // let x_query = i64::try_from(x_query_inp).ok().unwrap();
2086
+
2087
+ // // stick with single expo for ease of testing and generation
2088
+ // let pre_add_expo = -9;
2089
+
2090
+ // // require x2 > x1, as needed for affine_combination
2091
+ // if x1 >= x2 {
2092
+ // return TestResult::discard();
2093
+ // }
2094
+
2095
+ // // original result
2096
+ // let result_orig = Price::affine_combination(x1, y1, x2, y2, x_query,
2097
+ // pre_add_expo).unwrap();
2098
+
2099
+ // let y1_norm = y1.normalize().unwrap();
2100
+ // let y2_norm = y2.normalize().unwrap();
2101
+
2102
+ // // result with normalized price inputs
2103
+ // let result_norm =
2104
+ // Price::affine_combination(x1, y1_norm, x2, y2_norm, x_query, pre_add_expo).unwrap();
2105
+
2106
+ // // results should match exactly
2107
+ // TestResult::from_bool(result_norm == result_orig)
2108
+ // }
2109
+
2110
+ // // quickcheck to confirm affine_combination introduces bounded error if close fraction x/y
2111
+ // // passed in first this quickcheck calls affine_combination with two sets of similar inputs:
2112
+ // // the first set has xs generated by the quickcheck generation process, leading to
2113
+ // potentially // inexact fractions that don't fit within 8 digits of precision the second
2114
+ // set "normalizes" // down to 8 digits of precision by setting x1 to 0, x2 to 100_000_000,
2115
+ // and xquery // proportionally based on the bounds described in the docstring of
2116
+ // affine_combination, we // expect error due to this to be leq 4*10^-7
2117
+ // #[quickcheck]
2118
+ // fn quickcheck_affine_combination_normalize_fractions(
2119
+ // x1_inp: i32,
2120
+ // p1: i32,
2121
+ // x2_inp: i32,
2122
+ // p2: i32,
2123
+ // x_query_inp: i32,
2124
+ // ) -> TestResult {
2125
+ // // generating xs and prices from i32 to limit the range to reasonable values and guard
2126
+ // // against overflow/bespoke constraint setting for quickcheck
2127
+ // let y1 = construct_quickcheck_affine_combination_price(i64::try_from(p1).ok().unwrap());
2128
+ // let y2 = construct_quickcheck_affine_combination_price(i64::try_from(p2).ok().unwrap());
2129
+
2130
+ // let x1 = i64::try_from(x1_inp).ok().unwrap();
2131
+ // let x2 = i64::try_from(x2_inp).ok().unwrap();
2132
+ // let x_query = i64::try_from(x_query_inp).ok().unwrap();
2133
+
2134
+ // // stick with single expo for ease of testing and generation
2135
+ // let pre_add_expo = -9;
2136
+
2137
+ // // require x2 > x1, as needed for affine_combination
2138
+ // if x1 >= x2 {
2139
+ // return TestResult::discard();
2140
+ // }
2141
+
2142
+ // // constrain x_query to be within 5 interval lengths of x1 or x2
2143
+ // if (x_query > x2 + 5 * (x2 - x1)) || (x_query < x1 - 5 * (x2 - x1)) {
2144
+ // return TestResult::discard();
2145
+ // }
2146
+
2147
+ // // generate new xs based on scaling x_1 --> 0, x_2 --> 10^8
2148
+ // let x1_new: i64;
2149
+ // let xq_new: i64;
2150
+ // let x2_new: i64;
2151
+
2152
+ // if x2 == 0 {
2153
+ // x1_new = x1;
2154
+ // xq_new = x_query;
2155
+ // x2_new = x2;
2156
+ // } else {
2157
+ // let mut frac_q2 = Price::fraction(x_query - x1, x2 - x1).unwrap();
2158
+ // frac_q2 = frac_q2.scale_to_exponent(-8).unwrap();
2159
+
2160
+ // x1_new = 0;
2161
+ // xq_new = frac_q2.price;
2162
+ // x2_new = 100_000_000 as i64;
2163
+ // }
2164
+
2165
+ // // original result
2166
+ // let result_orig = Price::affine_combination(x1, y1, x2, y2, x_query, pre_add_expo)
2167
+ // .unwrap()
2168
+ // .scale_to_exponent(-7)
2169
+ // .unwrap();
2170
+
2171
+ // // xs "normalized" result
2172
+ // let result_norm = Price::affine_combination(x1_new, y1, x2_new, y2, xq_new, pre_add_expo)
2173
+ // .unwrap()
2174
+ // .scale_to_exponent(-7)
2175
+ // .unwrap();
2176
+
2177
+ // // compute difference in prices
2178
+ // let price_diff = result_norm.add(&result_orig.cmul(-1, 0).unwrap()).unwrap();
2179
+
2180
+ // // results should differ by less than 4*10^-7
2181
+ // TestResult::from_bool((price_diff.price < 4) && (price_diff.price > -4))
2182
+ // }
2182
2183
2183
2184
#[ test]
2184
2185
fn test_fraction ( ) {
0 commit comments