100 {
101 BOOST_TEST_MESSAGE("Testing Formula Parser with CompiledFormula...");
102
103 double tol = 1E-12;
104
105 double x = 42.0, y = -2.3;
106 std::vector<std::string> variables;
107
108 QuantExt::CompiledFormula f =
parseFormula(
"((2*{x})+3)/{y}", variables);
109 BOOST_REQUIRE(variables.size() == 2);
110 BOOST_CHECK_EQUAL(variables[0], "x");
111 BOOST_CHECK_EQUAL(variables[1], "y");
112 BOOST_CHECK_CLOSE(f({x, y}), (2.0 * x + 3.0) / y, tol);
113
115 BOOST_REQUIRE(variables.size() == 2);
116 BOOST_CHECK_EQUAL(variables[0], "x");
117 BOOST_CHECK_EQUAL(variables[1], "y");
118 BOOST_CHECK_CLOSE(f({x, y}), x - y, tol);
119
121 BOOST_REQUIRE(variables.size() == 1);
122 BOOST_CHECK_EQUAL(variables[0], "y");
123 BOOST_CHECK_CLOSE(f({y}), -y, tol);
124
126 BOOST_REQUIRE(variables.size() == 2);
127 BOOST_CHECK_EQUAL(variables[0], "x");
128 BOOST_CHECK_EQUAL(variables[1], "y");
129 BOOST_CHECK_CLOSE(f({x, y}), x / y, tol);
130
132 BOOST_REQUIRE(variables.size() == 2);
133 BOOST_CHECK_EQUAL(variables[0], "x");
134 BOOST_CHECK_EQUAL(variables[1], "y");
135 BOOST_CHECK_CLOSE(f({x, y}), std::max(x, y), tol);
136
138 BOOST_REQUIRE(variables.size() == 2);
139 BOOST_CHECK_EQUAL(variables[0], "x");
140 BOOST_CHECK_EQUAL(variables[1], "y");
141 BOOST_CHECK_CLOSE(f({x, y}), std::min(x, y), tol);
142
144 BOOST_REQUIRE(variables.size() == 2);
145 BOOST_CHECK_EQUAL(variables[0], "x");
146 BOOST_CHECK_EQUAL(variables[1], "y");
147 BOOST_CHECK_CLOSE(f({x, y}), std::pow(x, y), tol);
148
150 BOOST_REQUIRE(variables.size() == 1);
151 BOOST_CHECK_EQUAL(variables[0], "y");
152 BOOST_CHECK_CLOSE(f({y}), std::abs(y), tol);
153
155 BOOST_REQUIRE(variables.size() == 1);
156 BOOST_CHECK_EQUAL(variables[0], "x");
157 BOOST_CHECK_CLOSE(f({x}), 1.0, tol);
158 BOOST_CHECK_SMALL(f({y}), tol);
159 BOOST_CHECK_SMALL(f({0.0}), tol);
160
162 BOOST_REQUIRE(variables.size() == 1);
163 BOOST_CHECK_EQUAL(variables[0], "x");
164 BOOST_CHECK_CLOSE(f({x}), 1.0, tol);
165 BOOST_CHECK_SMALL(f({y}), tol);
166 BOOST_CHECK_CLOSE(f({0.0}), 1.0, tol);
167
169 BOOST_REQUIRE(variables.size() == 1);
170 BOOST_CHECK_EQUAL(variables[0], "y");
171 BOOST_CHECK_CLOSE(f({y}), std::exp(y), tol);
172
174 BOOST_REQUIRE(variables.size() == 1);
175 BOOST_CHECK_EQUAL(variables[0], "x");
176 BOOST_CHECK_CLOSE(f({x}), std::log(x), tol);
177
178
179
180 f =
parseFormula(
"max((2.3*({x}-{y}))-4.3,0.0)", variables);
181 boost::timer::cpu_timer timer;
182 double dummy = 0.0;
183 std::vector<Real> v(2);
184 for (Size i = 0; i < 100000; ++i) {
185 v[0] = static_cast<double>(i) / static_cast<double>(10000);
186 v[1] = static_cast<double>(100000 - i) / static_cast<double>(10000);
187 dummy += f(v);
188 }
189 BOOST_TEST_MESSAGE("dummy = " << dummy);
190 timer.stop();
191 BOOST_TEST_MESSAGE("timing precompiled formula (100k evalulations) = "
192 << timer.format(boost::timer::default_places, "%w") << " secs.");
193
194 timer.start();
195 dummy = 0.0;
196 for (Size i = 0; i < 100000; ++i) {
197 Real x = static_cast<double>(i) / static_cast<double>(10000);
198 Real y = static_cast<double>(100000 - i) / static_cast<double>(10000);
199 dummy += std::max((2.3 * (x - y)) - 4.3, 0.0);
200 }
201 BOOST_TEST_MESSAGE("dummy = " << dummy);
202 timer.stop();
203 BOOST_TEST_MESSAGE("timing native (100k evaluations) = " << timer.format(boost::timer::default_places, "%w")
204 << " secs.");
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228}
QuantExt::CompiledFormula parseFormula(const std::string &text, std::vector< std::string > &variables)