private void Init()
        {
            this.prj.CreateSymbols();
            this.prj.Initialize();
            this.prj.CreateSymbols();

            //calculate simulation dates and delta t
            double T = this.prj.GetTotalTime();

            double dt = T / this.S;

            this.simulationDates = new double[this.S];
            this.deltaT          = new double[this.S];
            for (int i = 0; i < this.S; i++)
            {
                this.simulationDates[i] = i * dt;
                this.deltaT[i]          = dt;
            }

            this.isLog = new bool[this.prj.Processes.Count];
            for (int u = 0; u < this.prj.Processes.Count; u++)
            {
                StocasticProcess s = this.prj.Processes[u];

                this.isLog[u] = s.IsLog()[0];//todo: fix for multivariate
                if (s is StochasticProcessExtendible)
                {
                    (s as StochasticProcessExtendible).process.Setup(this.simulationDates);
                }
            }

            this.prj.Processes.GetCorrelationMatrix();
            SolverBase.MatrixTransformations.CalculateVolatilityMatrix(0, this.prj.Processes, out this.VarCov);

            this.D = this.VarCov.R; //Number of components

            switch (this.D)
            {
            case 1:
                this.ProbTreshold = .5;
                break;

            case 2:
                this.ProbTreshold = .4;
                break;

            case 3:
                this.ProbTreshold = .3;
                break;

            case 4:
                this.ProbTreshold = .2;
                break;

            default:
                this.ProbTreshold = .1;
                break;
            }

            this.rfunctions = this.prj.Symbols.GetRFunctions();
            this.F          = this.rfunctions.Count;

            this.rfunctionR0Id   = new int[this.rfunctions.Count];
            this.rfunctionsExpId = new int[this.rfunctions.Count];
            for (int f = 0; f < this.F; f++)
            {
                this.rfunctionR0Id[f]   = Engine.Parser.Parse(this.rfunctions[f].m_R0);
                this.rfunctionsExpId[f] = Engine.Parser.Parse(this.rfunctions[f].m_UpdateExpression);
            }
            //Get Names
            this.componentNames = new List <string>();
            for (int d = 0; d < this.D; d++)
            {
                this.componentNames.Add(this.prj.Processes[d].description);
            }
            for (int f = 0; f < this.F; f++)
            {
                this.componentNames.Add(this.rfunctions[f].VarName);
            }
        }
        private unsafe List <TreeNode> GenerateChildNodes(TreeNode entryNode)
        {
            List <TreeNode> Outcomes = new List <TreeNode>();

            double delta_t   = deltaT[entryNode.Period];
            double r_delta_t = Math.Sqrt(delta_t);

            //otherwise Z is already calculated
            if (entryNode.Period >= this.randomizedBranchingStartPeriod)
            {
                if (rng.NextDouble() >= this.ProbTreshold)
                {
                    //return a zero idd outcome
                    this.Z = new List <Matrix>();
                    Matrix o = new Matrix(this.D, 1);//considers only  the stochastic components
                    this.Z.Add(o);
                }
                else
                {
                    this.Z = IIDOutcomesBySimulation(this.D, MonteCarloRealizations);//considers only  the stochastic components
                }
            }

            //iterates through the outcomes
            for (int s = 0; s < this.Z.Count; s++)
            {
                //Transform...
                Matrix epsilon = this.A * this.Z[s];

                TreeNode outcome = new TreeNode();
                outcome.Value       = new float[this.D + this.F];
                outcome.Probability = entryNode.Probability / this.Z.Count;
                outcome.Period      = entryNode.Period + 1;
                outcome.Predecessor = entryNode;

                //Double precision version
                Vector X = new Vector(this.D);
                for (int j = 0; j < this.D; j++)
                {
                    X[j] = entryNode.Value[j];
                }

                int i = entryNode.Period + 1;

                //iterates through the components of vector X
                for (int j = 0; j < this.D; j++)
                {
                    StocasticProcess sp = this.prj.Processes[j];

                    if (this.approximationType == 0)
                    {
                        if (!this.isLog[j])
                        {
                            outcome.Value[j] = entryNode.Value[j] + (float)(delta_t * sp.a(i, X.Buffer) + r_delta_t * epsilon[j, 0]);
                        }
                        else
                        {
                            outcome.Value[j] = entryNode.Value[j] * (float)Math.Exp(delta_t * sp.a(i, X.Buffer)
                                                                                    + r_delta_t * epsilon[j, 0] - 0.5 * delta_t * Math.Pow(this.A[j, j], 2));
                        }
                    }
                }

                //calculates the remaining components
                SetVariableValues(outcome);
                for (int j = 0; j < this.F; j++)
                {
                    outcome.Value[this.D + j] = (float)Engine.Parser.Evaluate(this.rfunctionsExpId[j]);
                }

                Outcomes.Add(outcome);
            }

            return(Outcomes);
        }