private static Matrix SimulateLiberalStageTwo(Matrix M, Matrix EA1, Matrix C, Matrix D, Matrix JC, double br)
        {
            Matrix JCC = JC * C;
            Matrix DC = D * C;

            int n = M.Rows;
            Matrix AM = M * EA1;
            Matrix R = new Matrix(n);
            for (int i = 0; i < R.Rows; ++i)
                for (int j = 0; j < R.Cols; ++j)
                    if (i != j && (M[i, j] > 0 || AM[i, j] > 0))
                        R[i, j] = 1;
                    else
                        R[i, j] = 0;

            Matrix EE = M * M;
            Matrix BEE = new Matrix(n);
            for (int i = 0; i < R.Rows; ++i)
                for (int j = 0; j < R.Cols; ++j)
                    if (i != j && EE[i, j] > 0)
                        BEE[i, j] = 1;
                    else
                        BEE[i, j] = 0;

            Matrix CR = R * C;
            Vector AO = new Vector(n);
            for (int i = 0; i < AO.Size; ++i)
            {
                double sum = br * (CR.GetRowSum(i) - C[i, i]);
                if (sum <= C[i, i])
                    AO[i] = 0;
                else
                    AO[i] = sum;
            }

            Matrix F = Matrix.Ones(n, n);
            F.SetDiagonalFromVector(Vector.Zero(n));

            Matrix PAN = (F - R) * C;
            Matrix PAC = BEE * C;

            Matrix EA = Matrix.Zero(n, n);

            UpdateEAMatrix(AO, DC, EA);
            UpdateEAMatrix(AO, PAC, EA);
            UpdateEAMatrix(AO, PAN, EA);
            UpdateEAMatrix(AO, JCC, EA);

            Matrix BEA = new Matrix(n);
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    BEA[i, j] = EA[i, j] < double.Epsilon ? 0 : 1;
            Matrix BEAT = BEA.GetTranspose();

            AO.Clear();
            PAC.Clear();
            EA.Clear();
            DC.Clear();

            return (BEA + BEAT) / 2;
        }
        private static Matrix SimulateLiberalStageOne(SymmetricBinaryMatrix G, Matrix C, Matrix R, Vector P, Matrix D, Matrix JC, double br)
        {
            Matrix DC = D * C;
            Matrix JCC = JC * C;

            int n = C.Rows;

            if (R == null)
            {
                R = new Matrix(n);
                for (int i = 0; i < R.Rows; ++i)
                    for (int j = 0; j < R.Cols; ++j)
                        if (G.GetValue(i, j) || P[i] == 1 || P[j] == 1)
                            R[i, j] = 1;
                        else
                            R[i, j] = 0;
            }

            Matrix CR = R * C;

            Vector AO = new Vector(n);
            for (int i = 0; i < AO.Size; ++i)
            {
                if (Algorithms.MaxValue<double>(CR.GetRowEnumerator(i)) <= 0.0)
                    AO[i] = 0;
                else
                    AO[i] = br * (CR.GetRowSum(i) - C[i, i] );
            }

            Matrix F = Matrix.Ones(n, n);
            F.SetDiagonalFromVector(Vector.Zero(n));

            Matrix PAN = (F - R) * C;

            Matrix EA = Matrix.Zero(n, n);

            UpdateEAMatrix(AO, DC, EA);
            UpdateEAMatrix(AO, PAN, EA);
            UpdateEAMatrix(AO, JCC, EA);

            Matrix BEA = new Matrix(n);
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    BEA[i, j] = EA[i, j] < double.Epsilon ? 0 : 1;
            Matrix BEAT = BEA.GetTranspose();

            return (BEA + BEAT) / 2;
        }
        // for steps 13-24 in stage one
        private static void NAPTStageOneHelper1(Matrix CAP, Matrix SRG, Matrix SRGC, Matrix PAN, Matrix UA11, Matrix CUA11, Vector AOC,
            ref Matrix DP1, ref Matrix FA1, int stage, Matrix AC)
        {
            // 13. Calculate the expected alliance matrix A11
            // Sum across rows of A11?
            Matrix A11 = new Matrix(CUA11.Rows, CUA11.Cols);
            if (stage == 1)
            {
                for (int i = 0; i < CUA11.Rows; i++)
                {
                    for (int j = 0; j < CUA11.Cols; j++)
                    {
                        if (i == j)
                            A11[i, j] = CAP[i, i];
                        else if (CUA11[i, j] == CUA11.GetMaxInRow(i))
                            A11[i, j] = CAP[j, j];
                        else
                            A11[i, j] = 0;
                    }
                }
            }
            else // stage 2 is different
            {
                for (int i = 0; i < CUA11.Rows; i++)
                {
                    for (int j = 0; j < CUA11.Cols; j++)
                    {
                        if (AC[i, j] > 0)
                            A11[i, j] = AC[i, j];
                        else if (CUA11[i, j] > 0)
                            A11[i, j] = CUA11[i, j];
                        else
                            A11[i, j] = 0;
                    }
                }
            }

            /*
            // 14. Update the AOC vector to AOC11
            Vector AOC11 = new Vector(AOC.Size);
            for (int i = 0; i < A11.Rows; i++)
            {
                if (A11.GetRowSum(i) >= AOC[i])
                    AOC11[i] = 0;
                else
                    AOC11[i] = AOC[i] - A11.GetRowSum(i);
            }
            */

            // 14. Update the AOC vector to AOC11
            //      (modified to compare to SRG CAP instead of AOC) -------- this one is correct ------
            Vector AOC11 = new Vector(AOC.Size);
            for (int i = 0; i < A11.Rows; i++)
            {
                if (A11.GetRowSum(i) >= SRGC.GetRowSum(i))
                    AOC11[i] = 0;
                else
                    AOC11[i] = SRGC.GetRowSum(i) - A11.GetRowSum(i);
            }

            // 17.  Subtract Sum(AOC12) - Sum(AOC11). If result is equal to zero, stop run and go back to step #x
            //      If the result is less than zero, repeat steps 11-16 by calculating UA13, CUA13, A13, AOC13
            //
            //      This method incorporates steps 15-16
            Matrix new_A = UpdateAOC(UA11, CUA11, AOC11, CAP, SRGC, A11, PAN, stage);

            // 18.  Generate an aliiance offer matrix AO1 which is a binarized version of A1x (where x is the number
            //      of the last A matrix

            //new_A.Binarize();

            // Recently updated as of 3:59AM 7/17/2012 (subject to change)

            Matrix AO1 = new Matrix(new_A.Rows, new_A.Cols);
            for (int i = 0; i < AO1.Rows; i++)
            {
                for (int j = 0; j < AO1.Cols; j++)
                {
                    if (i == j)
                        AO1[i, j] = 0;
                    else if (new_A[i, j] > 0)
                        AO1[i, j] = 1;
                    else
                        AO1[i, j] = 0;
                }
            }

            // 19. Transpose AO1
            Matrix AO1_T = AO1.GetTranspose();

            // 20. Generate a Defence Pacts matrix DP1 = AO1 * AO1'
            DP1 = new Matrix(AO1.Rows, AO1_T.Cols);
            for (int i = 0; i < AO1.Rows; i++)
                for (int j = 0; j < AO1_T.Cols; j++)
                    DP1[i, j] = AO1[i, j] * AO1_T[i, j];

            // 21. Generate an Allies of Enemies AE1 matrix AE1 = SRG x DP1
            Matrix AE1 = SRG * DP1;

            // 22. Generate a Prevention matrix PV1
            /*
            Matrix PV1 = new Matrix(AE1.Rows, AE1.Cols);
            for (int i = 0; i < AE1.Rows; i++)
            {
                for (int j = 0; j < AE1.Cols; j++)
                {
                    if (DP1[i, j] == 0 && AE1[i, j] == 0)
                        PV1[i, j] = 0;
                    else if (DP1[i, j] == 1 && AE1[i, j] == 0)
                        PV1[i, j] = 1;
                    else if (DP1[i, j] == 0 && AE1[i, j] > 0)
                        PV1[i, j] = 2;
                }
            }
            */

            // New implementation which uses excel formula instead of pdf
            Matrix PV1 = new Matrix(AE1.Rows, AE1.Cols);
            for (int i = 0; i < AE1.Rows; i++)
            {
                for (int j = 0; j < AE1.Cols; j++)
                {
                    if (i == j)
                        PV1[i, j] = 0;
                    else if (stage == 1)
                    {
                        if (AE1[i, j] == 1)
                            PV1[i, j] = 1;
                        else if (AE1[i, j] > 0 && SRG[i, j] == 0)
                            PV1[i, j] = 2;
                        else
                            PV1[i, j] = 0;
                    }
                    else
                    {
                        if (DP1[i, j] == 1)
                            PV1[i, j] = 1;
                        else if (AE1[i, j] > 0 && SRG[i, j] == 0)
                            PV1[i, j] = 2;
                        else
                            PV1[i, j] = 0;
                    }
                }
            }

            // 23. Transpose PV1
            Matrix PV1_T = PV1.GetTranspose();

            // 24. Generate a final alliance matrix at T1 (FA1)
            FA1 = new Matrix(PV1.Rows, PV1.Cols);
            for (int i = 0; i < PV1.Rows; i++)
            {
                for (int j = 0; j < PV1.Cols; j++)
                {
                    // PDF implementation
                    /*
                    if (PV1[i, j] == 0 && PV1_T[i, j] == 0)
                        FA1[i, j] = 0;
                    else
                        FA1[i, j] = (PV1[i, j] > PV1_T[i, j]) ? PV1[i, j] : PV1_T[i, j]; // max value of the two
                    */

                    // Excel Implementation
                    if (PV1[i, j] > 0 && PV1_T[i, j] > 0)
                        FA1[i, j] = (PV1[i, j] > PV1_T[i, j]) ? PV1[i, j] : PV1_T[i, j]; // max value of the two
                    else
                        FA1[i, j] = 0;

                }
            }
        }
        /// <summary>
        /// Simulates stage two of the realist network formation simulation.
        /// </summary>
        /// <param name="C">Capability matrix for stage two</param>
        /// <param name="R">Policy relevance matrix (SRG)</param>
        /// <param name="EAF">EAF matrix from stage one</param>
        /// <param name="M">MID matrix</param>
        /// <returns>Expected alliance matrix</returns>
        /// <returns>EA matrix for stage two</returns>
        private static Matrix UpdateSimplifiedRealistStageTwo(Matrix C, Matrix R, Matrix M, Matrix BEA, string outputFile, double br)
        {
            int n = C.Rows;

            Matrix AE = M * BEA;

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                {
                    if (R[i, j] == 1 || AE[i, j] > 0 ) R[i, j] = 1;
                    else R[i, j] = 0;
                }

            R.ZeroDiagonal();
            Matrix SRC = R * C;

            Vector SRGC = new Vector(n);
            for (int i = 0; i < n; ++i)
                SRGC[i] = SRC.GetRowSum(i) * br;

            Matrix EAC = BEA * C;

            Vector AOC = new Vector(n);
            for (int i = 0; i < n; ++i)
            {
                if (EAC.GetRowSum(i) + C[i, i] >= SRGC[i]) AOC[i] = 0;
                else AOC[i] = 1 - ((EAC.GetRowSum(i) + C[i, i]) / SRGC[i]);
            }

            Matrix F = Matrix.Ones(n, n);
            F.ZeroDiagonal();
            Matrix PAN = F - R;
            Matrix PAC = PAN * C;

            Matrix EE = M * M;
            EE.ZeroDiagonal();
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    if (EE[i, j] != 0) EE[i, j] = 1;

            Matrix EEC = EE * C;

            Vector EEM = new Vector(n);

            for (int i = 0; i < n; ++i)
                EEM[i] = Algorithms.MaxValue<double>(EEC.GetRowEnumerator(i));

            Matrix EA = new Matrix(n, n);

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    if (EAC[i, j] > 0 || AOC[i] <= 0)
                        EA[i, j] = EAC[i, j];
                    else if (PAN[i, j] > 0 && EEC[i, j] == EEM[i])
                        EA[i, j] = EEC[i, j];
                    else
                        EA[i, j] = 0;

            //Copied from Stage 1

            Vector SEA = new Vector(n);

            Matrix previousEA = new Matrix(n);

            Matrix TempEEC = new Matrix(n);

            EEC.CloneTo(TempEEC);

            do
            {

                EA.CloneTo(previousEA);

                for (int i = 0; i < n; ++i)
                    SEA[i] = EA.GetRowSum(i) + C[i, i];

                for (int i = 0; i < n; ++i)
                {
                    if (SRGC[i] <= SEA[i]) AOC[i] = 0;
                    else AOC[i] = 1 - SEA[i] / SRGC[i];
                }

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                        if (EEC[i, j] == EEM[i]) EEC[i, j] = 0;

                for (int i = 0; i < n; ++i)
                    EEM[i] = Algorithms.MaxValue<double>(EEC.GetRowEnumerator(i));

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                    {
                        if (AOC[i] == 0 || EA[i, j] != 0) ;
                        else if (PAN[i, j] > 0 && EEC[i, j] == EEM[i])
                            EA[i, j] = EEC[i, j];
                        else EA[i, j] = 0;
                    }

                //for (int i = 0; i < n; ++i)
                //    for (int j = 0; j < n; ++j)
                //    {
                //        if (AOC[i] == 0 || EA[i, j] > 0) ;
                //        else if (EEC[i, j] == EEM[i]) EA[i, j] = EEC[i, j];
                //        else EA[i, j] = 0;
                //    }
            } while ((!previousEA.IsSameAs(EA)) && !EEC.IsAllZero && !AOC.IsZeroVector);

            if (!AOC.IsZeroVector)
            {

                //for (int i = 0; i < n; ++i)
                //    for (int j = 0; j < n; ++j)
                //        if (PAC[i, j] > 0 && TempEEC[i, j] != 0) PAC[i, j] = 0;

                //PAC.CopyLabelsFrom(C);
                //MatrixWriter.WriteMatrixToMatrixFile(PAC, outputFile);
                Vector PAM = new Vector(n);

                for (int i = 0; i < n; ++i)
                    PAM[i] = Algorithms.MaxValue<double>(PAC.GetRowEnumerator(i));

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                        if (AOC[i] != 0 && PAC[i, j] == PAM[i] && EA[i, j] == 0)
                            EA[i, j] = PAC[i, j];

                do
                {

                    EA.CloneTo(previousEA);

                    for (int i = 0; i < n; ++i)
                        SEA[i] = EA.GetRowSum(i) + C[i, i];

                    for (int i = 0; i < n; ++i)
                    {
                        if (SRGC[i] <= SEA[i]) AOC[i] = 0;
                        else AOC[i] = 1 - SEA[i] / SRGC[i];
                    }

                    //Matrix output = new Matrix(n, n + 4);
                    //for (int i = 0; i < n; i++)
                    //    for (int j = 0; j < n; j++)
                    //        output[i, j] = EA[i, j];

                    //for (int i = 0; i < n; ++i)
                    //    output[i, n] = SEA[i];
                    //for (int i = 0; i < n; ++i)
                    //    output[i, n + 1] = SRGC[i];
                    //for (int i = 0; i < n; ++i)
                    //    output[i, n + 2] = AOC[i];
                    //for (int i = 0; i < n; ++i)
                    //    output[i, n + 3] = 1111;

                    //output.CopyLabelsFrom(C);
                    //MatrixWriter.WriteMatrixToMatrixFile(output, outputFile);

                    for (int i = 0; i < n; ++i)
                        for (int j = 0; j < n; ++j)
                            if (PAC[i, j] == PAM[i]) PAC[i, j] = 0;

                    //PAC.CopyLabelsFrom(C);
                    //MatrixWriter.WriteMatrixToMatrixFile(PAC, outputFile);
                    for (int i = 0; i < n; ++i)
                        PAM[i] = Algorithms.MaxValue<double>(PAC.GetRowEnumerator(i));

                    for (int i = 0; i < n; ++i)
                        for (int j = 0; j < n; ++j)
                            if (AOC[i] != 0 && PAC[i, j] == PAM[i] && EA[i, j] == 0)
                                EA[i, j] = PAC[i, j];

                } while ((!previousEA.IsSameAs(EA)) && !PAC.IsAllZero && !AOC.IsZeroVector);

            }//if AOC is not all zero

            Matrix EAT = EA.GetTranspose();

            Matrix EAF = new Matrix(n);

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    EAF[i, j] = EA[i, j] * EAT[i, j];

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                {
                    if (EAF[i, j] != 0) BEA[i, j] = 1;
                    else BEA[i, j] = 0;
                }

            return BEA;
        }
        /// <summary>
        /// Simulates stage one of the SIMPLIFIED realist network formation simulation.
        /// </summary>
        /// <param name="C">Capability matrix</param>
        /// <param name="R">Policy relevance matrix (SRG)</param>
        /// <param name="M">MID matrix</param>
        /// <returns>Expected alliance matrix</returns>
        private static Matrix SimulateSimplifiedRealistStageOne(Matrix C, Matrix R, Matrix M, string outputFile, double br)
        {
            int n = C.Rows;
            Matrix SRC = R * C;
            Vector SRGC = new Vector(n);
            for (int i = 0; i < n; ++i)
                SRGC[i] = SRC.GetRowSum(i) * br;
            Vector AOC = new Vector(n);
            for (int i = 0; i < n; ++i)
            {
                if (SRGC[i] <= C[i, i]) AOC[i] = 0;
                else AOC[i] = 1 - C[i, i] / SRGC[i];
            }

            Matrix F = Matrix.Ones(n, n);
            F.ZeroDiagonal();
            Matrix PAN = F - R;
            Matrix PAC = PAN * C;

            Matrix EE = M * M;
            EE.ZeroDiagonal();
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    if (EE[i, j] != 0) EE[i, j] = 1;

            Matrix EEC = EE * C;
            Vector EEM = new Vector(n);

            for (int i = 0; i < n; ++i)
                EEM[i] = Algorithms.MaxValue<double>(EEC.GetRowEnumerator(i));

            Matrix EA = new Matrix(n, n);

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    if (EEC[i, j] == EEM[i] && PAN[i, j] == 1 && AOC[i] != 0)
                        EA[i, j] = EEC[i, j];
                    else
                        EA[i, j] = 0;

            Vector SEA = new Vector(n);

            Matrix previousEA = new Matrix(n);

            do
            {

                EA.CloneTo(previousEA);

                for (int i = 0; i < n; ++i)
                    SEA[i] = EA.GetRowSum(i) + C[i, i];

                for (int i = 0; i < n; ++i)
                {
                    if (SRGC[i] <= SEA[i]) AOC[i] = 0;
                    else AOC[i] = 1 - SEA[i] / SRGC[i];
                }

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                        if (EEC[i, j] == EEM[i]) EEC[i, j] = 0;

                for (int i = 0; i < n; ++i)
                    EEM[i] = Algorithms.MaxValue<double>(EEC.GetRowEnumerator(i));

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                    {
                        //if (AOC[i] != 0 && EEC[i, j] == EEM[i] && EA[i, j] == 0)
                        //    EA[i, j] = EEC[i, j];

                        if (AOC[i] == 0 || EA[i, j] != 0);
                        else if (PAN[i, j] > 0 && EEC[i, j] == EEM[i])
                            EA[i, j] = EEC[i, j];
                        else EA[i, j] = 0;
                    }

            } while ((!previousEA.IsSameAs(EA)) && !EEC.IsAllZero && !AOC.IsZeroVector);

            if (!AOC.IsZeroVector)
            {

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                        if (PAC[i, j] > 0 && EEC[i, j] != 0) PAC[i, j] = 0;

                Vector PAM = new Vector(n);

                for (int i = 0; i < n; ++i)
                    PAM[i] = Algorithms.MaxValue<double>(PAC.GetRowEnumerator(i));

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                        if (AOC[i] != 0 && PAC[i, j] == PAM[i] && EA[i, j] == 0)
                            EA[i, j] = PAC[i, j];

                EA.CopyLabelsFrom(C);
                do
                {

                    EA.CloneTo(previousEA);

                    for (int i = 0; i < n; ++i)
                        SEA[i] = EA.GetRowSum(i) + C[i, i];

                    for (int i = 0; i < n; ++i)
                    {
                        if (SRGC[i] <= SEA[i]) AOC[i] = 0;
                        else AOC[i] = 1 - SEA[i] / SRGC[i];
                    }

                    for (int i = 0; i < n; ++i)
                        for (int j = 0; j < n; ++j)
                            if (PAC[i, j] == PAM[i]) PAC[i, j] = 0;

                    for (int i = 0; i < n; ++i)
                        PAM[i] = Algorithms.MaxValue<double>(PAC.GetRowEnumerator(i));

                    for (int i = 0; i < n; ++i)
                        for (int j = 0; j < n; ++j)
                            if (AOC[i] != 0 && PAC[i, j] == PAM[i] && EA[i, j] == 0)
                                EA[i, j] = PAC[i, j];

                    EA.CopyLabelsFrom(C);
                } while ((!previousEA.IsSameAs(EA)) && !PAC.IsAllZero && !AOC.IsZeroVector);

            }//if AOC is not all zero

            Matrix EAT = EA.GetTranspose();

            Matrix EAF = new Matrix(n);

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    EAF[i, j] = EA[i, j] * EAT[i, j];

            Matrix BEA = new Matrix(n);
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                {
                    if (EAF[i, j] != 0) BEA[i, j] = 1;
                    else BEA[i, j] = 0;
                }

            return BEA;
        }
