Data Analysis Mathematics Linear Algebra Statistics
New Version 7.0!  QuickStart Samples

# Triangular Matrices QuickStart Sample (F#)

Illustrates how to work efficiently with upper or lower triangular or trapezoidal matrices in F#.

```// Illustrates the use of the TriangularMatrix class in the
// Extreme.Mathematics.LinearAlgebra namespace of the Extreme Optimization
// Mathematics Library for .NET.

#light

open System

// The TriangularMatrix class resides in the Extreme.Mathematics.LinearAlgebra
// namespace.
open Extreme.Mathematics
open Extreme.Mathematics.LinearAlgebra

// Triangular matrices are matrices whose elements
// above or below the diagonal are all zero. The
// former is called lower triangular, the latter
// lower triangular. In addition, triangular matrices
// can have all 1's on the diagonal.

//
// Constructing triangular matrices
//

// Constructing triangular matrices is similar to
// constructing general matrices. See the
// BasicMatrices QuickStart samples for a more
// complete discussion.
//
// All constructors take a MatrixTriangle
// value as their first parameter. This indicates
// whether an upper or lower triangular matrix
// should be created. The following creates a
// 5x5 lower triangular matrix:
let t1 = Matrix.CreateLowerTriangular<float>(5, 5)
// You can also specify whether the diagonal
// consists of all 1's using a unitDiagonal parameter:
let t2 = Matrix.CreateLowerTriangular<float>(5, 5, MatrixDiagonal.UnitDiagonal)
// Triangular matrices access and modify only the
// elements that are non-zero. If the diagonal
// mode is UnitDiagonal, the diagonal elements
// are not used, since they are all equal to 1.
let elements =
[|
11.0; 12.0; 13.0; 14.0; 15.0;
21.0; 22.0; 23.0; 24.0; 25.0;
31.0; 32.0; 33.0; 34.0; 35.0;
41.0; 42.0; 43.0; 44.0; 45.0;
51.0; 52.0; 53.0; 54.0; 55.0
|]
// The following creates a matrix using the
// upper triangular part of the above.
let t3 = Matrix.CreateUpperTriangular(5, 5, elements, MatrixElementOrder.RowMajor)
printfn "t3 = %O" t3
// Same as above, but unit diagonal:
let t4 =
Matrix.CreateUpperTriangular(5, 5,
elements, MatrixDiagonal.UnitDiagonal,
MatrixElementOrder.RowMajor, true)
printfn "t4 = %O" t4

//
// Extracting triangular matrices
//

// You may want to use part of a dense matrix
// as a triangular matrix. The static
// ExtractUpperTriangle and ExtractLowerTriangle
let m = Matrix.Create(5, 5, elements, MatrixElementOrder.ColumnMajor)
printfn "m = %O" m
// Both methods are overloaded. The simplest
// returns a triangular matrix of the same dimension:
let t5 = Matrix.ExtractLowerTriangle(m)
printfn "t5 = %O" t5
// You can also specify if the matrix is unit diagonal:
let t6 = Matrix.ExtractUpperTriangle(m, MatrixDiagonal.UnitDiagonal)
printfn "t6 = %O" t6
// Or the dimensions of the matrix if they don't
// match the original:
let t7 = Matrix.ExtractUpperTriangle(m, 3, 3, MatrixDiagonal.UnitDiagonal)
printfn "t7 = %O" t7
printfn ""

//
// TriangularMatrix properties
//

// The IsLowerTriangular and IsUpperTriangular return
// a boolean value:
printfn "t4 is lower triangular? - %b" t4.IsLowerTriangular
printfn "t4 is upper triangular? - %b" t4.IsUpperTriangular
// The IsUnitDiagonal property indicates whether the
// matrix has all 1's on its diagonal:
printfn "t3 is unit diagonal? - %b" t3.IsUnitDiagonal
printfn "t4 is unit diagonal? - %b" t4.IsUnitDiagonal
printfn ""
// You can get and set matrix elements:
t3.[1, 3] <- 55.0
printfn "t3.[1, 3] = %O" t3.[1, 3]
// But trying to set an element that is zero or
// is on the diagonal for a unit diagonal matrix
// causes an exception to be thrown:
try
t3.[3, 1] <- 100.0
with :? ComponentReadOnlyException as e -> printfn "Error accessing element: %s" e.Message

//
// Rows and columns
//

// The GetRow and GetColumn methods are
// available.
let row = t3.GetRow(1)
printfn "row 2 of t3 = %O" row
let column = t4.GetColumn(1, 0, 2)
printfn "2nd column of t4 from row 1 to 3 = %O" column

printf "Press Enter key to exit..."