Line data Source code
1 : // Copyright 2023 The terCAD team. All rights reserved.
2 : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
3 :
4 : import 'dart:math';
5 :
6 : import 'package:material_ui/material_ui.dart';
7 :
8 : class MonteCarloSimulation {
9 : final Random random = Random();
10 : final int cycles;
11 : final double coercion;
12 :
13 0 : MonteCarloSimulation({this.cycles = 30, this.coercion = 1});
14 :
15 0 : List<Offset> generate(List<Offset> scope, double step, double max) {
16 0 : final List<List<double>> distribution = [];
17 0 : for (int i = 0; i < scope.length; i++) {
18 0 : final state = mcNormal(scope[i].dy, coercion, cycles);
19 0 : for (int j = 0; j < state.length; j++) {
20 0 : if (j >= distribution.length) {
21 0 : distribution.add([]);
22 : }
23 0 : distribution[j].add(state[j]);
24 : }
25 : }
26 0 : double posX = scope.last.dx + step;
27 0 : List<Offset> result = [];
28 : int idx = 0;
29 0 : while (posX <= max) {
30 0 : result.add(Offset(posX, distribution[idx][distribution[idx].length * random.nextDouble() ~/ 1]));
31 0 : posX += step;
32 0 : idx++;
33 : }
34 : return result;
35 : }
36 :
37 0 : List<double> mcNormal(double mean, double stdDev, int samples) {
38 0 : List<double> results = [];
39 0 : for (int i = 0; i < samples; i++) {
40 0 : results.add(_normalRandom(mean, stdDev));
41 : }
42 : return results;
43 : }
44 :
45 0 : double _normalRandom(double mean, double stdDev) {
46 0 : double u1 = random.nextDouble();
47 0 : double u2 = random.nextDouble();
48 0 : double z0 = sqrt(-2.0 * log(u1)) * cos(2 * pi * u2);
49 0 : return mean + stdDev * z0;
50 : }
51 : }
|