Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions benchmarks/FsMath.Benchmarks/FsMath.Benchmarks.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

<ItemGroup>
<Compile Include="Vector.fs" />
<Compile Include="LinearAlgebra.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

Expand Down
171 changes: 171 additions & 0 deletions benchmarks/FsMath.Benchmarks/LinearAlgebra.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
namespace FsMath.Benchmarks

open BenchmarkDotNet.Attributes
open FsMath
open FsMath.Algebra

/// <summary>
/// Benchmarks for linear algebra operations (QR, LU, Cholesky, EVD).
/// These operations are fundamental to scientific computing and their performance
/// is critical for applications in statistics, machine learning, and numerical analysis.
/// </summary>
[<MemoryDiagnoser>]
type LinearAlgebraBenchmarks() =

let mutable smallMatrix: Matrix<float> = Matrix.zeroCreate 10 10
let mutable mediumMatrix: Matrix<float> = Matrix.zeroCreate 30 30
let mutable largeMatrix: Matrix<float> = Matrix.zeroCreate 50 50

let mutable smallSymmetric: Matrix<float> = Matrix.zeroCreate 10 10
let mutable mediumSymmetric: Matrix<float> = Matrix.zeroCreate 30 30
let mutable largeSymmetric: Matrix<float> = Matrix.zeroCreate 50 50

let mutable smallVector: Vector<float> = Vector.zeroCreate 10
let mutable mediumVector: Vector<float> = Vector.zeroCreate 30
let mutable largeVector: Vector<float> = Vector.zeroCreate 50

/// Create a random positive-definite symmetric matrix for Cholesky/EVD benchmarks
let createSymmetricPositiveDefinite (n: int) =
let random = System.Random(42)
// Create a random matrix A
let a = Matrix.init n n (fun i j -> random.NextDouble())
// Make it symmetric positive-definite: A^T * A
let at = Matrix.transpose a
at * a

/// Create a random matrix for general decompositions
let createRandomMatrix (rows: int) (cols: int) =
let random = System.Random(42)
Matrix.init rows cols (fun i j -> random.NextDouble())

/// Create a random vector
let createRandomVector (n: int) =
let random = System.Random(42)
Vector.init n (fun i -> random.NextDouble())

[<GlobalSetup>]
member _.Setup() =
// Initialize matrices with proper random data
smallMatrix <- createRandomMatrix 10 10
mediumMatrix <- createRandomMatrix 30 30
largeMatrix <- createRandomMatrix 50 50

smallSymmetric <- createSymmetricPositiveDefinite 10
mediumSymmetric <- createSymmetricPositiveDefinite 30
largeSymmetric <- createSymmetricPositiveDefinite 50

smallVector <- createRandomVector 10
mediumVector <- createRandomVector 30
largeVector <- createRandomVector 50

// ============================================
// QR Decomposition Benchmarks
// ============================================

[<Benchmark>]
member _.QR_10x10() =
LinearAlgebra.qrDecompose smallMatrix

[<Benchmark>]
member _.QR_30x30() =
LinearAlgebra.qrDecompose mediumMatrix

[<Benchmark>]
member _.QR_50x50() =
LinearAlgebra.qrDecompose largeMatrix

// ============================================
// LU Decomposition Benchmarks
// ============================================

[<Benchmark>]
member _.LU_10x10() =
LinearAlgebra.luDecompose smallMatrix

[<Benchmark>]
member _.LU_30x30() =
LinearAlgebra.luDecompose mediumMatrix

[<Benchmark>]
member _.LU_50x50() =
LinearAlgebra.luDecompose largeMatrix

// ============================================
// Cholesky Decomposition Benchmarks
// ============================================

[<Benchmark>]
member _.Cholesky_10x10() =
LinearAlgebra.cholesky smallSymmetric

[<Benchmark>]
member _.Cholesky_30x30() =
LinearAlgebra.cholesky mediumSymmetric

[<Benchmark>]
member _.Cholesky_50x50() =
LinearAlgebra.cholesky largeSymmetric

// ============================================
// Eigenvalue Decomposition Benchmarks
// ============================================

[<Benchmark>]
member _.EVD_10x10() =
LinearAlgebra.symmetricEigenspectrum smallSymmetric

[<Benchmark>]
member _.EVD_30x30() =
LinearAlgebra.symmetricEigenspectrum mediumSymmetric

[<Benchmark>]
member _.EVD_50x50() =
LinearAlgebra.symmetricEigenspectrum largeSymmetric

// ============================================
// Linear System Solving Benchmarks
// ============================================

[<Benchmark>]
member _.SolveLinearSystem_10x10() =
LinearAlgebra.solveLinearSystem smallMatrix smallVector

[<Benchmark>]
member _.SolveLinearSystem_30x30() =
LinearAlgebra.solveLinearSystem mediumMatrix mediumVector

[<Benchmark>]
member _.SolveLinearSystem_50x50() =
LinearAlgebra.solveLinearSystem largeMatrix largeVector

// ============================================
// Matrix Inverse Benchmarks
// ============================================

[<Benchmark>]
member _.Inverse_10x10() =
LinearAlgebra.inverse smallMatrix

[<Benchmark>]
member _.Inverse_30x30() =
LinearAlgebra.inverse mediumMatrix

[<Benchmark>]
member _.Inverse_50x50() =
LinearAlgebra.inverse largeMatrix

// ============================================
// Least Squares Benchmarks
// ============================================

[<Benchmark>]
member _.LeastSquares_10x10() =
LinearAlgebra.leastSquares smallMatrix smallVector

[<Benchmark>]
member _.LeastSquares_30x30() =
LinearAlgebra.leastSquares mediumMatrix mediumVector

[<Benchmark>]
member _.LeastSquares_50x50() =
LinearAlgebra.leastSquares largeMatrix largeVector
3 changes: 2 additions & 1 deletion benchmarks/FsMath.Benchmarks/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ open FsMath.Benchmarks
[<EntryPoint>]
let Main args =
// Register multiple benchmark classes
let switcher = BenchmarkSwitcher [|
let switcher = BenchmarkSwitcher [|
typeof<VectorBenchmarks>
typeof<LinearAlgebraBenchmarks>
|]
switcher.Run args |> ignore
0
Loading