Skip to content

amoretspero/FSharp_Linear_Algebra

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FSharp Linear Algebra

Library for linear algebra made with F#.

Build Status

Build status

Version

Stable : 0.4.2.0
Unstable : 0.4.2.1 (stable version <> newest version)

Update History

0.4.2.0 -> 0.4.2.1

  • Supports row-space, left-null-space calculation of matrices.
  • Supports right-inverse, left-inverse calculation and existness check of matrices.
  • May not be tested.

0.4.1.0 -> 0.4.2.0

  • Supports RREF(Row-Reduced Echelon Form)-decomposition for any m by n matrix.
  • Supports column-space, null-space calculation of matrices.
  • Supports rank computation of matrices.
  • Solving linear system of Ax=b (A : m by n matrix, x : n-dim vector, b : m-dim vector) is now possible.

Description

This project is to provide F#-made linear algebra library.
Support will mainly include matrix and vector computation.
Also, most of objects will be generic, meaning you can use this library with types you want.
Currently, no optimization is provided.

Supported Features

Matrix

Construction : You can create matrix with three options.

  1. Basic constructor - matrix<'T>(rowCnt : int, columnCnt : int, element : 'T [,])
  2. Zero matrix constructor - matrix<'T>(rowCnt : int, columnCnt : int, zero : 'T)
  3. Constructor with Array2D. - matrix<'T>(elem : 'T [] [])
open FSharp_Linear_Algebra.Matrix

// First constructor. Should provide type.
let matrix1 = matrix<int>(3, 7, (Array2D.init 3 7 (fun idx1 idx2 -> idx1 * idx2 - 1)))

// Second constructor. Should provide zero for type of matrix.
let matrix2 = matrix(3, 3, 0)

// Third constructor. Should provide type.
let matrix3 = matrix<float>([| [| 1.334; 8.461; 9.361; 2.904; 5.837 |]; [| 0.948; 8.847; 6.372; 4.981; 7.829 |]; [| 1.938; 3.284; 8.944; 5.748; 2.987 |] |])

// Check matrices.
printfn "matrix1 is : \n%A" (matrix1.Format())
printfn "matrix2 is : \n%A" (matrix2.Format())
printfn "matrix3 is : \n%A" (matrix3.Format())

Stringify : Format() method.

open FSharp_Linear_Algebra

// Float matrix.
let matrix4 = matrix<float>([| [| 1.334; 8.461; 9.361; 2.904; 5.837 |]; [| 0.948; 8.847; 6.372; 4.981; 7.829 |]; [| 1.938; 3.284; 8.944; 5.748; 2.987 |] |])
matrix4.Format() |> printfn "Matrix formatted: \n%s"
(*
Output will be:

Matrix formatted: 
1.334 8.461 9.361 2.904 5.837
0.948 8.847 6.372 4.981 7.829
1.938 3.284 8.944 5.748 2.987

*)

File I/O : You can write to or read from files.

  1. Write to file - Matrix.WriteToFile()
  2. Read from file (int32) - Matrix.ReadFromFileInt32()
  3. Read from file (double) - Matrix.ReadFromFileDouble()
open FSharp_Linear_Algebra

// Float matrix.
let matrix5 = matrix<float>([| [| 1.334; 8.461; 9.361; 2.904; 5.837 |]; [| 0.948; 8.847; 6.372; 4.981; 7.829 |]; [| 1.938; 3.284; 8.944; 5.748; 2.987 |] |])

// Write matrix to file.
Matrix.WriteToFile matrix5 ".\float.txt"

// Read integer matrix from file.
let integerMatrixFromFile = Matrix.ReadFromFileInt32 ".\Int32Matrix.txt"

// Read double matrix from file.
let doubleMatrixFromFile = Matrix.ReadFromFileDouble ".\DoubleMatrix.txt"

Computation : You can perform basic matrix computations.

  1. Addition - Matrix.Add()
  2. Subtraction - Matrix.Subtract()
  3. Multiplication - Matrix.Multiply()
  4. Transpose - Matrix.Transpose()
  5. Scalar multiplication - Matrix.ScalarMultiply()
  6. Identity matrix - Matrix.Identity()
  7. Inverse matrix - Matrix.Inverse()
  8. Column space - Matrix.ColumnSpace()
  9. Null Space - Matrix.NullSpace()
  10. Rank - Matrix.Rank()
  11. Solve - Matrix.Solve()
