/// <summary>
      /// Given a positive-definite symmetric matrix <c>A[0..n][0..n]</c>, 
      /// this routine constructs its Cholesky decomposition,  <c> A = L*(L^T) </c>. 
      /// </summary>
      /// <remarks>
      /// The operations count is <c>(N^3)/6</c> executions of the inner loop (consisting of 
      /// one multiply and one subtract), with also N square roots. 
      /// This is about a factor 2 better than LU decomposition of <c>A</c> 
      /// (where its symmetry would be ignored).
      /// </remarks>
      /// <param name="matrix">Square Symmetric Definite-defined matrix A. 
      /// </param>
      /// <exception cref="ArgumentNullException"><paramref name="matrix"/> is a null reference.</exception>
      /// <exception cref="ArgumentException"><paramref name="matrix"/> is a not Symmetric.</exception>
      /// <exception cref="ArgumentException"><paramref name="matrix"/> is a null Square.</exception>
      /// <returns> The Cholesky factor L is returned</returns>
      public void Decompose(Matrix matrix)
      {

         Guard.ArgumentNotNull(matrix, "a");


          matrix.ValidateIsSymmetric();
         

         var aRows = matrix.Rows;

         var res = new Matrix(aRows, aRows);

         for (var i = 0; i < aRows; i++)
         {
            int j;
            for (j = i; j < aRows; j++)
            {
               int k;
               double sum;
               for (sum = matrix[i, j], k = i - 1; k >= 0; k--)
               {
                  sum -= res[i, k] * res[j, k];
               }

               if (i == j)
               {
                  if (sum <= 0)
                  {
                      throw new ArgumentException(isNotPositiveDefinite);
                  }

                   res[i, i] = Math.Sqrt(sum);
               }
               else
               {
                  res[j, i] = sum / res[i, i];
               }
            }
         }
         LeftFactorMatrix = res;
      }
Пример #2
0
        public static double[] QuickSolveLinearEquation(Matrix a, double[] b)
        {
            #region Validation

             Guard.ArgumentNotNull(a, "a");
             Guard.ArgumentNotNull(b, "b");

             #endregion

              a.ValidateIsSymmetric();

             var aRowCount = a.Rows;

             if (b.Length != aRowCount)
             {
             throw new ArgumentException(haveNonMatchingDimensions);
             }

              //L is a Cholesky Decomposition
             var decomposeMatrix = QuickDecompose(a);
             var x = new double[aRowCount];
             int k;
             double sum;
             for (var i = 0; i < aRowCount; i++)
             {
            // Solve <c>L * y = b</c>, storing y in x.
            for (sum = b[i], k = i - 1; k >= 0; k--)
            {
               sum -= decomposeMatrix[i, k] * x[k];
            }
            x[i] = sum / decomposeMatrix[i, i];
             }

             for (var i = aRowCount - 1; i >= 0; i--)
             {
            // Solve L^T * x = y.
            for (sum = x[i], k = i + 1; k < aRowCount; k++)
            {
               sum -= decomposeMatrix[k, i] * x[k];
            }
            x[i] = sum / decomposeMatrix[i, i];
             }

             return x;
        }
Пример #3
0
        public static Matrix QuickDecompose(Matrix a)
        {
            Guard.ArgumentNotNull(a, "a");

              a.ValidateIsSymmetric();

             var aRowCount = a.Rows;

             var res = new Matrix(aRowCount, aRowCount);

             for (var i = 0; i < aRowCount; i++)
             {
            int j;
            for (j = i; j < aRowCount; j++)
            {
               int k;
               double sum;
               for (sum = a[i, j], k = i - 1; k >= 0; k--)
               {
                  sum -= res[i, k] * res[j, k];
               }

               if (i == j)
               {
                  if (sum <= 0)
                  {
                      throw new ArgumentException(isNotPositiveDefinite);
                  }

                  res[i, i] = Math.Sqrt(sum);
               }
               else
               {
                  res[j, i] = sum / res[i, i];
               }
            }
             }
             return res;
        }