예제 #1
0
        /// <summary>
        /// Computes four correlated deviates for Monte Carlo simulation.
        /// </summary>
        /// <param name="R">Correlation matrix (which is always symmetric).</param>
        /// <param name="dt">Time step.</param>
        /// <param name="z">Array to store correlated deviates.</param>
        /// <returns></returns>
        public double[] GenerateCorrelatedDeviates(SymmetricMatrix R, double dt, double[] z)
        {
            double sum =  0.0;
            // standard normal deviate
            double deviate = 0.0;
            // number of rows in correlation matrix.
            int m = R.GetNumberOfRows();
            // list of correlated deviates
            //List<double> dz;
            // list of eigenvalues
            List<double> eigenValues = new List<double>();
            // array of eigenvectors
            List<double>[] eigenVectors = new List<double>[4];
            // stores eigenvalues of correlation matrix R
            double[] lambda = new double[] { 0.0, 0.0, 0.0, 0.0 };
            // stores correlated deviates
            double[] dw = new double[] { 0.0, 0.0, 0.0, 0.0 };

            DiagonalMatrix D = R.GetEigenValues();
            Matrix V = GenerateEigenVectors(R);

            // store eigen values
            for (int i = 0; i < m; i++)
            {
                eigenValues.Add(D.GetElement(i, i));
                lambda[i] = D.GetElement(i, i);
            }

            // stores rows of eigenvectors so that we can compute
            // dz[i] = v[i][1]*sqrt(eigenvalue[1])*dw1 + v[i][2]*sqrt(eigenvalue[2])*dw2 + ...
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < m; j++)
                {
                    eigenVectors[i].Add(V.GetElement(i, j));
                }
            }

            Random randomNumberGenerator = new Random();
            long seed = randomNumberGenerator.Next() % 100;

            // generate uncorrelated deviates
            for (int i = 0; i < m; i++)
            {
                deviate = NormalDeviate(ref seed);
                dw[i] = deviate * Math.Sqrt(dt);
            }

            // generate correlated deviates
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < m; j++)
                {
                    sum += eigenVectors[i][j] * Math.Sqrt(eigenValues[j]) * dw[j];
                }
                z[i] = sum;
            }
            return z;
        }
예제 #2
0
 private Matrix GenerateEigenVectors(SymmetricMatrix symmetricMatrix)
 {
     // OkashTODO: why do we need the diagonal matrix here??
     DiagonalMatrix D = new DiagonalMatrix(symmetricMatrix.GetNumberOfRows());
     Matrix eigenVectors = symmetricMatrix.GetEigenValues(D);
     return eigenVectors;
 }