open FSharp_Linear_Algebra.Matrix
open FSharp_Linear_Algebra.Matrix.Computation

// Matrix initialization.
let matrix6 = matrix<decimal>([| [| 2M; 1M; 1M; |]; [| 4M; -6M; 0M; |]; [| -2M; 7M; 2M; |] |])
let matrix7 = matrix<decimal>([| [| 1M; 1M; 1M; |]; [| 2M; 2M; 5M; |]; [| 4M; 6M; 8M; |] |])

// Addition
let matrixAdd = Matrix.Add matrix6  matrix7
matrixAdd.Format() |> printfn "matrixAdd: \n%s"

// Subtraction
let matrixSubtract = Matrix.Subtract matrix6 matrix7
matrixSubtract.Format() |> printfn "matrixSubt: \n%s"

// Multiplication
let matrixMultiply = Matrix.Multiply matrix6 matrix7
matrixMultiply.Format() |> printfn "matrixMultiply: \n%s"

// Transpose
let matrixTranspose = Matrix.Transpose matrix6
matrixTranspose.Format() |> printfn "matrixTranspose: \n%s"

// Scalar multiplication
let matrixScalarMultiply = Matrix.ScalarMultiply 1.5M matrix6
matrixScalarMultiply.Format() |> printfn "matrixScalarMultiply: \n%s"

// Identity matrix
let matrixIdentity = Matrix.Identity 3 1.0
matrixIdentity.Format() |> printfn "matrixIdentity: \n%s"

// Inverse matrix
let matrixInverse = Matrix.Inverse matrix6
matrixInverse.Format() |> printfn "matrixInverse: \n%s"

// Column space
let columnSpaceResult = Matrix.ColumnSpace matrix8
for vec in columnSpaceResult do vec.Format() |> printfn "Basis of column space: \n%s"
printfn ""

// Null space
let nullSpaceResult = Matrix.NullSpace matrix8
for vec in nullSpaceResult do vec.Format() |> printfn "Basis of null space: \n%s"
printfn ""

// Rank
let rankResult = Matrix.Rank matrix8
printfn "Rank of matrix \n%A is: %d\n" (matrix8.Format()) rankResult

// Solve
let matrixSolverRHS = vector<double>([| 1.0; 5.0; 5.0 |])
let matrixSolverResult = Matrix.Solve matrix8 matrixSolverRHS 10E-8
matrixSolverResult.Format() |> printfn "Solver result: \n%s"
printfn ""

(*
Output: 

matrixAdd: 
3	2	2	
6	-4	5	
2	13	10	

matrixSubt: 
1	0	0	
2	-8	-5	
-6	1	-6	

matrixMultiply: 
8	10	15	
-8	-8	-26	
20	24	49	

matrixTranspose: 
2	4	-2	
1	-6	7	
1	0	2	

matrixScalarMultiply: 
3.0	1.5	1.5	
6.0	-9.0	0.0	
-3.0	10.5	3.0	

matrixIdentity: 
1	0	0	
0	1	0	
0	0	1	

matrixInverse: 
0.750000	-0.312500	-0.375000	
0.50000	-0.37500	-0.25000	
-1.000	1.000	1.000	

Basis of column space: 
[1 , 2 , -1 ]
Basis of column space: 
[3 , 9 , 3 ]

Basis of null space: 
[-3 , 1 , 0 , 0 ]
Basis of null space: 
[1 , 0 , -1 , 1 ]

Rank of matrix                                                                                                                                     
"1      3       3       2                                                                                                                          
2       6       9       7                                                                                                                          
-1      -3      3       4                                                                                                                          
" is: 2  

Solver result: 
[-2 , 0 , 1 , 0 ]

*)

Decomposition : Decomposition of matrix is provided.

  1. LDU-decomposition - Matrix.Decomposition.LDUdecomposition()
  2. RREF-decomposition - Matrix.Decomposition.RREFdecomposition()
open FSharp_Linear_Algebra.Matrix
open FSharp_Linear_Algebra.Matrix.Decomposition

// Random double matrix.
let matrix9 = RandomMatrix().RandomMatrixDouble 5 5
let matrix10 = RandomMatrix().RandomMatrixDouble 4 6

