コード例 #1
0
ファイル: Matrix.cs プロジェクト: kollare/Arconic
        public Matrix SolveFor(Matrix mRight)
        {
            Debug.Assert(mRight.NumRows == m_nNumColumns);
            Debug.Assert(m_nNumColumns == m_nNumRows);

            Matrix mRet = new Matrix(m_nNumColumns, mRight.NumColumns);
            LUDecompositionResults resDecomp = LUDecompose();

            int[]  nP = resDecomp.PivotArray;
            Matrix mL = resDecomp.L;
            Matrix mU = resDecomp.U;

            double dSum = 0.0;

            for (int k = 0; k < mRight.NumColumns; k++)
            {
                Matrix D = new Matrix(m_nNumRows, 1);
                D[0, 0] = mRight[nP[0], k] / mL[0, 0];
                for (int i = 1; i < m_nNumRows; i++)
                {
                    dSum = 0.0;

                    for (int j = 0; j < i; j++)
                    {
                        dSum += mL[i, j] * D[j, 0];
                    }

                    D[i, 0] = (mRight[nP[i], k] - dSum) / mL[i, i];
                }

                mRet[m_nNumRows - 1, k] = D[m_nNumRows - 1, 0];
                for (int i = m_nNumRows - 2; i >= 0; i--)
                {
                    dSum = 0.0;
                    for (int j = i + 1; j < m_nNumRows; j++)
                    {
                        dSum += mU[i, j] * mRet[j, k];
                    }

                    mRet[i, k] = D[i, 0] - dSum;
                }
            }

            return(mRet);
        }
コード例 #2
0
ファイル: Matrix.cs プロジェクト: kollare/Arconic
        private LUDecompositionResults LUDecompose()
        {
            Debug.Assert(m_nNumColumns == m_nNumRows);

            LUDecompositionResults resRet = new LUDecompositionResults();

            int[]  nP        = new int[m_nNumRows];     //Pivot matrix.
            Matrix mU        = new Matrix(m_nNumRows, m_nNumColumns);
            Matrix mL        = new Matrix(m_nNumRows, m_nNumColumns);
            Matrix mUWorking = Clone();
            Matrix mLWorking = new Matrix(m_nNumRows, m_nNumColumns);

            for (int i = 0; i < m_nNumRows; i++)
            {
                nP[i] = i;
            }

            for (int i = 0; i < m_nNumRows; i++)
            {
                double dMaxRowRatio = double.NegativeInfinity;
                int    nMaxRow      = -1;
                int    nMaxPosition = -1;

                for (int j = i; j < m_nNumRows; j++)
                {
                    double dRowSum = 0.0;

                    for (int k = i; k < m_nNumColumns; k++)
                    {
                        dRowSum += Math.Abs(mUWorking[nP[j], k]);
                    }

                    if (Math.Abs(mUWorking[nP[j], i] / dRowSum) > dMaxRowRatio)
                    {
                        dMaxRowRatio = Math.Abs(mUWorking[nP[j], i] / dRowSum);
                        nMaxRow      = nP[j];
                        nMaxPosition = j;
                    }
                }

                if (nMaxRow != nP[i])
                {
                    int nHold = nP[i];
                    nP[i]            = nMaxRow;
                    nP[nMaxPosition] = nHold;
                }

                double dRowFirstElementValue = mUWorking[nP[i], i];

                for (int j = 0; j < m_nNumRows; j++)
                {
                    if (j < i)
                    {
                        mUWorking[nP[i], j] = 0.0;
                    }
                    else if (j == i)
                    {
                        mLWorking[nP[i], j] = dRowFirstElementValue;
                        mUWorking[nP[i], j] = 1.0;
                    }
                    else
                    {
                        mUWorking[nP[i], j] /= dRowFirstElementValue;
                        mLWorking[nP[i], j]  = 0.0;
                    }
                }


                for (int k = i + 1; k < m_nNumRows; k++)
                {
                    dRowFirstElementValue = mUWorking[nP[k], i];

                    for (int j = 0; j < m_nNumRows; j++)
                    {
                        if (j < i)
                        {
                            mUWorking[nP[k], j] = 0.0;
                        }
                        else if (j == i)
                        {
                            mLWorking[nP[k], j] = dRowFirstElementValue;
                            mUWorking[nP[k], j] = 0.0;
                        }
                        else
                        {
                            mUWorking[nP[k], j] = mUWorking[nP[k], j] - dRowFirstElementValue * mUWorking[nP[i], j];
                        }
                    }
                }
            }

            for (int i = 0; i < m_nNumRows; i++)
            {
                for (int j = 0; j < m_nNumRows; j++)
                {
                    mU[i, j] = mUWorking[nP[i], j];
                    mL[i, j] = mLWorking[nP[i], j];
                }
            }

            resRet.U = mU;
            resRet.L = mL;

            resRet.PivotArray = nP;

            return(resRet);
        }