├── .gitignore ├── LICENSE ├── README.md ├── main.cpp ├── mis.sln ├── mis.vcxproj ├── mis.vcxproj.filters ├── out1.abse.csv ├── out1.var.csv ├── out2.abse.csv ├── out2.var.csv ├── out3.abse.csv ├── out3.var.csv ├── out3_icdf1.csv ├── out3_icdf2.csv ├── out3_icdf3.csv ├── out3_pdf1.csv ├── out3_pdf2.csv └── out3_pdf3.csv /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | x64/ 3 | *.vcxproj.user 4 | out/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Alan Wolfe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MIS 2 | Basic multiple importance sampling, in 1d 3 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define DETERMINISTIC() true 5 | 6 | // Blue noise is very slow to generate, and doesn't have good convergence speed, but does decrease variance compared to white noise. 7 | // Decrease c_numSamples and/or c_numtests if turning blue noise on. 8 | #define DO_BLUE_NOISE() false 9 | 10 | #define DO_PDF_TEST() true 11 | 12 | static const size_t c_numSamples = 5000; 13 | static const size_t c_numTests = 10000; 14 | 15 | static const double c_pi = 3.14159265359; 16 | static const double c_goldeRatioConjugate = 0.61803398875; 17 | static const double c_sqrt2 = sqrt(2.0); 18 | static const double c_sqrt5 = sqrt(5.0); 19 | static const double c_minError = 0.00001; // to avoid errors when showing on a log plot 20 | 21 | std::mt19937 GetRNG(int seed) 22 | { 23 | #if DETERMINISTIC() 24 | static int internalSeed = 0; 25 | internalSeed++; 26 | std::mt19937 mt(internalSeed * 1000 + seed); 27 | #else 28 | std::random_device rd("/dev/random"); 29 | std::mt19937 mt(rd()); 30 | #endif 31 | return mt; 32 | } 33 | 34 | struct Result 35 | { 36 | double estimate; 37 | std::vector estimates; 38 | 39 | double estimateAvg; 40 | std::vector estimatesAvg; 41 | 42 | double estimateSqAvg; 43 | std::vector estimatesSqAvg; 44 | }; 45 | 46 | inline double max(double a, double b) 47 | { 48 | return a >= b ? a : b; 49 | } 50 | 51 | inline double min(double a, double b) 52 | { 53 | return a <= b ? a : b; 54 | } 55 | 56 | inline double TorroidalDistance(double a, double b) 57 | { 58 | double dist = abs(a - b); 59 | if (dist > 0.5) 60 | dist = 1.0 - dist; 61 | return dist; 62 | } 63 | 64 | void MakeBlueNoise(std::vector& samples, size_t sampleCount, int seed) 65 | { 66 | #if DO_BLUE_NOISE() 67 | std::mt19937 rng = GetRNG(seed); 68 | std::uniform_real_distribution dist(0.0, 1.0); 69 | 70 | samples.resize(sampleCount); 71 | for (size_t sampleIndex = 0; sampleIndex < sampleCount; ++sampleIndex) 72 | { 73 | double bestCandidate = 0.0f; 74 | double bestCandidateScore = 0.0f; 75 | 76 | for (size_t candidateIndex = 0; candidateIndex <= sampleIndex; ++candidateIndex) 77 | { 78 | double candidate = dist(rng); 79 | double minDist = FLT_MAX; 80 | for (size_t distIndex = 0; distIndex < sampleIndex; ++distIndex) 81 | minDist = min(minDist, TorroidalDistance(candidate, samples[distIndex])); 82 | 83 | if (minDist > bestCandidateScore) 84 | { 85 | bestCandidate = candidate; 86 | bestCandidateScore = minDist; 87 | } 88 | } 89 | 90 | samples[sampleIndex] = bestCandidate; 91 | } 92 | #else 93 | std::mt19937 rng = GetRNG(seed); 94 | std::uniform_real_distribution dist(0.0, 1.0); 95 | 96 | samples.resize(sampleCount); 97 | for (double& d : samples) 98 | d = dist(rng); 99 | #endif 100 | } 101 | 102 | template 103 | T Clamp(T value, T min, T max) 104 | { 105 | if (value <= min) 106 | return min; 107 | if (value >= max) 108 | return max; 109 | return value; 110 | } 111 | 112 | double Lerp(double A, double B, double t) 113 | { 114 | return A * (1.0 - t) + B * t; 115 | } 116 | 117 | void AddSampleToRunningAverage(double &average, double newValue, size_t sampleCount) 118 | { 119 | // Incremental averaging: lerp from old value to new value by 1/(sampleCount+1) 120 | // https://blog.demofox.org/2016/08/23/incremental-averaging/ 121 | double t = 1.0 / double(sampleCount + 1); 122 | average = Lerp(average, newValue, t); 123 | } 124 | 125 | template 126 | void MonteCarlo(const TF& F, Result& result, int seed) 127 | { 128 | std::mt19937 rng = GetRNG(seed); 129 | std::uniform_real_distribution dist(0.0, c_pi); 130 | 131 | result.estimates.resize(c_numSamples); 132 | 133 | result.estimate = 0.0f; 134 | for (size_t i = 0; i < c_numSamples; ++i) 135 | { 136 | double x = dist(rng); 137 | double y = F(x); 138 | AddSampleToRunningAverage(result.estimate, y, i); 139 | result.estimates[i] = result.estimate * c_pi; 140 | } 141 | 142 | result.estimate *= c_pi; 143 | } 144 | 145 | template 146 | void MonteCarloLDS(const TF& F, Result& result, int seed) 147 | { 148 | std::mt19937 rng = GetRNG(seed); 149 | std::uniform_real_distribution dist(0.0, 1.0f); 150 | 151 | result.estimates.resize(c_numSamples); 152 | double lds = dist(rng); 153 | result.estimate = 0.0f; 154 | for (size_t i = 0; i < c_numSamples; ++i) 155 | { 156 | double x = lds * c_pi; 157 | double y = F(x); 158 | AddSampleToRunningAverage(result.estimate, y, i); 159 | result.estimates[i] = result.estimate * c_pi; 160 | lds = fmod(lds + c_goldeRatioConjugate, 1.0f); 161 | } 162 | 163 | result.estimate *= c_pi; 164 | } 165 | 166 | template 167 | void MonteCarloBlue(const TF& F, Result& result, int seed) 168 | { 169 | std::vector blueNoise; 170 | MakeBlueNoise(blueNoise, c_numSamples, seed); 171 | 172 | result.estimates.resize(c_numSamples); 173 | result.estimate = 0.0f; 174 | for (size_t i = 0; i < c_numSamples; ++i) 175 | { 176 | double x = blueNoise[i] * c_pi; 177 | double y = F(x); 178 | AddSampleToRunningAverage(result.estimate, y, i); 179 | result.estimates[i] = result.estimate * c_pi; 180 | } 181 | 182 | result.estimate *= c_pi; 183 | } 184 | 185 | template 186 | void ImportanceSampledMonteCarlo(const TF& F, const TPDF& PDF, const TINVERSECDF& InverseCDF, Result& result, int seed) 187 | { 188 | std::mt19937 rng = GetRNG(seed); 189 | std::uniform_real_distribution dist(0.0, 1.0); 190 | 191 | result.estimates.resize(c_numSamples); 192 | 193 | result.estimate = 0.0f; 194 | for (size_t i = 0; i < c_numSamples; ++i) 195 | { 196 | double x = InverseCDF(dist(rng)); 197 | double y = F(x); 198 | double pdf = PDF(x); 199 | double value = y / pdf; 200 | AddSampleToRunningAverage(result.estimate, value, i); 201 | result.estimates[i] = result.estimate; 202 | } 203 | } 204 | 205 | template 206 | void ImportanceSampledMonteCarloLDS(const TF& F, const TPDF& PDF, const TINVERSECDF& InverseCDF, Result& result, int seed) 207 | { 208 | std::mt19937 rng = GetRNG(seed); 209 | std::uniform_real_distribution dist(0.0, 1.0f); 210 | 211 | result.estimates.resize(c_numSamples); 212 | double lds = dist(rng); 213 | result.estimate = 0.0f; 214 | for (size_t i = 0; i < c_numSamples; ++i) 215 | { 216 | double x = InverseCDF(lds); 217 | double y = F(x); 218 | double pdf = PDF(x); 219 | double value = y / pdf; 220 | AddSampleToRunningAverage(result.estimate, value, i); 221 | result.estimates[i] = result.estimate; 222 | lds = fmod(lds + c_goldeRatioConjugate, 1.0f); 223 | } 224 | } 225 | 226 | template 227 | void ImportanceSampledMonteCarloBlue(const TF& F, const TPDF& PDF, const TINVERSECDF& InverseCDF, Result& result, int seed) 228 | { 229 | std::vector blueNoise; 230 | MakeBlueNoise(blueNoise, c_numSamples, seed); 231 | 232 | result.estimates.resize(c_numSamples); 233 | result.estimate = 0.0f; 234 | for (size_t i = 0; i < c_numSamples; ++i) 235 | { 236 | double x = InverseCDF(blueNoise[i]); 237 | double y = F(x); 238 | double pdf = PDF(x); 239 | double value = y / pdf; 240 | AddSampleToRunningAverage(result.estimate, value, i); 241 | result.estimates[i] = result.estimate; 242 | } 243 | } 244 | 245 | template 246 | void MultipleImportanceSampledMonteCarlo(const TF& F, const TPDF1& PDF1, const TINVERSECDF1& InverseCDF1, const TPDF2& PDF2, const TINVERSECDF2& InverseCDF2, Result& result, int seed) 247 | { 248 | std::mt19937 rng = GetRNG(seed); 249 | std::uniform_real_distribution dist(0.0, 1.0); 250 | 251 | result.estimates.resize(c_numSamples); 252 | 253 | result.estimate = 0.0f; 254 | for (size_t i = 0; i < c_numSamples; ++i) 255 | { 256 | double x1 = InverseCDF1(dist(rng)); 257 | double y1 = F(x1); 258 | double pdf11 = PDF1(x1); 259 | double pdf12 = PDF2(x1); 260 | 261 | double x2 = InverseCDF2(dist(rng)); 262 | double y2 = F(x2); 263 | double pdf21 = PDF1(x2); 264 | double pdf22 = PDF2(x2); 265 | 266 | double value = 267 | y1 / (pdf11 + pdf12) + 268 | y2 / (pdf21 + pdf22) 269 | ; 270 | 271 | AddSampleToRunningAverage(result.estimate, value, i); 272 | result.estimates[i] = result.estimate; 273 | } 274 | } 275 | 276 | template 277 | void MultipleImportanceSampledMonteCarloBlue(const TF& F, const TPDF1& PDF1, const TINVERSECDF1& InverseCDF1, const TPDF2& PDF2, const TINVERSECDF2& InverseCDF2, Result& result, int seed) 278 | { 279 | std::vector blueNoise1; 280 | MakeBlueNoise(blueNoise1, c_numSamples, seed); 281 | 282 | std::vector blueNoise2; 283 | MakeBlueNoise(blueNoise2, c_numSamples, seed); 284 | 285 | result.estimates.resize(c_numSamples); 286 | 287 | result.estimate = 0.0f; 288 | for (size_t i = 0; i < c_numSamples; ++i) 289 | { 290 | double x1 = InverseCDF1(blueNoise1[i]); 291 | double y1 = F(x1); 292 | double pdf11 = PDF1(x1); 293 | double pdf12 = PDF2(x1); 294 | 295 | double x2 = InverseCDF2(blueNoise2[i]); 296 | double y2 = F(x2); 297 | double pdf21 = PDF1(x2); 298 | double pdf22 = PDF2(x2); 299 | 300 | double value = 301 | y1 / (pdf11 + pdf12) + 302 | y2 / (pdf21 + pdf22) 303 | ; 304 | 305 | AddSampleToRunningAverage(result.estimate, value, i); 306 | result.estimates[i] = result.estimate; 307 | } 308 | } 309 | 310 | template 311 | void MultipleImportanceSampledMonteCarlo(const TF& F, const TPDF1& PDF1, const TINVERSECDF1& InverseCDF1, const TPDF2& PDF2, const TINVERSECDF2& InverseCDF2, const TPDF3& PDF3, const TINVERSECDF3& InverseCDF3, Result& result, int seed) 312 | { 313 | std::mt19937 rng = GetRNG(seed); 314 | std::uniform_real_distribution dist(0.0, 1.0); 315 | 316 | result.estimates.resize(c_numSamples); 317 | 318 | result.estimate = 0.0f; 319 | for (size_t i = 0; i < c_numSamples; ++i) 320 | { 321 | double x1 = InverseCDF1(dist(rng)); 322 | double y1 = F(x1); 323 | double pdf11 = PDF1(x1); 324 | double pdf12 = PDF2(x1); 325 | double pdf13 = PDF3(x1); 326 | 327 | double x2 = InverseCDF2(dist(rng)); 328 | double y2 = F(x2); 329 | double pdf21 = PDF1(x2); 330 | double pdf22 = PDF2(x2); 331 | double pdf23 = PDF3(x2); 332 | 333 | double x3 = InverseCDF3(dist(rng)); 334 | double y3 = F(x3); 335 | double pdf31 = PDF1(x3); 336 | double pdf32 = PDF2(x3); 337 | double pdf33 = PDF3(x3); 338 | 339 | double value = 340 | y1 / (pdf11 + pdf12 + pdf13) + 341 | y2 / (pdf21 + pdf22 + pdf23) + 342 | y3 / (pdf31 + pdf32 + pdf33) 343 | ; 344 | 345 | AddSampleToRunningAverage(result.estimate, value, i); 346 | result.estimates[i] = result.estimate; 347 | } 348 | } 349 | 350 | template 351 | void MultipleImportanceSampledMonteCarloBlue(const TF& F, const TPDF1& PDF1, const TINVERSECDF1& InverseCDF1, const TPDF2& PDF2, const TINVERSECDF2& InverseCDF2, const TPDF3& PDF3, const TINVERSECDF3& InverseCDF3, Result& result, int seed) 352 | { 353 | std::vector blueNoise1; 354 | MakeBlueNoise(blueNoise1, c_numSamples, seed); 355 | 356 | std::vector blueNoise2; 357 | MakeBlueNoise(blueNoise2, c_numSamples, seed); 358 | 359 | std::vector blueNoise3; 360 | MakeBlueNoise(blueNoise3, c_numSamples, seed); 361 | 362 | result.estimates.resize(c_numSamples); 363 | 364 | result.estimate = 0.0f; 365 | for (size_t i = 0; i < c_numSamples; ++i) 366 | { 367 | double x1 = InverseCDF1(blueNoise1[i]); 368 | double y1 = F(x1); 369 | double pdf11 = PDF1(x1); 370 | double pdf12 = PDF2(x1); 371 | double pdf13 = PDF3(x1); 372 | 373 | double x2 = InverseCDF2(blueNoise2[i]); 374 | double y2 = F(x2); 375 | double pdf21 = PDF1(x2); 376 | double pdf22 = PDF2(x2); 377 | double pdf23 = PDF3(x2); 378 | 379 | double x3 = InverseCDF3(blueNoise3[i]); 380 | double y3 = F(x3); 381 | double pdf31 = PDF1(x3); 382 | double pdf32 = PDF2(x3); 383 | double pdf33 = PDF3(x3); 384 | 385 | double value = 386 | y1 / (pdf11 + pdf12 + pdf13) + 387 | y2 / (pdf21 + pdf22 + pdf23) + 388 | y3 / (pdf31 + pdf32 + pdf33) 389 | ; 390 | 391 | AddSampleToRunningAverage(result.estimate, value, i); 392 | result.estimates[i] = result.estimate; 393 | } 394 | } 395 | 396 | template 397 | void MultipleImportanceSampledMonteCarloStochastic(const TF& F, const TPDF1& PDF1, const TINVERSECDF1& InverseCDF1, const TPDF2& PDF2, const TINVERSECDF2& InverseCDF2, Result& result, int seed) 398 | { 399 | std::mt19937 rng = GetRNG(seed); 400 | std::uniform_real_distribution dist(0.0, 1.0); 401 | 402 | result.estimates.resize(c_numSamples); 403 | 404 | result.estimate = 0.0f; 405 | for (size_t i = 0; i < c_numSamples; ++i) 406 | { 407 | double x1 = InverseCDF1(dist(rng)); 408 | double pdf11 = PDF1(x1); 409 | double pdf12 = PDF2(x1); 410 | double weight1 = pdf11 / (pdf11 + pdf12); 411 | 412 | double x2 = InverseCDF2(dist(rng)); 413 | double pdf21 = PDF1(x2); 414 | double pdf22 = PDF2(x2); 415 | double weight2 = pdf22 / (pdf21 + pdf22); 416 | 417 | double totalWeight = weight1 + weight2; 418 | 419 | double weight1chance = weight1 / totalWeight; 420 | 421 | double estimate = dist(rng) < weight1chance 422 | ? (F(x1) / pdf11) * totalWeight // (F(x1) / pdf11) * (weight1 / weight1chance) 423 | : (F(x2) / pdf22) * totalWeight; // (F(x2) / pdf22) * (weight2 / (1.0 - weight1chance)); 424 | 425 | AddSampleToRunningAverage(result.estimate, estimate, i); 426 | result.estimates[i] = result.estimate; 427 | } 428 | } 429 | 430 | template 431 | void MultipleImportanceSampledMonteCarloLDS(const TF& F, const TPDF1& PDF1, const TINVERSECDF1& InverseCDF1, const TPDF2& PDF2, const TINVERSECDF2& InverseCDF2, Result& result, int seed) 432 | { 433 | std::mt19937 rng = GetRNG(seed); 434 | std::uniform_real_distribution dist(0.0, 1.0); 435 | 436 | result.estimates.resize(c_numSamples); 437 | 438 | double lds1 = dist(rng); 439 | double lds2 = dist(rng); 440 | result.estimate = 0.0f; 441 | for (size_t i = 0; i < c_numSamples; ++i) 442 | { 443 | double x1 = InverseCDF1(lds1); 444 | double y1 = F(x1); 445 | double pdf11 = PDF1(x1); 446 | double pdf12 = PDF2(x1); 447 | 448 | double x2 = InverseCDF2(lds2); 449 | double y2 = F(x2); 450 | double pdf21 = PDF1(x2); 451 | double pdf22 = PDF2(x2); 452 | 453 | double value = 454 | y1 / (pdf11 + pdf12) + 455 | y2 / (pdf21 + pdf22) 456 | ; 457 | 458 | AddSampleToRunningAverage(result.estimate, value, i); 459 | result.estimates[i] = result.estimate; 460 | 461 | lds1 = fmod(lds1 + c_goldeRatioConjugate, 1.0f); 462 | lds2 = fmod(lds2 + c_sqrt2, 1.0f); 463 | } 464 | } 465 | 466 | template 467 | void MultipleImportanceSampledMonteCarloLDS(const TF& F, const TPDF1& PDF1, const TINVERSECDF1& InverseCDF1, const TPDF2& PDF2, const TINVERSECDF2& InverseCDF2, const TPDF3& PDF3, const TINVERSECDF3& InverseCDF3, Result& result, int seed) 468 | { 469 | std::mt19937 rng = GetRNG(seed); 470 | std::uniform_real_distribution dist(0.0, 1.0); 471 | 472 | result.estimates.resize(c_numSamples); 473 | 474 | double lds1 = dist(rng); 475 | double lds2 = dist(rng); 476 | double lds3 = dist(rng); 477 | result.estimate = 0.0f; 478 | for (size_t i = 0; i < c_numSamples; ++i) 479 | { 480 | double x1 = InverseCDF1(lds1); 481 | double y1 = F(x1); 482 | double pdf11 = PDF1(x1); 483 | double pdf12 = PDF2(x1); 484 | double pdf13 = PDF3(x1); 485 | 486 | double x2 = InverseCDF2(lds2); 487 | double y2 = F(x2); 488 | double pdf21 = PDF1(x2); 489 | double pdf22 = PDF2(x2); 490 | double pdf23 = PDF3(x2); 491 | 492 | double x3 = InverseCDF3(lds3); 493 | double y3 = F(x3); 494 | double pdf31 = PDF1(x3); 495 | double pdf32 = PDF2(x3); 496 | double pdf33 = PDF3(x3); 497 | 498 | double value = 499 | y1 / (pdf11 + pdf12 + pdf13) + 500 | y2 / (pdf21 + pdf22 + pdf23) + 501 | y3 / (pdf31 + pdf32 + pdf33) 502 | ; 503 | 504 | AddSampleToRunningAverage(result.estimate, value, i); 505 | result.estimates[i] = result.estimate; 506 | 507 | lds1 = fmod(lds1 + c_goldeRatioConjugate, 1.0f); 508 | lds2 = fmod(lds2 + c_sqrt2, 1.0f); 509 | lds3 = fmod(lds2 + c_sqrt5, 1.0f); 510 | } 511 | } 512 | 513 | void IntegrateResult(Result& sample, int sampleCount) 514 | { 515 | AddSampleToRunningAverage(sample.estimateAvg, sample.estimate, sampleCount); 516 | AddSampleToRunningAverage(sample.estimateSqAvg, sample.estimate * sample.estimate, sampleCount); 517 | 518 | sample.estimatesAvg.resize(sample.estimates.size()); 519 | sample.estimatesSqAvg.resize(sample.estimates.size()); 520 | 521 | for (size_t index = 0; index < sample.estimates.size(); ++index) 522 | { 523 | AddSampleToRunningAverage(sample.estimatesAvg[index], sample.estimates[index], sampleCount); 524 | AddSampleToRunningAverage(sample.estimatesSqAvg[index], sample.estimates[index] * sample.estimates[index], sampleCount); 525 | } 526 | } 527 | 528 | void PDFTest1() 529 | { 530 | std::mt19937 rng = GetRNG(0); 531 | std::uniform_real_distribution dist(0.0, 1.0); 532 | 533 | double sumAverage = 0.0; 534 | 535 | // y=x normalized to y=x * 2 536 | auto PDF1 = [](double x) -> double 537 | { 538 | return x * 2.0; 539 | }; 540 | 541 | // y=1 542 | auto PDF2 = [](double x) -> double 543 | { 544 | return 1.0; 545 | }; 546 | 547 | // y=sin(x*pi) normalized to y=sin(x*pi)*pi/2 548 | auto PDF3 = [](double x) -> double 549 | { 550 | return sin(x * c_pi) * c_pi / 2.0; 551 | }; 552 | 553 | for (size_t index = 0; index < 100000; ++index) 554 | { 555 | double x = dist(rng); 556 | double sum = PDF1(x) + PDF2(x) + PDF3(x); 557 | AddSampleToRunningAverage(sumAverage, sum, index); 558 | } 559 | 560 | printf("PDFTest1: %f (%f)\n", sumAverage, sumAverage - 3.0 / 1.0); 561 | } 562 | 563 | void PDFTest2() 564 | { 565 | std::mt19937 rng = GetRNG(0); 566 | std::uniform_real_distribution dist(0.0, 5.0); 567 | 568 | double sumAverage = 0.0; 569 | //double OOSumAverage = 0.0; 570 | 571 | // y=x normalized to y=x*2/25 572 | auto PDF1 = [](double x) -> double 573 | { 574 | return x * 2.0/25.0; 575 | }; 576 | 577 | // y=1 normalized to y=1/5 578 | auto PDF2 = [](double x) -> double 579 | { 580 | return 1.0 / 5.0; 581 | }; 582 | 583 | // y=sin(x*pi/5) normalized to y=sin(x*pi/5) * pi/10 584 | auto PDF3 = [](double x) -> double 585 | { 586 | return sin(x * c_pi / 5.0) * c_pi / 10.0; 587 | }; 588 | 589 | for (size_t index = 0; index < 100000; ++index) 590 | { 591 | double x = dist(rng); 592 | double sum = PDF1(x) + PDF2(x) + PDF3(x); 593 | AddSampleToRunningAverage(sumAverage, sum, index); 594 | } 595 | 596 | printf("PDFTest2: %f (%f)\n", sumAverage, sumAverage - 3.0 / 5.0); 597 | } 598 | 599 | void PDFTest3() 600 | { 601 | std::mt19937 rng = GetRNG(0); 602 | std::uniform_real_distribution dist(0.0, 1.0); 603 | 604 | // The function we are integrating 605 | auto F = [](double x) -> double 606 | { 607 | return sin(x) * 2.0 * x; 608 | }; 609 | 610 | // the PDF and inverse CDF of distributions we are using for integration 611 | auto PDF1 = [](double x) -> double 612 | { 613 | // normalizing y=sin(x) from 0 to pi to integrate to 1 from 0 to pi 614 | return sin(x) / 2.0; 615 | }; 616 | 617 | auto InverseCDF1 = [](double x) -> double 618 | { 619 | // turning the PDF into a CDF, flipping x and y, and solving for y again 620 | return 2.0 * asin(sqrt(x)); 621 | }; 622 | 623 | auto PDF2 = [](double x) -> double 624 | { 625 | // normalizing y=2x from 0 to pi to integrate to 1 from 0 to pi 626 | return x * 2.0 / (c_pi * c_pi); 627 | }; 628 | 629 | auto InverseCDF2 = [](double x) -> double 630 | { 631 | // turning the PDF into a CDF, flipping x and y, and solving for y again 632 | return c_pi * sqrt(x); 633 | }; 634 | 635 | double c_actual = 2.0 * c_pi; 636 | 637 | double integrated1 = 0.0; 638 | double integrated2 = 0.0; 639 | double integrated = 0.0; 640 | 641 | for (size_t index = 0; index < 100000; ++index) 642 | { 643 | double rng1 = dist(rng); 644 | double x1 = InverseCDF1(rng1); 645 | double y1 = F(x1) / (PDF1(x1) + PDF2(x1)); 646 | 647 | double rng2 = dist(rng); 648 | double x2 = InverseCDF2(dist(rng)); 649 | double y2 = F(x2) / (PDF1(x2) + PDF2(x2)); 650 | 651 | AddSampleToRunningAverage(integrated1, y1, index); 652 | AddSampleToRunningAverage(integrated2, y2, index); 653 | AddSampleToRunningAverage(integrated, y1 + y2, index); 654 | } 655 | 656 | printf("PDFTest3 A: %f (%f)\n", integrated1, integrated1 - c_actual); 657 | printf("PDFTest3 B: %f (%f)\n", integrated2, integrated2 - c_actual); 658 | printf("PDFTest3 A+B: %f (%f)\n", integrated, integrated - c_actual); 659 | } 660 | 661 | double Variance(double avg, double sqAvg) 662 | { 663 | return abs(sqAvg - (avg * avg)); 664 | } 665 | 666 | void PrintfResult(const char* label, const Result& result, double actual) 667 | { 668 | double variance = Variance(result.estimateAvg, result.estimateSqAvg); 669 | printf(" %s = %f | abse %f | var %f\n", label, result.estimateAvg, abs(result.estimateAvg - actual), variance); 670 | } 671 | 672 | template 673 | void TestPDF(const TPDF& PDF, double min, double max, const char* fileName) 674 | { 675 | static const size_t c_buckets = 100; 676 | FILE* file = nullptr; 677 | fopen_s(&file, fileName, "w+b"); 678 | fprintf(file, "\"x\",\"PDF(x)\"\n"); 679 | for (size_t index = 0; index < c_buckets; ++index) 680 | { 681 | double percent = (double(index) + 0.5) / double(c_buckets); 682 | double x = Lerp(min, max, percent); 683 | double pdf = PDF(x); 684 | fprintf(file, "\"%f\",\"%f\"\n", x, pdf); 685 | } 686 | fclose(file); 687 | } 688 | 689 | template 690 | void TestICDF(const TICDF& ICDF, double min, double max, const char* fileName) 691 | { 692 | static const size_t c_buckets = 100; 693 | static const size_t c_values = 10000; 694 | 695 | std::vector histogram(c_buckets, 0); 696 | 697 | for (size_t index = 0; index < c_values; ++index) 698 | { 699 | double percent = (double(index) + 0.5) / double(c_values); 700 | double x = ICDF(percent); 701 | 702 | double xpercent = (x - min) / (max - min); 703 | size_t xbucket = Clamp(size_t(xpercent * double(c_buckets)), 0, c_buckets - 1); 704 | histogram[xbucket]++; 705 | } 706 | 707 | FILE* file = nullptr; 708 | fopen_s(&file, fileName, "w+b"); 709 | fprintf(file, "\"x\",\"count\"\n"); 710 | for (size_t index = 0; index < c_buckets; ++index) 711 | { 712 | double percent = (double(index) + 0.5) / double(c_values); 713 | fprintf(file, "\"%f\",\"%zu\"\n", percent, histogram[index]); 714 | } 715 | 716 | fclose(file); 717 | } 718 | 719 | int main(int argc, char** argv) 720 | { 721 | #if DO_PDF_TEST() // experiments to help demonstrate how and why MIS works 722 | printf("PDF tests to show aspects of MIS\n"); 723 | PDFTest1(); // showing how the expected value of the sum of 3 PDF's is 3 (instead of 1, it's from 0 to 1) 724 | PDFTest2(); // showing how the expected value of the sum of 3 PDS's are 3x too large. (0.6 instead of 0.2, it's from 0 to 5) 725 | PDFTest3(); // showing how this MIS formulaion with 2 PDFs makes two values which are each 50% sized, so adding them together makes the correct value. 726 | printf("\n\n\n"); 727 | #endif 728 | 729 | printf("%zu tests, with %zu samples each.\n\n", c_numTests, c_numSamples); 730 | 731 | // y = sin(x)*sin(x) from 0 to pi 732 | { 733 | Result mc; 734 | Result mcblue; 735 | Result mclds; 736 | Result ismc; 737 | Result ismcblue; 738 | Result ismclds; 739 | 740 | // The function we are integrating 741 | auto F = [](double x) -> double 742 | { 743 | return sin(x) * sin(x); 744 | }; 745 | 746 | // the PDF and inverse CDF of a distribution we are using for integration 747 | auto PDF = [](double x) -> double 748 | { 749 | // normalizing y=sin(x) from 0 to pi to integrate to 1 from 0 to pi 750 | return sin(x) / 2.0; 751 | }; 752 | 753 | auto InverseCDF = [](double x) -> double 754 | { 755 | // turning the PDF into a CDF, flipping x and y, and solving for y again 756 | return 2.0 * asin(sqrt(x)); 757 | }; 758 | 759 | double c_actual = c_pi / 2.0; 760 | 761 | // numerical integration 762 | for (int testIndex = 0; testIndex < c_numTests; ++testIndex) 763 | { 764 | MonteCarlo(F, mc, testIndex); 765 | MonteCarloBlue(F, mcblue, testIndex); 766 | MonteCarloLDS(F, mclds, testIndex); 767 | ImportanceSampledMonteCarlo(F, PDF, InverseCDF, ismc, testIndex); 768 | ImportanceSampledMonteCarloBlue(F, PDF, InverseCDF, ismcblue, testIndex); 769 | ImportanceSampledMonteCarloLDS(F, PDF, InverseCDF, ismclds, testIndex); 770 | 771 | IntegrateResult(mc, testIndex); 772 | IntegrateResult(mcblue, testIndex); 773 | IntegrateResult(mclds, testIndex); 774 | IntegrateResult(ismc, testIndex); 775 | IntegrateResult(ismcblue, testIndex); 776 | IntegrateResult(ismclds, testIndex); 777 | } 778 | 779 | // report results 780 | { 781 | // summary to screen 782 | printf("y = sin(x)*sin(x) from 0 to pi\n"); 783 | PrintfResult("mc ", mc, c_actual); 784 | PrintfResult("mcblue ", mcblue, c_actual); 785 | PrintfResult("mclds ", mclds, c_actual); 786 | PrintfResult("ismc ", ismc, c_actual); 787 | PrintfResult("ismcblue ", ismcblue, c_actual); 788 | PrintfResult("ismclds ", ismclds, c_actual); 789 | printf("\n"); 790 | 791 | // details to csv 792 | { 793 | FILE* file = nullptr; 794 | fopen_s(&file, "out1.abse.csv", "wb"); 795 | fprintf(file, "\"index\",\"mc\",\"mcblue\",\"mclds\",\"ismc\",\"ismcblue\",\"ismclds\"\n"); 796 | for (size_t i = 0; i < c_numSamples; ++i) 797 | { 798 | fprintf(file, "\"%zu\",", i); 799 | fprintf(file, "\"%f\",", max(abs(mc.estimatesAvg[i] - c_actual), c_minError)); 800 | fprintf(file, "\"%f\",", max(abs(mcblue.estimatesAvg[i] - c_actual), c_minError)); 801 | fprintf(file, "\"%f\",", max(abs(mclds.estimatesAvg[i] - c_actual), c_minError)); 802 | fprintf(file, "\"%f\",", max(abs(ismc.estimatesAvg[i] - c_actual), c_minError)); 803 | fprintf(file, "\"%f\",", max(abs(ismcblue.estimatesAvg[i] - c_actual), c_minError)); 804 | fprintf(file, "\"%f\",", max(abs(ismclds.estimatesAvg[i] - c_actual), c_minError)); 805 | fprintf(file, "\n"); 806 | } 807 | fclose(file); 808 | } 809 | { 810 | FILE* file = nullptr; 811 | fopen_s(&file, "out1.var.csv", "wb"); 812 | fprintf(file, "\"index\",\"mc\",\"mcblue\",\"mclds\",\"ismc\",\"ismcblue\",\"ismclds\"\n"); 813 | for (size_t i = 0; i < c_numSamples; ++i) 814 | { 815 | fprintf(file, "\"%zu\",", i); 816 | fprintf(file, "\"%f\",", max(Variance(mc.estimatesAvg[i], mc.estimatesSqAvg[i]), c_minError)); 817 | fprintf(file, "\"%f\",", max(Variance(mcblue.estimatesAvg[i], mcblue.estimatesSqAvg[i]), c_minError)); 818 | fprintf(file, "\"%f\",", max(Variance(mclds.estimatesAvg[i], mclds.estimatesSqAvg[i]), c_minError)); 819 | fprintf(file, "\"%f\",", max(Variance(ismc.estimatesAvg[i], ismc.estimatesSqAvg[i]), c_minError)); 820 | fprintf(file, "\"%f\",", max(Variance(ismcblue.estimatesAvg[i], ismcblue.estimatesSqAvg[i]), c_minError)); 821 | fprintf(file, "\"%f\",", max(Variance(ismclds.estimatesAvg[i], ismclds.estimatesSqAvg[i]), c_minError)); 822 | fprintf(file, "\n"); 823 | } 824 | fclose(file); 825 | } 826 | } 827 | } 828 | 829 | // y=sin(x)*2x from 0 to pi 830 | { 831 | Result mc; 832 | Result mcblue; 833 | Result mclds; 834 | Result ismc1; 835 | Result ismcblue1; 836 | Result ismclds1; 837 | Result ismc2; 838 | Result ismcblue2; 839 | Result ismclds2; 840 | Result mismc; 841 | Result mismcblue; 842 | Result mismclds; 843 | Result mismcstoc; 844 | 845 | // The function we are integrating 846 | auto F = [](double x) -> double 847 | { 848 | return sin(x) * 2.0 * x; 849 | }; 850 | 851 | // the PDF and inverse CDF of distributions we are using for integration 852 | auto PDF1 = [](double x) -> double 853 | { 854 | // normalizing y=sin(x) from 0 to pi to integrate to 1 from 0 to pi 855 | return sin(x) / 2.0; 856 | }; 857 | 858 | auto InverseCDF1 = [](double x) -> double 859 | { 860 | // turning the PDF into a CDF, flipping x and y, and solving for y again 861 | return 2.0 * asin(sqrt(x)); 862 | }; 863 | 864 | auto PDF2 = [](double x) -> double 865 | { 866 | // normalizing y=2x from 0 to pi to integrate to 1 from 0 to pi 867 | return x * 2.0 / (c_pi * c_pi); 868 | }; 869 | 870 | auto InverseCDF2 = [](double x) -> double 871 | { 872 | // turning the PDF into a CDF, flipping x and y, and solving for y again 873 | return c_pi * sqrt(x); 874 | }; 875 | 876 | double c_actual = 2.0 * c_pi; 877 | 878 | // numerical integration 879 | for (int testIndex = 0; testIndex < c_numTests; ++testIndex) 880 | { 881 | MonteCarlo(F, mc, testIndex); 882 | MonteCarloBlue(F, mcblue, testIndex); 883 | MonteCarloLDS(F, mclds, testIndex); 884 | ImportanceSampledMonteCarlo(F, PDF1, InverseCDF1, ismc1, testIndex); 885 | ImportanceSampledMonteCarloBlue(F, PDF1, InverseCDF1, ismcblue1, testIndex); 886 | ImportanceSampledMonteCarloLDS(F, PDF1, InverseCDF1, ismclds1, testIndex); 887 | ImportanceSampledMonteCarlo(F, PDF2, InverseCDF2, ismc2, testIndex); 888 | ImportanceSampledMonteCarloBlue(F, PDF2, InverseCDF2, ismcblue2, testIndex); 889 | ImportanceSampledMonteCarloLDS(F, PDF2, InverseCDF2, ismclds2, testIndex); 890 | MultipleImportanceSampledMonteCarlo(F, PDF1, InverseCDF1, PDF2, InverseCDF2, mismc, testIndex); 891 | MultipleImportanceSampledMonteCarloBlue(F, PDF1, InverseCDF1, PDF2, InverseCDF2, mismcblue, testIndex); 892 | MultipleImportanceSampledMonteCarloLDS(F, PDF1, InverseCDF1, PDF2, InverseCDF2, mismclds, testIndex); 893 | MultipleImportanceSampledMonteCarloStochastic(F, PDF1, InverseCDF1, PDF2, InverseCDF2, mismcstoc, testIndex); 894 | 895 | IntegrateResult(mc, testIndex); 896 | IntegrateResult(mcblue, testIndex); 897 | IntegrateResult(mclds, testIndex); 898 | IntegrateResult(ismc1, testIndex); 899 | IntegrateResult(ismcblue1, testIndex); 900 | IntegrateResult(ismclds1, testIndex); 901 | IntegrateResult(ismc2, testIndex); 902 | IntegrateResult(ismcblue2, testIndex); 903 | IntegrateResult(ismclds2, testIndex); 904 | IntegrateResult(mismc, testIndex); 905 | IntegrateResult(mismcblue, testIndex); 906 | IntegrateResult(mismclds, testIndex); 907 | IntegrateResult(mismcstoc, testIndex); 908 | } 909 | 910 | // report results 911 | { 912 | // summary to screen 913 | printf("y = sin(x)*2x from 0 to pi\n"); 914 | PrintfResult("mc ", mc, c_actual); 915 | PrintfResult("mcblue ", mcblue, c_actual); 916 | PrintfResult("mclds ", mclds, c_actual); 917 | PrintfResult("ismc1 ", ismc1, c_actual); 918 | PrintfResult("ismcblue1", ismcblue1, c_actual); 919 | PrintfResult("ismclds1 ", ismclds1, c_actual); 920 | PrintfResult("ismc2 ", ismc2, c_actual); 921 | PrintfResult("ismcblue2", ismcblue2, c_actual); 922 | PrintfResult("ismclds2 ", ismclds2, c_actual); 923 | PrintfResult("mismc ", mismc, c_actual); 924 | PrintfResult("mismcblue", mismcblue, c_actual); 925 | PrintfResult("mismclds ", mismclds, c_actual); 926 | PrintfResult("mismcstoc", mismcstoc, c_actual); 927 | printf("\n"); 928 | 929 | // details to csv 930 | { 931 | FILE* file = nullptr; 932 | fopen_s(&file, "out2.abse.csv", "wb"); 933 | fprintf(file, "\"index\",\"mc\",\"mcblue\",\"mclds\",\"ismc1\",\"ismcblue1\",\"ismclds1\",\"ismc2\",\"ismcblue2\",\"ismclds2\",\"mismc\",\"mismcblue\",\"mismcstoc\",\"mismclds\"\n"); 934 | for (size_t i = 0; i < c_numSamples; ++i) 935 | { 936 | fprintf(file, "\"%zu\",", i); 937 | fprintf(file, "\"%f\",", max(abs(mc.estimatesAvg[i] - c_actual), c_minError)); 938 | fprintf(file, "\"%f\",", max(abs(mcblue.estimatesAvg[i] - c_actual), c_minError)); 939 | fprintf(file, "\"%f\",", max(abs(mclds.estimatesAvg[i] - c_actual), c_minError)); 940 | fprintf(file, "\"%f\",", max(abs(ismc1.estimatesAvg[i] - c_actual), c_minError)); 941 | fprintf(file, "\"%f\",", max(abs(ismcblue1.estimatesAvg[i] - c_actual), c_minError)); 942 | fprintf(file, "\"%f\",", max(abs(ismclds1.estimatesAvg[i] - c_actual), c_minError)); 943 | fprintf(file, "\"%f\",", max(abs(ismc2.estimatesAvg[i] - c_actual), c_minError)); 944 | fprintf(file, "\"%f\",", max(abs(ismcblue2.estimatesAvg[i] - c_actual), c_minError)); 945 | fprintf(file, "\"%f\",", max(abs(ismclds2.estimatesAvg[i] - c_actual), c_minError)); 946 | fprintf(file, "\"%f\",", max(abs(mismc.estimatesAvg[i] - c_actual), c_minError)); 947 | fprintf(file, "\"%f\",", max(abs(mismcblue.estimatesAvg[i] - c_actual), c_minError)); 948 | fprintf(file, "\"%f\",", max(abs(mismcstoc.estimatesAvg[i] - c_actual), c_minError)); 949 | fprintf(file, "\"%f\",", max(abs(mismclds.estimatesAvg[i] - c_actual), c_minError)); 950 | fprintf(file, "\n"); 951 | } 952 | fclose(file); 953 | } 954 | { 955 | FILE* file = nullptr; 956 | fopen_s(&file, "out2.var.csv", "wb"); 957 | fprintf(file, "\"index\",\"mc\",\"mcblue\",\"mclds\",\"ismc1\",\"ismcblue1\",\"ismclds1\",\"ismc2\",\"ismcblue2\",\"ismclds2\",\"mismc\",\"mismcblue\",\"mismcstoc\",\"mismclds\"\n"); 958 | for (size_t i = 0; i < c_numSamples; ++i) 959 | { 960 | fprintf(file, "\"%zu\",", i); 961 | fprintf(file, "\"%f\",", max(Variance(mc.estimatesAvg[i], mc.estimatesSqAvg[i]), c_minError)); 962 | fprintf(file, "\"%f\",", max(Variance(mcblue.estimatesAvg[i], mcblue.estimatesSqAvg[i]), c_minError)); 963 | fprintf(file, "\"%f\",", max(Variance(mclds.estimatesAvg[i], mclds.estimatesSqAvg[i]), c_minError)); 964 | fprintf(file, "\"%f\",", max(Variance(ismc1.estimatesAvg[i], ismc1.estimatesSqAvg[i]), c_minError)); 965 | fprintf(file, "\"%f\",", max(Variance(ismcblue1.estimatesAvg[i], ismcblue1.estimatesSqAvg[i]), c_minError)); 966 | fprintf(file, "\"%f\",", max(Variance(ismclds1.estimatesAvg[i], ismclds1.estimatesSqAvg[i]), c_minError)); 967 | fprintf(file, "\"%f\",", max(Variance(ismc2.estimatesAvg[i], ismc2.estimatesSqAvg[i]), c_minError)); 968 | fprintf(file, "\"%f\",", max(Variance(ismcblue2.estimatesAvg[i], ismcblue2.estimatesSqAvg[i]), c_minError)); 969 | fprintf(file, "\"%f\",", max(Variance(ismclds2.estimatesAvg[i], ismclds2.estimatesSqAvg[i]), c_minError)); 970 | fprintf(file, "\"%f\",", max(Variance(mismc.estimatesAvg[i], mismc.estimatesSqAvg[i]), c_minError)); 971 | fprintf(file, "\"%f\",", max(Variance(mismcblue.estimatesAvg[i], mismcblue.estimatesSqAvg[i]), c_minError)); 972 | fprintf(file, "\"%f\",", max(Variance(mismcstoc.estimatesAvg[i], mismcstoc.estimatesSqAvg[i]), c_minError)); 973 | fprintf(file, "\"%f\",", max(Variance(mismclds.estimatesAvg[i], mismclds.estimatesSqAvg[i]), c_minError)); 974 | fprintf(file, "\n"); 975 | } 976 | fclose(file); 977 | } 978 | } 979 | } 980 | 981 | // y=sin(x*3)*sin(x*3)*sin(x)*sin(x) from 0 to pi 982 | { 983 | Result mc; 984 | Result mcblue; 985 | Result mclds; 986 | Result mismc; 987 | Result mismcblue; 988 | Result mismclds; 989 | 990 | // The function we are integrating 991 | auto F = [](double x) -> double 992 | { 993 | return sin(x * 3.0) * sin(x * 3.0) * sin(x) * sin(x); 994 | }; 995 | 996 | // the PDF and inverse CDF of distributions we are using for integration 997 | auto PDF = [](double x) -> double 998 | { 999 | // normalizing y=sin(x) from 0 to pi to integrate to 1 from 0 to pi 1000 | return sin(x) / 2.0; 1001 | }; 1002 | 1003 | auto InverseCDF = [](double x) -> double 1004 | { 1005 | // turning the PDF into a CDF, flipping x and y, and solving for y again 1006 | return 2.0 * asin(sqrt(x)); 1007 | }; 1008 | 1009 | // [0,1/3) 1010 | auto PDF1 = [PDF](double x) -> double 1011 | { 1012 | x = x * 3.0 - 0.0 * c_pi; 1013 | 1014 | if (x < 0.0 || x >= c_pi) 1015 | return 0.0; 1016 | 1017 | return PDF(x) * 3.0; 1018 | }; 1019 | 1020 | auto InverseCDF1 = [InverseCDF](double x) -> double 1021 | { 1022 | return InverseCDF(x) * 1.0 / 3.0 + c_pi * 0.0 / 3.0; 1023 | }; 1024 | 1025 | // [1/3,2/3) 1026 | auto PDF2 = [PDF](double x) -> double 1027 | { 1028 | x = x * 3.0 - 1.0 * c_pi; 1029 | 1030 | if (x < 0.0 || x >= c_pi) 1031 | return 0.0; 1032 | 1033 | return PDF(x) * 3.0; 1034 | }; 1035 | 1036 | auto InverseCDF2 = [InverseCDF](double x) -> double 1037 | { 1038 | return InverseCDF(x) * 1.0 / 3.0 + c_pi * 1.0 / 3.0; 1039 | }; 1040 | 1041 | // [2/3,2/3] 1042 | auto PDF3 = [PDF](double x) -> double 1043 | { 1044 | x = x * 3.0 - 2.0 * c_pi; 1045 | 1046 | if (x < 0.0 || x > c_pi) 1047 | return 0.0; 1048 | 1049 | return PDF(x) * 3.0; 1050 | }; 1051 | 1052 | auto InverseCDF3 = [InverseCDF](double x) -> double 1053 | { 1054 | return InverseCDF(x) * 1.0 / 3.0 + c_pi * 2.0 / 3.0; 1055 | }; 1056 | 1057 | TestPDF(PDF1, 0.0, c_pi, "out3_pdf1.csv"); 1058 | TestPDF(PDF2, 0.0, c_pi, "out3_pdf2.csv"); 1059 | TestPDF(PDF3, 0.0, c_pi, "out3_pdf3.csv"); 1060 | TestICDF(InverseCDF1, 0.0, c_pi, "out3_icdf1.csv"); 1061 | TestICDF(InverseCDF2, 0.0, c_pi, "out3_icdf2.csv"); 1062 | TestICDF(InverseCDF3, 0.0, c_pi, "out3_icdf3.csv"); 1063 | 1064 | double c_actual = c_pi / 4.0; 1065 | 1066 | // numerical integration 1067 | for (int testIndex = 0; testIndex < c_numTests; ++testIndex) 1068 | { 1069 | MonteCarlo(F, mc, testIndex); 1070 | MonteCarloBlue(F, mcblue, testIndex); 1071 | MonteCarloLDS(F, mclds, testIndex); 1072 | MultipleImportanceSampledMonteCarlo(F, PDF1, InverseCDF1, PDF2, InverseCDF2, PDF3, InverseCDF3, mismc, testIndex); 1073 | MultipleImportanceSampledMonteCarloBlue(F, PDF1, InverseCDF1, PDF2, InverseCDF2, PDF3, InverseCDF3, mismcblue, testIndex); 1074 | MultipleImportanceSampledMonteCarloLDS(F, PDF1, InverseCDF1, PDF2, InverseCDF2, PDF3, InverseCDF3, mismclds, testIndex); 1075 | 1076 | IntegrateResult(mc, testIndex); 1077 | IntegrateResult(mcblue, testIndex); 1078 | IntegrateResult(mclds, testIndex); 1079 | IntegrateResult(mismc, testIndex); 1080 | IntegrateResult(mismcblue, testIndex); 1081 | IntegrateResult(mismclds, testIndex); 1082 | } 1083 | 1084 | // report results 1085 | { 1086 | // summary to screen 1087 | printf("y = sin(x*3)*sin(x*3)*sin(x)*sin(x) from 0 to pi\n"); 1088 | PrintfResult("mc ", mc, c_actual); 1089 | PrintfResult("mcblue ", mcblue, c_actual); 1090 | PrintfResult("mclds ", mclds, c_actual); 1091 | PrintfResult("mismc ", mismc, c_actual); 1092 | PrintfResult("mismcblue", mismcblue, c_actual); 1093 | PrintfResult("mismclds ", mismclds, c_actual); 1094 | printf("\n"); 1095 | 1096 | // details to csv 1097 | { 1098 | FILE* file = nullptr; 1099 | fopen_s(&file, "out3.abse.csv", "wb"); 1100 | fprintf(file, "\"index\",\"mc\",\"mcblue\",\"mclds\",\"mismc\",\"mismcblue\",\"mismclds\"\n"); 1101 | for (size_t i = 0; i < c_numSamples; ++i) 1102 | { 1103 | fprintf(file, "\"%zu\",", i); 1104 | fprintf(file, "\"%f\",", max(abs(mc.estimatesAvg[i] - c_actual), c_minError)); 1105 | fprintf(file, "\"%f\",", max(abs(mcblue.estimatesAvg[i] - c_actual), c_minError)); 1106 | fprintf(file, "\"%f\",", max(abs(mclds.estimatesAvg[i] - c_actual), c_minError)); 1107 | fprintf(file, "\"%f\",", max(abs(mismc.estimatesAvg[i] - c_actual), c_minError)); 1108 | fprintf(file, "\"%f\",", max(abs(mismcblue.estimatesAvg[i] - c_actual), c_minError)); 1109 | fprintf(file, "\"%f\",", max(abs(mismclds.estimatesAvg[i] - c_actual), c_minError)); 1110 | fprintf(file, "\n"); 1111 | } 1112 | fclose(file); 1113 | } 1114 | { 1115 | FILE* file = nullptr; 1116 | fopen_s(&file, "out3.var.csv", "wb"); 1117 | fprintf(file, "\"index\",\"mc\",\"mcblue\",\"mclds\",\"mismc\",\"mismcblue\",\"mismclds\"\n"); 1118 | for (size_t i = 0; i < c_numSamples; ++i) 1119 | { 1120 | fprintf(file, "\"%zu\",", i); 1121 | fprintf(file, "\"%f\",", max(Variance(mc.estimatesAvg[i], mc.estimatesSqAvg[i]), c_minError)); 1122 | fprintf(file, "\"%f\",", max(Variance(mcblue.estimatesAvg[i], mcblue.estimatesSqAvg[i]), c_minError)); 1123 | fprintf(file, "\"%f\",", max(Variance(mclds.estimatesAvg[i], mclds.estimatesSqAvg[i]), c_minError)); 1124 | fprintf(file, "\"%f\",", max(Variance(mismc.estimatesAvg[i], mismc.estimatesSqAvg[i]), c_minError)); 1125 | fprintf(file, "\"%f\",", max(Variance(mismcblue.estimatesAvg[i], mismcblue.estimatesSqAvg[i]), c_minError)); 1126 | fprintf(file, "\"%f\",", max(Variance(mismclds.estimatesAvg[i], mismclds.estimatesSqAvg[i]), c_minError)); 1127 | fprintf(file, "\n"); 1128 | } 1129 | fclose(file); 1130 | } 1131 | } 1132 | } 1133 | 1134 | return 0; 1135 | } 1136 | -------------------------------------------------------------------------------- /mis.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30711.63 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mis", "mis.vcxproj", "{D08E800A-A8CC-45D5-9F4B-EB86B08271F2}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D08E800A-A8CC-45D5-9F4B-EB86B08271F2}.Debug|x64.ActiveCfg = Debug|x64 15 | {D08E800A-A8CC-45D5-9F4B-EB86B08271F2}.Debug|x64.Build.0 = Debug|x64 16 | {D08E800A-A8CC-45D5-9F4B-EB86B08271F2}.Release|x64.ActiveCfg = Release|x64 17 | {D08E800A-A8CC-45D5-9F4B-EB86B08271F2}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {46804A6C-F845-4E78-B333-BBE72C43B5DC} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /mis.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {d08e800a-a8cc-45d5-9f4b-eb86b08271f2} 25 | mis 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Level3 100 | true 101 | true 102 | true 103 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | 106 | 107 | Console 108 | true 109 | true 110 | true 111 | 112 | 113 | 114 | 115 | Level3 116 | true 117 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | true 119 | 120 | 121 | Console 122 | true 123 | 124 | 125 | 126 | 127 | Level3 128 | true 129 | true 130 | true 131 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 132 | true 133 | 134 | 135 | Console 136 | true 137 | true 138 | true 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /mis.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /out3_icdf1.csv: -------------------------------------------------------------------------------- 1 | "x","count" 2 | "0.000050","22" 3 | "0.000150","67" 4 | "0.000250","110" 5 | "0.000350","152" 6 | "0.000450","194" 7 | "0.000550","233" 8 | "0.000650","271" 9 | "0.000750","306" 10 | "0.000850","338" 11 | "0.000950","368" 12 | "0.001050","394" 13 | "0.001150","416" 14 | "0.001250","435" 15 | "0.001350","451" 16 | "0.001450","461" 17 | "0.001550","468" 18 | "0.001650","471" 19 | "0.001750","470" 20 | "0.001850","464" 21 | "0.001950","454" 22 | "0.002050","441" 23 | "0.002150","423" 24 | "0.002250","401" 25 | "0.002350","377" 26 | "0.002450","349" 27 | "0.002550","317" 28 | "0.002650","282" 29 | "0.002750","247" 30 | "0.002850","207" 31 | "0.002950","166" 32 | "0.003050","125" 33 | "0.003150","81" 34 | "0.003250","37" 35 | "0.003350","2" 36 | "0.003450","0" 37 | "0.003550","0" 38 | "0.003650","0" 39 | "0.003750","0" 40 | "0.003850","0" 41 | "0.003950","0" 42 | "0.004050","0" 43 | "0.004150","0" 44 | "0.004250","0" 45 | "0.004350","0" 46 | "0.004450","0" 47 | "0.004550","0" 48 | "0.004650","0" 49 | "0.004750","0" 50 | "0.004850","0" 51 | "0.004950","0" 52 | "0.005050","0" 53 | "0.005150","0" 54 | "0.005250","0" 55 | "0.005350","0" 56 | "0.005450","0" 57 | "0.005550","0" 58 | "0.005650","0" 59 | "0.005750","0" 60 | "0.005850","0" 61 | "0.005950","0" 62 | "0.006050","0" 63 | "0.006150","0" 64 | "0.006250","0" 65 | "0.006350","0" 66 | "0.006450","0" 67 | "0.006550","0" 68 | "0.006650","0" 69 | "0.006750","0" 70 | "0.006850","0" 71 | "0.006950","0" 72 | "0.007050","0" 73 | "0.007150","0" 74 | "0.007250","0" 75 | "0.007350","0" 76 | "0.007450","0" 77 | "0.007550","0" 78 | "0.007650","0" 79 | "0.007750","0" 80 | "0.007850","0" 81 | "0.007950","0" 82 | "0.008050","0" 83 | "0.008150","0" 84 | "0.008250","0" 85 | "0.008350","0" 86 | "0.008450","0" 87 | "0.008550","0" 88 | "0.008650","0" 89 | "0.008750","0" 90 | "0.008850","0" 91 | "0.008950","0" 92 | "0.009050","0" 93 | "0.009150","0" 94 | "0.009250","0" 95 | "0.009350","0" 96 | "0.009450","0" 97 | "0.009550","0" 98 | "0.009650","0" 99 | "0.009750","0" 100 | "0.009850","0" 101 | "0.009950","0" 102 | -------------------------------------------------------------------------------- /out3_icdf2.csv: -------------------------------------------------------------------------------- 1 | "x","count" 2 | "0.000050","0" 3 | "0.000150","0" 4 | "0.000250","0" 5 | "0.000350","0" 6 | "0.000450","0" 7 | "0.000550","0" 8 | "0.000650","0" 9 | "0.000750","0" 10 | "0.000850","0" 11 | "0.000950","0" 12 | "0.001050","0" 13 | "0.001150","0" 14 | "0.001250","0" 15 | "0.001350","0" 16 | "0.001450","0" 17 | "0.001550","0" 18 | "0.001650","0" 19 | "0.001750","0" 20 | "0.001850","0" 21 | "0.001950","0" 22 | "0.002050","0" 23 | "0.002150","0" 24 | "0.002250","0" 25 | "0.002350","0" 26 | "0.002450","0" 27 | "0.002550","0" 28 | "0.002650","0" 29 | "0.002750","0" 30 | "0.002850","0" 31 | "0.002950","0" 32 | "0.003050","0" 33 | "0.003150","0" 34 | "0.003250","0" 35 | "0.003350","10" 36 | "0.003450","52" 37 | "0.003550","95" 38 | "0.003650","139" 39 | "0.003750","180" 40 | "0.003850","220" 41 | "0.003950","259" 42 | "0.004050","294" 43 | "0.004150","328" 44 | "0.004250","358" 45 | "0.004350","386" 46 | "0.004450","409" 47 | "0.004550","429" 48 | "0.004650","446" 49 | "0.004750","458" 50 | "0.004850","466" 51 | "0.004950","471" 52 | "0.005050","471" 53 | "0.005150","466" 54 | "0.005250","458" 55 | "0.005350","446" 56 | "0.005450","429" 57 | "0.005550","409" 58 | "0.005650","386" 59 | "0.005750","358" 60 | "0.005850","328" 61 | "0.005950","294" 62 | "0.006050","259" 63 | "0.006150","220" 64 | "0.006250","180" 65 | "0.006350","139" 66 | "0.006450","95" 67 | "0.006550","52" 68 | "0.006650","10" 69 | "0.006750","0" 70 | "0.006850","0" 71 | "0.006950","0" 72 | "0.007050","0" 73 | "0.007150","0" 74 | "0.007250","0" 75 | "0.007350","0" 76 | "0.007450","0" 77 | "0.007550","0" 78 | "0.007650","0" 79 | "0.007750","0" 80 | "0.007850","0" 81 | "0.007950","0" 82 | "0.008050","0" 83 | "0.008150","0" 84 | "0.008250","0" 85 | "0.008350","0" 86 | "0.008450","0" 87 | "0.008550","0" 88 | "0.008650","0" 89 | "0.008750","0" 90 | "0.008850","0" 91 | "0.008950","0" 92 | "0.009050","0" 93 | "0.009150","0" 94 | "0.009250","0" 95 | "0.009350","0" 96 | "0.009450","0" 97 | "0.009550","0" 98 | "0.009650","0" 99 | "0.009750","0" 100 | "0.009850","0" 101 | "0.009950","0" 102 | -------------------------------------------------------------------------------- /out3_icdf3.csv: -------------------------------------------------------------------------------- 1 | "x","count" 2 | "0.000050","0" 3 | "0.000150","0" 4 | "0.000250","0" 5 | "0.000350","0" 6 | "0.000450","0" 7 | "0.000550","0" 8 | "0.000650","0" 9 | "0.000750","0" 10 | "0.000850","0" 11 | "0.000950","0" 12 | "0.001050","0" 13 | "0.001150","0" 14 | "0.001250","0" 15 | "0.001350","0" 16 | "0.001450","0" 17 | "0.001550","0" 18 | "0.001650","0" 19 | "0.001750","0" 20 | "0.001850","0" 21 | "0.001950","0" 22 | "0.002050","0" 23 | "0.002150","0" 24 | "0.002250","0" 25 | "0.002350","0" 26 | "0.002450","0" 27 | "0.002550","0" 28 | "0.002650","0" 29 | "0.002750","0" 30 | "0.002850","0" 31 | "0.002950","0" 32 | "0.003050","0" 33 | "0.003150","0" 34 | "0.003250","0" 35 | "0.003350","0" 36 | "0.003450","0" 37 | "0.003550","0" 38 | "0.003650","0" 39 | "0.003750","0" 40 | "0.003850","0" 41 | "0.003950","0" 42 | "0.004050","0" 43 | "0.004150","0" 44 | "0.004250","0" 45 | "0.004350","0" 46 | "0.004450","0" 47 | "0.004550","0" 48 | "0.004650","0" 49 | "0.004750","0" 50 | "0.004850","0" 51 | "0.004950","0" 52 | "0.005050","0" 53 | "0.005150","0" 54 | "0.005250","0" 55 | "0.005350","0" 56 | "0.005450","0" 57 | "0.005550","0" 58 | "0.005650","0" 59 | "0.005750","0" 60 | "0.005850","0" 61 | "0.005950","0" 62 | "0.006050","0" 63 | "0.006150","0" 64 | "0.006250","0" 65 | "0.006350","0" 66 | "0.006450","0" 67 | "0.006550","0" 68 | "0.006650","2" 69 | "0.006750","37" 70 | "0.006850","81" 71 | "0.006950","125" 72 | "0.007050","166" 73 | "0.007150","207" 74 | "0.007250","247" 75 | "0.007350","282" 76 | "0.007450","317" 77 | "0.007550","349" 78 | "0.007650","377" 79 | "0.007750","401" 80 | "0.007850","423" 81 | "0.007950","441" 82 | "0.008050","454" 83 | "0.008150","464" 84 | "0.008250","470" 85 | "0.008350","471" 86 | "0.008450","468" 87 | "0.008550","461" 88 | "0.008650","451" 89 | "0.008750","435" 90 | "0.008850","416" 91 | "0.008950","394" 92 | "0.009050","368" 93 | "0.009150","338" 94 | "0.009250","306" 95 | "0.009350","271" 96 | "0.009450","233" 97 | "0.009550","194" 98 | "0.009650","152" 99 | "0.009750","110" 100 | "0.009850","67" 101 | "0.009950","22" 102 | -------------------------------------------------------------------------------- /out3_pdf1.csv: -------------------------------------------------------------------------------- 1 | "x","PDF(x)" 2 | "0.015708","0.070660" 3 | "0.047124","0.211352" 4 | "0.078540","0.350168" 5 | "0.109956","0.485876" 6 | "0.141372","0.617272" 7 | "0.172788","0.743188" 8 | "0.204204","0.862508" 9 | "0.235619","0.974172" 10 | "0.267035","1.077189" 11 | "0.298451","1.170646" 12 | "0.329867","1.253711" 13 | "0.361283","1.325648" 14 | "0.392699","1.385819" 15 | "0.424115","1.433690" 16 | "0.455531","1.468834" 17 | "0.486947","1.490941" 18 | "0.518363","1.499815" 19 | "0.549779","1.495376" 20 | "0.581195","1.477664" 21 | "0.612611","1.446836" 22 | "0.644026","1.403166" 23 | "0.675442","1.347041" 24 | "0.706858","1.278960" 25 | "0.738274","1.199527" 26 | "0.769690","1.109447" 27 | "0.801106","1.009519" 28 | "0.832522","0.900630" 29 | "0.863938","0.783748" 30 | "0.895354","0.659909" 31 | "0.926770","0.530212" 32 | "0.958186","0.395810" 33 | "0.989602","0.257894" 34 | "1.021018","0.117689" 35 | "1.052434","0.000000" 36 | "1.083849","0.000000" 37 | "1.115265","0.000000" 38 | "1.146681","0.000000" 39 | "1.178097","0.000000" 40 | "1.209513","0.000000" 41 | "1.240929","0.000000" 42 | "1.272345","0.000000" 43 | "1.303761","0.000000" 44 | "1.335177","0.000000" 45 | "1.366593","0.000000" 46 | "1.398009","0.000000" 47 | "1.429425","0.000000" 48 | "1.460841","0.000000" 49 | "1.492257","0.000000" 50 | "1.523672","0.000000" 51 | "1.555088","0.000000" 52 | "1.586504","0.000000" 53 | "1.617920","0.000000" 54 | "1.649336","0.000000" 55 | "1.680752","0.000000" 56 | "1.712168","0.000000" 57 | "1.743584","0.000000" 58 | "1.775000","0.000000" 59 | "1.806416","0.000000" 60 | "1.837832","0.000000" 61 | "1.869248","0.000000" 62 | "1.900664","0.000000" 63 | "1.932079","0.000000" 64 | "1.963495","0.000000" 65 | "1.994911","0.000000" 66 | "2.026327","0.000000" 67 | "2.057743","0.000000" 68 | "2.089159","0.000000" 69 | "2.120575","0.000000" 70 | "2.151991","0.000000" 71 | "2.183407","0.000000" 72 | "2.214823","0.000000" 73 | "2.246239","0.000000" 74 | "2.277655","0.000000" 75 | "2.309071","0.000000" 76 | "2.340487","0.000000" 77 | "2.371902","0.000000" 78 | "2.403318","0.000000" 79 | "2.434734","0.000000" 80 | "2.466150","0.000000" 81 | "2.497566","0.000000" 82 | "2.528982","0.000000" 83 | "2.560398","0.000000" 84 | "2.591814","0.000000" 85 | "2.623230","0.000000" 86 | "2.654646","0.000000" 87 | "2.686062","0.000000" 88 | "2.717478","0.000000" 89 | "2.748894","0.000000" 90 | "2.780309","0.000000" 91 | "2.811725","0.000000" 92 | "2.843141","0.000000" 93 | "2.874557","0.000000" 94 | "2.905973","0.000000" 95 | "2.937389","0.000000" 96 | "2.968805","0.000000" 97 | "3.000221","0.000000" 98 | "3.031637","0.000000" 99 | "3.063053","0.000000" 100 | "3.094469","0.000000" 101 | "3.125885","0.000000" 102 | -------------------------------------------------------------------------------- /out3_pdf2.csv: -------------------------------------------------------------------------------- 1 | "x","PDF(x)" 2 | "0.015708","0.000000" 3 | "0.047124","0.000000" 4 | "0.078540","0.000000" 5 | "0.109956","0.000000" 6 | "0.141372","0.000000" 7 | "0.172788","0.000000" 8 | "0.204204","0.000000" 9 | "0.235619","0.000000" 10 | "0.267035","0.000000" 11 | "0.298451","0.000000" 12 | "0.329867","0.000000" 13 | "0.361283","0.000000" 14 | "0.392699","0.000000" 15 | "0.424115","0.000000" 16 | "0.455531","0.000000" 17 | "0.486947","0.000000" 18 | "0.518363","0.000000" 19 | "0.549779","0.000000" 20 | "0.581195","0.000000" 21 | "0.612611","0.000000" 22 | "0.644026","0.000000" 23 | "0.675442","0.000000" 24 | "0.706858","0.000000" 25 | "0.738274","0.000000" 26 | "0.769690","0.000000" 27 | "0.801106","0.000000" 28 | "0.832522","0.000000" 29 | "0.863938","0.000000" 30 | "0.895354","0.000000" 31 | "0.926770","0.000000" 32 | "0.958186","0.000000" 33 | "0.989602","0.000000" 34 | "1.021018","0.000000" 35 | "1.052434","0.023561" 36 | "1.083849","0.164601" 37 | "1.115265","0.304181" 38 | "1.146681","0.441060" 39 | "1.178097","0.574025" 40 | "1.209513","0.701895" 41 | "1.240929","0.823534" 42 | "1.272345","0.937864" 43 | "1.303761","1.043869" 44 | "1.335177","1.140609" 45 | "1.366593","1.227225" 46 | "1.398009","1.302947" 47 | "1.429425","1.367105" 48 | "1.460841","1.419128" 49 | "1.492257","1.458555" 50 | "1.523672","1.485035" 51 | "1.555088","1.498335" 52 | "1.586504","1.498335" 53 | "1.617920","1.485035" 54 | "1.649336","1.458555" 55 | "1.680752","1.419128" 56 | "1.712168","1.367105" 57 | "1.743584","1.302947" 58 | "1.775000","1.227225" 59 | "1.806416","1.140609" 60 | "1.837832","1.043869" 61 | "1.869248","0.937864" 62 | "1.900664","0.823534" 63 | "1.932079","0.701895" 64 | "1.963495","0.574025" 65 | "1.994911","0.441060" 66 | "2.026327","0.304181" 67 | "2.057743","0.164601" 68 | "2.089159","0.023561" 69 | "2.120575","0.000000" 70 | "2.151991","0.000000" 71 | "2.183407","0.000000" 72 | "2.214823","0.000000" 73 | "2.246239","0.000000" 74 | "2.277655","0.000000" 75 | "2.309071","0.000000" 76 | "2.340487","0.000000" 77 | "2.371902","0.000000" 78 | "2.403318","0.000000" 79 | "2.434734","0.000000" 80 | "2.466150","0.000000" 81 | "2.497566","0.000000" 82 | "2.528982","0.000000" 83 | "2.560398","0.000000" 84 | "2.591814","0.000000" 85 | "2.623230","0.000000" 86 | "2.654646","0.000000" 87 | "2.686062","0.000000" 88 | "2.717478","0.000000" 89 | "2.748894","0.000000" 90 | "2.780309","0.000000" 91 | "2.811725","0.000000" 92 | "2.843141","0.000000" 93 | "2.874557","0.000000" 94 | "2.905973","0.000000" 95 | "2.937389","0.000000" 96 | "2.968805","0.000000" 97 | "3.000221","0.000000" 98 | "3.031637","0.000000" 99 | "3.063053","0.000000" 100 | "3.094469","0.000000" 101 | "3.125885","0.000000" 102 | -------------------------------------------------------------------------------- /out3_pdf3.csv: -------------------------------------------------------------------------------- 1 | "x","PDF(x)" 2 | "0.015708","0.000000" 3 | "0.047124","0.000000" 4 | "0.078540","0.000000" 5 | "0.109956","0.000000" 6 | "0.141372","0.000000" 7 | "0.172788","0.000000" 8 | "0.204204","0.000000" 9 | "0.235619","0.000000" 10 | "0.267035","0.000000" 11 | "0.298451","0.000000" 12 | "0.329867","0.000000" 13 | "0.361283","0.000000" 14 | "0.392699","0.000000" 15 | "0.424115","0.000000" 16 | "0.455531","0.000000" 17 | "0.486947","0.000000" 18 | "0.518363","0.000000" 19 | "0.549779","0.000000" 20 | "0.581195","0.000000" 21 | "0.612611","0.000000" 22 | "0.644026","0.000000" 23 | "0.675442","0.000000" 24 | "0.706858","0.000000" 25 | "0.738274","0.000000" 26 | "0.769690","0.000000" 27 | "0.801106","0.000000" 28 | "0.832522","0.000000" 29 | "0.863938","0.000000" 30 | "0.895354","0.000000" 31 | "0.926770","0.000000" 32 | "0.958186","0.000000" 33 | "0.989602","0.000000" 34 | "1.021018","0.000000" 35 | "1.052434","0.000000" 36 | "1.083849","0.000000" 37 | "1.115265","0.000000" 38 | "1.146681","0.000000" 39 | "1.178097","0.000000" 40 | "1.209513","0.000000" 41 | "1.240929","0.000000" 42 | "1.272345","0.000000" 43 | "1.303761","0.000000" 44 | "1.335177","0.000000" 45 | "1.366593","0.000000" 46 | "1.398009","0.000000" 47 | "1.429425","0.000000" 48 | "1.460841","0.000000" 49 | "1.492257","0.000000" 50 | "1.523672","0.000000" 51 | "1.555088","0.000000" 52 | "1.586504","0.000000" 53 | "1.617920","0.000000" 54 | "1.649336","0.000000" 55 | "1.680752","0.000000" 56 | "1.712168","0.000000" 57 | "1.743584","0.000000" 58 | "1.775000","0.000000" 59 | "1.806416","0.000000" 60 | "1.837832","0.000000" 61 | "1.869248","0.000000" 62 | "1.900664","0.000000" 63 | "1.932079","0.000000" 64 | "1.963495","0.000000" 65 | "1.994911","0.000000" 66 | "2.026327","0.000000" 67 | "2.057743","0.000000" 68 | "2.089159","0.000000" 69 | "2.120575","0.117689" 70 | "2.151991","0.257894" 71 | "2.183407","0.395810" 72 | "2.214823","0.530212" 73 | "2.246239","0.659909" 74 | "2.277655","0.783748" 75 | "2.309071","0.900630" 76 | "2.340487","1.009519" 77 | "2.371902","1.109447" 78 | "2.403318","1.199527" 79 | "2.434734","1.278960" 80 | "2.466150","1.347041" 81 | "2.497566","1.403166" 82 | "2.528982","1.446836" 83 | "2.560398","1.477664" 84 | "2.591814","1.495376" 85 | "2.623230","1.499815" 86 | "2.654646","1.490941" 87 | "2.686062","1.468834" 88 | "2.717478","1.433690" 89 | "2.748894","1.385819" 90 | "2.780309","1.325648" 91 | "2.811725","1.253711" 92 | "2.843141","1.170646" 93 | "2.874557","1.077189" 94 | "2.905973","0.974172" 95 | "2.937389","0.862508" 96 | "2.968805","0.743188" 97 | "3.000221","0.617272" 98 | "3.031637","0.485876" 99 | "3.063053","0.350168" 100 | "3.094469","0.211352" 101 | "3.125885","0.070660" 102 | --------------------------------------------------------------------------------