// LDU-decompose matrix.
let matrix9LU = Decomposition.LDUdecomposition matrix9

// Check P, L, D, U.
printfn "LDU-decomposition result - permutation matrix P : \n%A" (matrix9LU.Permutation.Format())
printfn "LDU-decomposition result - lower triangular matrix L : \n%A" (matrix9LU.Lower.Format())
printfn "LDU-decomposition result - diagonal matrix D : \n%A" (matrix9LU.Diagonal.Format())
printfn "LDU-decomposition result - upper triangular matrix U : \n%A" (matrix9LU.Upper.Format())

// RREF-decompose matrix.
let matrix10RREF = Decomposition.RREFdecomposition matrix10

// Check P, L, D, U, R
printfn "RREF-decomposition result - permutation matrix P : \n%A" (matrix10RREF.Permutation.Format())
printfn "RREF-decomposition result - lower matrix L : \n%A" (matrix10RREF.Lower.Format())
printfn "RREF-decomposition result - diagonal matrix D : \n%A" (matrix10RREF.Diagonal.Format())
printfn "RREF-decomposition result - upper matrix U : \n%A" (matrix10RREF.Upper.Format())
printfn "RREF-decomposition result - row-reduced echelon form matrix R : \n%A" (matrix10RREF.RREF.Format())

(*
Output will be (since random, results will vary) :

LDU-decomposition result - permutation matrix P : 
"1	0	0	0	0	
0	1	0	0	0	
0	0	0	0	1	
0	0	0	1	0	
0	0	1	0	0	
"
LDU-decomposition result - lower triangular matrix L : 
"1	0	0	0	0	
0.912469584879621	1	0	0	0	
0.833733308876576	0.968478037172233	1	0	0	
0.590786545174727	0.262825024811019	0.180887100037611	1	0	
0.921801935169788	0.865103479331415	-0.124928821945207	-0.36879768313967	1	
"
LDU-decomposition result - diagonal matrix D : 
"0.745390404362879	0	0	0	0	
0	0.615656479489813	0	0	0	
0	0	0.954266027830404	0	0	
0	0	0	0.0599831511524589	0	
0	0	0	0	0.19338922474478	
"
LDU-decomposition result - upper triangular matrix U : 
"1	0.358528834085624	0.901718659865987	0.294647960357563	0.274469225759811	
0	1	-0.883290706941838	0.719233246935208	-0.0118039081690822	
0	0	1	0.358018525062971	0.796112066982027	
0	0	0	1	-2.96933778536181	
0	0	0	0	1	
"
RREF-decomposition result - permutation matrix P : 
"1	0	0	0	
0	0	1	0	
0	0	0	1	
0	1	0	0	
"
RREF-decomposition result - lower matrix L : 
"1	0	0	0	
0.9535784851072	1	0	0	
0.527288198847576	0.46956950844709	1	0	
0.334476937476073	-0.0218903515260848	-0.62438804542556	1	
"
RREF-decomposition result - diagonal matrix D : 
"0.753324252904078	0	0	0	
0	-0.379502444666017	0	0	
0	0	-0.101856058152057	0	
0	0	0	0.0847669578101374	
"
RREF-decomposition result - upper matrix U : 
"1	1.30696035806646	1.05408676749352	1.04405797143949	
0	1	1.11920725818051	-0.342936070083238	
0	0	1	0.395603364762073	
0	0	0	1	
"
RREF-decomposition result - row-reduced echelon form matrix R : 
"1	0	0	0	-6.965740643683	-14.6999169103296	
0	1	0	0	4.38431226497532	11.6898662777569	
0	0	1	0	-3.38679671772621	-6.40875568979755	
0	0	0	1	4.85267767956053	7.04913469209129	
"

*)

Vector

