예제 #1
0
        public static MMatrix EchelonForm(MMatrix matrix)
        {
            try
            {
                MMatrix EchelonMatrix = new MMatrix(matrix);
                for (int i = 0; i < matrix.row; ++i)
                {
                    /*Overcome round-off error to approximate values
                    for (int j = 0; j < EchelonMatrix.row; ++j)
                        for (int k = 0 ; k < EchelonMatrix.col; ++k)
                            if (Math.Abs(EchelonMatrix[j, k]) <= ZERO)
                                EchelonMatrix[j, k] = 0;
                    */
                    if (i < EchelonMatrix.col)
                    {
                        if (EchelonMatrix[i, i] == 0)	// if diagonal entry is zero,
                            for (int j = i + 1; j < EchelonMatrix.row; ++j)
                                if (EchelonMatrix[j, i] != 0)	 //check if some below entry is non-zero
                                    EchelonMatrix.InterchangeRow(i, j);	// then interchange the two rows
                        if (EchelonMatrix[i, i] == 0)	// if not found any non-zero diagonal entry
                            continue;	// increment i;

                        if (EchelonMatrix[i, i] != 1)	// if diagonal entry is not 1 ,
                            for (int j = i + 1; j < EchelonMatrix.row; ++j)
                                if (EchelonMatrix[j, i] == 1)	 //check if some below entry is 1
                                    EchelonMatrix.InterchangeRow(i, j);	// then interchange the two rows

                        EchelonMatrix.MultiplyRow(i, 1 / (EchelonMatrix[i, i]));

                        for (int j = i + 1; j < EchelonMatrix.row; ++j)
                            EchelonMatrix.AddRow(j, i, -EchelonMatrix[j, i]);
                    }
                }
                return EchelonMatrix;
            }
            catch (Exception)
            {
                throw new MMatrixException("MMatrix can not be reduced to Echelon form");
            }
        }
