# Structured Linear Equations in IronPython QuickStart Sample

Illustrates how to solve systems of simultaneous linear equations that have special structure in IronPython.

View this sample in: C# Visual Basic F#

```Python import numerics from System import Array from Extreme.Mathematics import * # The structured matrix classes reside in the # Extreme.Mathematics.LinearAlgebra namespace. from Extreme.Mathematics.LinearAlgebra import * # Illustrates solving symmetrical and triangular systems # of simultaneous linear equations using classes # in the Extreme.Mathematics.LinearAlgebra namespace of the Extreme # Optimization Mathematics Library for .NET. # To learn more about solving general systems of # simultaneous linear equations, see the # LinearEquations QuickStart Sample. # # The methods and classes available for solving # structured systems of equations are similar # to those for general equations. # # Triangular systems and matrices # print "Triangular matrices:" # For the basics of working with triangular # matrices, see the TriangularMatrices QuickStart # Sample. # # Let's start with a triangular matrix. Remember # that elements are stored in column-major order # by default. t = Matrix.CreateUpperTriangular(4, 4, Array[float]([ \ 1, 0, 0, 0, \ 1, 2, 0, 0, \ 1, 4, 1, 0, \ 1, 3, 1, 2 ]), \ MatrixElementOrder.ColumnMajor) b1 = Vector([ 1, 3, 6, 3 ]) b2 = Matrix([[1,2], [3,3], [6,5], [3,8]]) print "t = {0:.4f}".format(t) # # The Solve method # # The following solves m x = b1. The second # parameter specifies whether to overwrite the # right-hand side with the result. x1 = t.Solve(b1, False) print "x1 = {0:.4f}".format(x1) # If the overwrite parameter is omitted, the # right-hand-side is overwritten with the solution: t.Solve(b1) print "b1 = {0:.4f}".format(b1) # You can solve for multiple right hand side # vectors by passing them in a DenseMatrix: x2 = t.Solve(b2, False) print "x2 = {0:.4f}".format(x2) # # Related Methods # # You can verify whether a matrix is singular # using the IsSingular method: print "IsSingular(t) =", t.IsSingular() # The inverse matrix is returned by the Inverse # method: print "Inverse(t) = {0:.4f}".format(t.GetInverse()) # The determinant is also available: print "Det(t) = {0:.4f}".format(t.GetDeterminant()) # The condition number is an estimate for the # loss of precision in solving the equations print "Cond(t) = {0:.4f}".format(t.EstimateConditionNumber()) print # # Symmetric systems and matrices # print "Symmetric matrices:" # For the basics of working with symmetric # matrices, see the SymmetricMatrices QuickStart # Sample. # # Let's start with a symmetric matrix. Remember # that elements are stored in column-major order # by default. s = Matrix.CreateSymmetric(4, Array[float]([ \ 1, 0, 0, 0, \ 1, 2, 0, 0, \ 1, 1, 2, 0, \ 1, 0, 1, 4 ]), MatrixTriangle.Upper) b1 = Vector.Create(1, 3, 6, 3) print "s = {0:.4f}".format(s) # # The Solve method # # The following solves m x = b1. The second # parameter specifies whether to overwrite the # right-hand side with the result. x1 = s.Solve(b1, False) print "x1 = {0:.4f}".format(x1) # If the overwrite parameter is omitted, the # right-hand-side is overwritten with the solution: s.Solve(b1) print "b1 = {0:.4f}".format(b1) # You can solve for multiple right hand side # vectors by passing them in a DenseMatrix: x2 = s.Solve(b2, False) print "x2 = {0:.4f}".format(x2) # # Related Methods # # You can verify whether a matrix is singular # using the IsSingular method: print "IsSingular(s) =", s.IsSingular() # The inverse matrix is returned by the Inverse # method: print "Inverse(s) = {0:.4f}".format(s.GetInverse()) # The determinant is also available: print "Det(s) = {0:.4f}".format(s.GetDeterminant()) # The condition number is an estimate for the # loss of precision in solving the equations print "Cond(s) = {0:.4f}".format(s.EstimateConditionNumber()) print # # The CholeskyDecomposition class # # If the symmetric matrix is positive definite, # you can use the CholeskyDecomposition class # to optimize performance if multiple operations # need to be performed. This class does the # bulk of the calculations only once. This # decomposes the matrix into G x transpose(G) # where G is a lower triangular matrix. # # If the matrix is indefinite, you need to use # the LUDecomposition class instead. See the # LinearEquations QuickStart Sample for details. print "Using Cholesky Decomposition:" # The constructor takes an optional second argument # indicating whether to overwrite the original # matrix with its decomposition: cf = s.GetCholeskyDecomposition(False) # The Factorize method performs the actual # factorization. It is called automatically # if needed. cf.Decompose() # All methods mentioned earlier are still available: x2 = cf.Solve(b2, False) print "x2 = {0:.4f}".format(x2) print "IsSingular(m) =", cf.IsSingular() print "Inverse(m) = {0:.4f}".format(cf.GetInverse()) print "Det(m) = {0:.4f}".format(cf.GetDeterminant()) print "Cond(m) = {0:.4f}".format(cf.EstimateConditionNumber()) # In addition, you have access to the # triangular matrix, G, of the composition. print " G = {0:.4f}".format(cf.LowerTriangularFactor) # Note that if the matrix is indefinite, # the factorization will fail and throw a # MatrixNotPositiveDefiniteException. s[0, 0] = -99 cf = s.GetCholeskyDecomposition() try: cf.Decompose() except MatrixNotPositiveDefiniteException as e: print e.Message # To avoid this, you can use the TryDecompose method, # which returns True if the decomposition succeeds, # and false otherwise: if cf.TryDecompose(): print "Decomposition succeeded!" else: print "Decomposition failed!" ```