Example #1
0
        public Matrix SolveFor(Matrix rightMatrix)
        {
            Debug.Assert(rightMatrix.RowCount == _columnCount);
            Debug.Assert(_columnCount == _rowCount);
            Matrix resultMatrix = new Matrix(_columnCount, rightMatrix.ColumnCount);
            LUDecompositionResults resDecomp = LUDecompose();

            int[]  nP = resDecomp.PivotArray; Matrix lMatrix = resDecomp.L;
            Matrix uMatrix = resDecomp.U;

            for (int k = 0; k < rightMatrix.ColumnCount; k++)
            {
                //Solve for the corresponding d Matrix from Ld=Pb
                double sum     = 0.0;
                Matrix dMatrix = new Matrix(_rowCount, 1);
                dMatrix[0, 0] = rightMatrix[nP[0], k] / lMatrix[0, 0];
                for (int i = 1; i < _rowCount; i++)
                {
                    sum = 0.0; for (int j = 0; j < i; j++)
                    {
                        sum += lMatrix[i, j] * dMatrix[j, 0];
                    }
                    dMatrix[i, 0] = (rightMatrix[nP[i], k] - sum) / lMatrix[i, i];
                }//Solve for x using Ux = d
                resultMatrix[_rowCount - 1, k] = dMatrix[_rowCount - 1, 0];
                for (int i = _rowCount - 2; i >= 0; i--)
                {
                    sum = 0.0;
                    for (int j = i + 1; j < _rowCount; j++)
                    {
                        sum += uMatrix[i, j] * resultMatrix[j, k];
                    }
                    resultMatrix[i, k] = dMatrix[i, 0] - sum;
                }
            }
            return(resultMatrix);
        }