示例#6
0
            // Solve least square problem by QR-decomposition:
            //  minimize ||M*x - b||.  Returns x.
            //
            // The method works only for well-determined (#rows = #columns) and over-determined (#rows > #columns) systems.
            //
            public Vector SolveLeastSquareQR( Vector b )
            {
                int		l = Rows > Columns ? Columns : Rows;

                //////////////////////////////////////////////////////////////////////////
                // QR-decompose this = q*r
                Matrix		Q = new Matrix( Rows, Columns );
                Matrix		R = new Matrix( Columns, Columns );

                // Make vectors x out of columns. Vectors g will populate q-matrix.
                Vector[]	x = new Vector[Columns];
                Vector[]	g = new Vector[Columns];

                for ( int k=0; k < Columns; k++ )
                {
                    x[k] = new Vector( Rows );
                    g[k] = new Vector( Rows );
                    for( int i=0; i < Rows; i++ )
                        x[k].m[i] = m[i,k];
                }

                // The main loop
                for ( int k=0; k < Columns; k++ )
                {
                    // Calculate r(k,k): norm of x[k]
                    R.m[k,k] = Math.Sqrt( x[k].Dot( x[k] ) );
                    if ( R.m[k,k] == 0.0 )
                    {
                        for ( int i=0; i < Rows; i++ )
                            g[k].m[i] = 0.0;
                    }
                    else
                    {	// set g-s
                        for ( int i=0; i < Rows; i++ )
                        {
                            double	temp = 1.0 / R.m[k,k];
                            g[k].m[i] = x[k].m[i] * temp;
                        }
                    }

                    // Calculate non-diagonal elements of r-matrix
                    for ( int j=k+1; j < Columns; j++ )
                    {
                        R.m[j,k] = 0.0;
                        for ( int i=0; i < Rows; i++ )
                            R.m[k,j] += x[j].m[i] * g[k].m[i];
                    }

                    // Reset x-s
                    for ( int j=k+1; j < Columns; j++ )
                        for ( int i=0; i < Rows; i++ )
                            x[j].m[i] -= R.m[k,j] * g[k].m[i];
                }

                // Make q out of g-s
                for( int i=0; i < Rows; i++ )
                    for( int k=0; k < Columns; k++ )
                        Q.m[i,k] = g[k].m[i];

                //////////////////////////////////////////////////////////////////////////
                // Solve R*x = Q.setToAdjoint()*b
                Q = Q.GetTranspose();
                Vector	y = Q * b;
                Vector	Result = R.SolveBackwardSubstitution( y );
                return Result;
            }