예제 #2
0
        public static MMatrix ReducedEchelonForm(MMatrix matrix)
        {
            try
            {
                MMatrix ReducedEchelonMatrix = new MMatrix(matrix);
                for (int i = 0; i < matrix.row; ++i)
                {
                    if (i < ReducedEchelonMatrix.col)
                    {
                        if (ReducedEchelonMatrix[i, i] == 0)	// if diagonal entry is zero,
                            for (int j = i + 1; j < ReducedEchelonMatrix.row; ++j)
                                if (ReducedEchelonMatrix[j, i] != 0)	 //check if some below entry is non-zero
                                    ReducedEchelonMatrix.InterchangeRow(i, j);	// then interchange the two rows
                        if (ReducedEchelonMatrix[i, i] == 0)	// if not found any non-zero diagonal entry
                            continue;	// increment i;
                        if (ReducedEchelonMatrix[i, i] != 1)	// if diagonal entry is not 1 ,
                            for (int j = i + 1; j < ReducedEchelonMatrix.row; ++j)
                                if (ReducedEchelonMatrix[j, i] == 1)	 //check if some below entry is 1
                                    ReducedEchelonMatrix.InterchangeRow(i, j);	// then interchange the two rows
                        ReducedEchelonMatrix.MultiplyRow(i, 1 / (ReducedEchelonMatrix[i, i]));

                        for (int j = i + 1; j < ReducedEchelonMatrix.row; ++j)
                            ReducedEchelonMatrix.AddRow(j, i, -ReducedEchelonMatrix[j, i]);
                        for (int j = i - 1; j >= 0; j--)
                            ReducedEchelonMatrix.AddRow(j, i, -ReducedEchelonMatrix[j, i]);
                    }
                }
                return ReducedEchelonMatrix;
            }
            catch (Exception)
            {
                throw new MMatrixException("MMatrix can not be reduced to Echelon form");
            }
        }
        //Solve A*x = b
        //After solving the system, Argument Matrix will contain the reduced system
        public static Vector SolveSystemOfEquations(MMatrix CoefficientMatrix, Vector b,ref MMatrix ArgumentMatrix, ref bool InfiniteSolution)
        {
            if (CoefficientMatrix.row != b.Elements.Length)
                throw new MMatrixException("The coefficient matrix A and vector b are different size.");

            Vector x = new Vector(CoefficientMatrix.col);
            Vector xSetFlag = new Vector(CoefficientMatrix.col);
            double sum;
            InfiniteSolution = false;

            ArgumentMatrix = CalculateArgumentMatrix(CoefficientMatrix,b);

            try
            {
                //Gaussian elimination
                for (int i = 0; i < CoefficientMatrix.row; ++i)
                {
                    if (i < ArgumentMatrix.col - 1)
                    {
                        if (ArgumentMatrix[i, i] == 0)	// if diagonal entry is zero,
                            for (int j = i + 1; j < ArgumentMatrix.row; ++j)
                                if (ArgumentMatrix[j, i] != 0)	 //check if some below entry is non-zero
                                    ArgumentMatrix.InterchangeRow(i, j);	// then interchange the two rows
                        if (ArgumentMatrix[i, i] == 0)	// if not found any non-zero diagonal entry
                            continue;	// increment i;

                        if (ArgumentMatrix[i, i] != 1)	// if diagonal entry is not 1 ,
                            for (int j = i + 1; j < ArgumentMatrix.row; ++j)
                                if (ArgumentMatrix[j, i] == 1)	 //check if some below entry is 1
                                    ArgumentMatrix.InterchangeRow(i, j);	// then interchange the two rows

                        ArgumentMatrix.MultiplyRow(i, 1 / (ArgumentMatrix[i, i]));

                        for (int j = i + 1; j < ArgumentMatrix.row; ++j)
                            ArgumentMatrix.AddRow(j, i, -ArgumentMatrix[j, i]);
                    }
                }

                //Finding solution based on the reduced system == Argument matrix

                //More equations than unknown varriables x[i]
                if (CoefficientMatrix.row > CoefficientMatrix.col)
                    for (int i = CoefficientMatrix.col; i < CoefficientMatrix.row; ++i)
                    {
                        if (ArgumentMatrix[i, CoefficientMatrix.col - 1] == 0)
                            if (ArgumentMatrix[i, ArgumentMatrix.col - 1] != 0)  //b[i] == 0
                                return null;
                    }

                for (int i = Math.Min(CoefficientMatrix.row, CoefficientMatrix.col) - 1; i >= 0; i--)
                {
                    //The system has more than one solutions. Get one.
                    if (ArgumentMatrix[i, i] == 0)
                    {
                        //More unknowns than equations
                        int j;
                        for (j = i+1; j < CoefficientMatrix.col; ++j)
                        {
                            if (ArgumentMatrix[i, j] != 0)
                            {
                                sum = 0;
                                for (int k = j + 1; k < CoefficientMatrix.col; ++k)
                                {
                                    sum += ArgumentMatrix[i, k] * x[k];
                                }
                                if (xSetFlag[j] == 0)
                                {
                                    //this is the 1st time setting the solution
                                    x[j] = (ArgumentMatrix[i, ArgumentMatrix.col - 1] - sum) / ArgumentMatrix[i, j];
                                    xSetFlag[j] = 1;
                                }
                                //this is not the 1st time setting the solution
                                else
                                    if (x[j] != (ArgumentMatrix[i, ArgumentMatrix.col - 1] - sum) / CoefficientMatrix[i, j])
                                    {
                                        return null;
                                    }
                                    else
                                        InfiniteSolution = true;
                                break;
                            }
                        }
                        //All coefficient == 0 & b[i] == 0 -> The system has infinitely many solutions
                        if ((j == CoefficientMatrix.col) && (ArgumentMatrix[i, ArgumentMatrix.col - 1] == 0))
                        {
                            x[i] = 0;
                            //xSetFlag[i] = 1;-> since we may use other equations to update this x[i] later, so don't set flag for case 0 = 0.
                            InfiniteSolution = true;
                        }
                        else if ((j == CoefficientMatrix.col) && (ArgumentMatrix[i, ArgumentMatrix.col - 1] != 0))
                            return null; //All coefficient == 0 & b[i] != 0 -> The system has no solutions
                    }
                    else
                    {
                        sum = 0;
                        for (int j = i + 1; j < CoefficientMatrix.col; ++j)
                        {
                            sum += ArgumentMatrix[i, j] * x[j];
                        }
                        x[i] = (ArgumentMatrix[i, ArgumentMatrix.col - 1] - sum) / ArgumentMatrix[i, i];
                        xSetFlag[i] = 1;
                    }
                }

                return x;
            }
            catch (Exception exp)
            {
                throw new MMatrixException("The system of equation cannot be solved:" + exp.Message);
            }
        }