Example #2
0
        private LUDecompositionResults LUDecompose()
        {
            Debug.Assert(_columnCount == _rowCount);
            // Using Crout Decomp with P//// Ax = b //By definition of problem variables.//// LU = PA //By definition of L, U, and P.//// LUx = Pb //By substition for PA.//// Ux = d //By definition of d//// Ld = Pb //By subsitition for d.////For 4x4 with P = I// [l11 0 0 0 ] [1 u12 u13 u14] [a11 a12 a13 a14]// [l21 l22 0 0 ] [0 1 u23 u24] = [a21 a22 a23 a24]// [l31 l32 l33 0 ] [0 0 1 u34] [a31 a32 a33 a34]// [l41 l42 l43 l44] [0 0 0 1 ] [a41 a42 a43 a44]
            LUDecompositionResults result = new LUDecompositionResults();

            try
            {
                int[]  pivotArray     = new int[_rowCount];//Pivot matrix.
                Matrix uMatrix        = new Matrix(_rowCount, _columnCount);
                Matrix lMatrix        = new Matrix(_rowCount, _columnCount);
                Matrix workingUMatrix = Clone();
                Matrix workingLMatrix = new Matrix(_rowCount, _columnCount);
                for (int i = 0; i < _rowCount; i++)
                {
                    pivotArray[i] = i;
                }                     //Iterate down the number of rows in the U matrix.
                for (int i = 0; i < _rowCount; i++)
                {
                    //Do pivots first.
                    //I want to make the matrix diagnolaly dominate.
                    //Initialize the variables used to determine the pivot row.
                    double maxRowRatio = double.NegativeInfinity;
                    int    maxRow      = -1;
                    int    maxPosition = -1;
                    //Check all of the rows below and including the current row
                    //to determine which row should be pivoted to the working row position.
                    //The pivot row will be set to the row with the maximum ratio
                    //of the absolute value of the first column element divided by the
                    //sum of the absolute values of the elements in that row.
                    for (int j = i; j < _rowCount; j++)
                    {
                        //Store the sum of the absolute values of the row elements in
                        //dRowSum. Clear it out now because I am checking a new row.
                        double rowSum = 0.0;
                        //Go across the columns, add the absolute values of the elements in
                        //that column to dRowSum.
                        for (int k = i; k < _columnCount; k++)
                        {
                            rowSum += Math.Abs(workingUMatrix[pivotArray[j], k]);
                        }
                        //Check to see if the absolute value of the ratio of the lead
                        //element over the sum of the absolute values of the elements is larger
                        //that the ratio for preceding rows. If it is, then the current row
                        //becomes the new pivot candidate.
                        if (rowSum == 0.0)
                        {
                            throw new SingularMatrixException();
                        }

                        double dCurrentRatio = Math.Abs(workingUMatrix[pivotArray[j], i]) / rowSum;

                        lock (this)
                        {
                            if (dCurrentRatio > maxRowRatio)
                            {
                                maxRowRatio = Math.Abs(workingUMatrix[pivotArray[j], i] / rowSum);
                                maxRow      = pivotArray[j]; maxPosition = j;
                            }
                        }
                    }
                    //If the pivot candidate isn't the current row, update the
                    //pivot array to swap the current row with the pivot row.
                    if (maxRow != pivotArray[i])
                    {
                        int hold = pivotArray[i];
                        pivotArray[i] = maxRow; pivotArray[maxPosition] = hold;
                    }
                    //Store the value of the left most element in the working U
                    //matrix in dRowFirstElementValue.
                    double rowFirstElementValue = workingUMatrix[pivotArray[i], i];
                    //Update the columns of the working row. j is the column index.
                    for (int j = 0; j < _columnCount; j++)
                    {
                        if (j < i)
                        {
                            //If j<1, then the U matrix element value is 0.
                            workingUMatrix[pivotArray[i], j] = 0.0;
                        }
                        else if (j == i)
                        {
                            //If i == j, the L matrix value is the value of the
                            //element in the working U matrix.
                            workingLMatrix[pivotArray[i], j] = rowFirstElementValue;
                            //The value of the U matrix for i == j is 1
                            workingUMatrix[pivotArray[i], j] = 1.0;
                        }
                        else
                        // j>i
                        {
                            //Divide each element in the current row of the U matrix by the
                            //value of the first element in the row
                            workingUMatrix[pivotArray[i], j] /= rowFirstElementValue;
                            //The element value of the L matrix for j>i is 0
                            workingLMatrix[pivotArray[i], j] = 0.0;
                        }
                    }
                    //For the working U matrix, subtract the ratioed active row from the rows below it.
                    //Update the columns of the rows below the working row. k is the row index.
                    for (int k = i + 1; k < _rowCount; k++)
                    {
                        //Store the value of the first element in the working row
                        //of the U matrix.
                        rowFirstElementValue = workingUMatrix[pivotArray[k], i];
                        //Go accross the columns of row k.
                        for (int j = 0; j < _columnCount; j++)
                        {
                            if (j < i)
                            {
                                //If j<1, then the U matrix element value is 0.
                                workingUMatrix[pivotArray[k], j] = 0.0;
                            }
                            else if (j == i)
                            {
                                //If i == j, the L matrix value is the value of the
                                //element in the working U matrix.
                                workingLMatrix[pivotArray[k], j] = rowFirstElementValue;
                                //The element value of the L matrix for j>i is 0
                                workingUMatrix[pivotArray[k], j] = 0.0;
                            }
                            else
                            //j>i
                            {
                                workingUMatrix[pivotArray[k], j] = workingUMatrix[pivotArray[k], j] - rowFirstElementValue * workingUMatrix[pivotArray[i], j];
                            }
                        }
                    }
                }
                for (int i = 0; i < _rowCount; i++)
                {
                    for (int j = 0; j < _rowCount; j++)
                    {
                        uMatrix[i, j] = workingUMatrix[pivotArray[i], j]; lMatrix[i, j] = workingLMatrix[pivotArray[i], j];
                    }
                }
                result.U          = uMatrix;
                result.L          = lMatrix;
                result.PivotArray = pivotArray;
            }
            catch (AggregateException ex2)
            {
                if (ex2.InnerExceptions.Count > 0)
                {
                    throw ex2.InnerExceptions[0];
                }
                else
                {
                    throw ex2;
                }
            }
            catch (Exception ex3)
            {
                throw ex3;
            }
            return(result);
        }