///<summary>
        ///</summary>
        ///<param name="process"></param>
        ///<param name="timeGrid"></param>
        ///<param name="isPositive"></param>
        public TrinomialTree(IDiffusionProcess process,
                             ITimeGrid timeGrid, bool isPositive) : base(timeGrid.Count)
        {
            TimeGrid = timeGrid;
            _x0      = process.X0;
            _dx      = new double[timeGrid.Count];
            // dx[0] = 0.0;
            int nTimeSteps = timeGrid.Count - 1;
            int jMin       = 0;
            int jMax       = 0;

            _branchings = new TrinomialBranching[nTimeSteps];
            for (int i = 0; i < nTimeSteps; i++)
            {
                double t  = timeGrid[i];
                double dt = timeGrid.Dt(i);
                //Variance must be independent of x
                double v2 = process.Variance(t, 0.0, dt);
                double v  = Math.Sqrt(v2);
                _dx[i + 1] = v * Math.Sqrt(3.0);            // Add dx
                var branching =
                    new TrinomialBranching(jMax - jMin + 1);
                int jNewMin = int.MaxValue;
                int jNewMax = int.MinValue;
                for (int j = jMin; j <= jMax; j++)
                {
                    double x    = _x0 + j * _dx[i];
                    double m    = process.Expectation(t, x, dt);
                    var    temp = (int)Math.Floor((m - _x0) / _dx[i + 1] + 0.5);
                    if (isPositive)
                    {
                        while (_x0 + (temp - 1) * _dx[i + 1] <= 0)
                        {
                            temp++;
                        }
                    }
                    if (temp < jNewMin)
                    {
                        jNewMin = temp;
                    }
                    if (temp > jNewMax)
                    {
                        jNewMax = temp;
                    }
                    double e  = m - (_x0 + temp * _dx[i + 1]);
                    double e2 = e * e;
                    double e3 = e * Math.Sqrt(3.0);
                    int    j0 = j - jMin;
                    branching.K[j0]        = temp;
                    branching.Probs[0, j0] = (1.0 + e2 / v2 - e3 / v) / 6.0;
                    branching.Probs[1, j0] = (2.0 - e2 / v2) / 3.0;
                    branching.Probs[2, j0] = (1.0 + e2 / v2 + e3 / v) / 6.0;
                }
                branching.JMin = jNewMin - 1;
                branching.JMax = jNewMax + 1;
                _branchings[i] = branching;     // Add branching
                jMin           = branching.JMin;
                jMax           = branching.JMax;
            }
        }
        ///<summary>
        ///</summary>
        ///<param name="process"></param>
        ///<param name="endTime"></param>
        ///<param name="steps"></param>
        public StandardBinomialTree(IDiffusionProcess process,
                                    double endTime, int steps) : base(steps + 1)
        {
            double dt = endTime / steps;

            _x0 = process.X0;
            _dx = Math.Sqrt(process.Variance(0.0, 0.0, dt));
        }