Construction : You can create vector with one option.

  1. Basic constructor - (element : 'T [])
open FSharp_Linear_Algebra.Vector

// Basic constructor. Should provide type.
let vector1 = vector<int>([| 1; 2; 3; 4; 5 |])

Stringify : Format() method.

open FSharp_Linear_Algebra.Vector

// Decimal vector whose dimension is 3.
let vector2 = vector<decimal>([| 1.0M; 1.5M; -2.0M |])
vector2.Format() |> printfn "vector2: %s\n"

(*
Output:

1   1.5 -2

*)

Computation : You can perform basic vector computations.

  1. Addition - Vector.Add()
  2. Subtracion - Vector.Subtract()
  3. Inner Production - Vector.InnerProduct
  4. Size (int32) - Vector.SizeInt32
  5. Size (int64) - Vector.SizeInt64
  6. Size (float32) - Vector.SizeFloat32
  7. Size (double) - Vector.SizeDouble
  8. Unit vector check - Vector.IsUnitVector()
  9. Zero vector constructor - Vector.ZeroVector()
  10. Unit vector constructor - Vector.UnitVector()
open FSharp_Linear_Algebra.Vector

// Vector initialization
let vec1 = vector<decimal>([| 1.0M; 2.0M; 3.0M; |])
let vec2 = vector<decimal>([| 2.0M; -1.5M; -2.0M; |])

// Addition
let vectorAdd = Vector.Add vec1 vec2
vectorAdd.Format() |> printfn "vectorAdd: \n%s"

// Subtraction
let vectorSubtract = Vector.Subtract vec1 vec2
vectorSubtract.Format() |> printfn "vectorSub: \n%s"

// Inner production
let vectorInnerProduct = Vector.InnerProduct vec1 vec2
vectorInnerProduct.Format() |> printfn "vectorInnerProduct: \n%s"

// Size - int32
let sizeInt32Vector = vector<int32>([| 3; 4 |])
Vector.SizeInt32 sizeInt32Vector |> printfn "Size of %s is: \n%d" (sizeInt32Vector.Format())

// Size - int64
let sizeInt64Vector = vector<int64>([| 3L; 4L |])
Vector.SizeInt64 sizeInt64Vector |> printfn "Size of %s is: \n%d" (sizeInt32Vector.Format())

// Size - float32
let sizeFloat32Vector = vector<float32>([| 3.2f; 4.1f |])
Vector.SizeFloat32 sizeFloat32Vector |> printfn "Size of %s is: \n%A" (sizeFloat32Vector.Format())

// Size - int32
let sizeDoubleVector = vector<double>([| 2.5; 4.7; 5.6 |])
Vector.SizeDouble sizeDoubleVector |> printfn "Size of %s is: \n%A" (sizeDoubleVector.Format())

// Zero vector creation
let zeroVector = Vector.ZeroVector<decimal> 3
zeroVector.Format() |> printfn "zeroVector: \n%s"

// Unit vector creation
let unitVector = Vector.UnitVector 5 3 1.0
unitVector.Format() |> printfn "unitVector: \n%s"

// Check unit vector
let nonUnitVector = vector<float>([| 1.2; 2.1; 0.0 |])
let unitVector2 = vector<float>([| 0.5; -0.5; 0.5; -0.5 |])
if Vector.IsUnitVector nonUnitVector then 
    printfn "ERROR! This is not unit vector: \n%s" (nonUnitVector.Format()) 
else 
    printfn "CORRECT! This is not unit vector: \n%s" (nonUnitVector.Format())
if Vector.IsUnitVector unitVector then
    printfn "CORRECT! This is unit vector: \n%s" (unitVector2.Format())
else
    printfn "ERROR! This is unit vector: \n%s" (unitVector2.Format())

(*
Output: 

vectorAdd: 
[3.0 , 0.5 , 1.0 ]
vectorSub: 
[-1.0 , 3.5 , 5.0 ]
vectorInnerProduct: 
[2.00 , -3.00 , -6.00 ]
Size of [3 , 4 ] is: 
5
Size of [3 , 4 ] is: 
5
Size of [3.2 , 4.1 ] is: 
5.20096159f
Size of [2.5 , 4.7 , 5.6 ] is: 
7.726577509
zeroVector: 
[0 , 0 , 0 ]
unitVector: 
[0 , 0 , 1 , 0 , 0 ]
CORRECT! This is not unit vector: 
[1.2 , 2.1 , 0 ]
CORRECT! This is unit vector: 
[0.5 , -0.5 , 0.5 , -0.5 ]

*)

License

This program is open source under MIT license.

Copyright (c) 2016 Jiung Hahm

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

Linear Algebra library for .NET, made with F#

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages