Skip to content

Commit 740933b

Browse files
authored
Merge pull request #24 from fslaborg/perf/linear-algebra-benchmarks-35a09c6111df8849
Daily Perf Improver - Add comprehensive linear algebra benchmarks
2 parents a6e9f42 + 2968fea commit 740933b

File tree

3 files changed

+174
-1
lines changed

3 files changed

+174
-1
lines changed

benchmarks/FsMath.Benchmarks/FsMath.Benchmarks.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
<ItemGroup>
99
<Compile Include="Vector.fs" />
10+
<Compile Include="LinearAlgebra.fs" />
1011
<Compile Include="Program.fs" />
1112
</ItemGroup>
1213

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
namespace FsMath.Benchmarks
2+
3+
open BenchmarkDotNet.Attributes
4+
open FsMath
5+
open FsMath.Algebra
6+
7+
/// <summary>
8+
/// Benchmarks for linear algebra operations (QR, LU, Cholesky, EVD).
9+
/// These operations are fundamental to scientific computing and their performance
10+
/// is critical for applications in statistics, machine learning, and numerical analysis.
11+
/// </summary>
12+
[<MemoryDiagnoser>]
13+
type LinearAlgebraBenchmarks() =
14+
15+
let mutable smallMatrix: Matrix<float> = Matrix.zeroCreate 10 10
16+
let mutable mediumMatrix: Matrix<float> = Matrix.zeroCreate 30 30
17+
let mutable largeMatrix: Matrix<float> = Matrix.zeroCreate 50 50
18+
19+
let mutable smallSymmetric: Matrix<float> = Matrix.zeroCreate 10 10
20+
let mutable mediumSymmetric: Matrix<float> = Matrix.zeroCreate 30 30
21+
let mutable largeSymmetric: Matrix<float> = Matrix.zeroCreate 50 50
22+
23+
let mutable smallVector: Vector<float> = Vector.zeroCreate 10
24+
let mutable mediumVector: Vector<float> = Vector.zeroCreate 30
25+
let mutable largeVector: Vector<float> = Vector.zeroCreate 50
26+
27+
/// Create a random positive-definite symmetric matrix for Cholesky/EVD benchmarks
28+
let createSymmetricPositiveDefinite (n: int) =
29+
let random = System.Random(42)
30+
// Create a random matrix A
31+
let a = Matrix.init n n (fun i j -> random.NextDouble())
32+
// Make it symmetric positive-definite: A^T * A
33+
let at = Matrix.transpose a
34+
at * a
35+
36+
/// Create a random matrix for general decompositions
37+
let createRandomMatrix (rows: int) (cols: int) =
38+
let random = System.Random(42)
39+
Matrix.init rows cols (fun i j -> random.NextDouble())
40+
41+
/// Create a random vector
42+
let createRandomVector (n: int) =
43+
let random = System.Random(42)
44+
Vector.init n (fun i -> random.NextDouble())
45+
46+
[<GlobalSetup>]
47+
member _.Setup() =
48+
// Initialize matrices with proper random data
49+
smallMatrix <- createRandomMatrix 10 10
50+
mediumMatrix <- createRandomMatrix 30 30
51+
largeMatrix <- createRandomMatrix 50 50
52+
53+
smallSymmetric <- createSymmetricPositiveDefinite 10
54+
mediumSymmetric <- createSymmetricPositiveDefinite 30
55+
largeSymmetric <- createSymmetricPositiveDefinite 50
56+
57+
smallVector <- createRandomVector 10
58+
mediumVector <- createRandomVector 30
59+
largeVector <- createRandomVector 50
60+
61+
// ============================================
62+
// QR Decomposition Benchmarks
63+
// ============================================
64+
65+
[<Benchmark>]
66+
member _.QR_10x10() =
67+
LinearAlgebra.qrDecompose smallMatrix
68+
69+
[<Benchmark>]
70+
member _.QR_30x30() =
71+
LinearAlgebra.qrDecompose mediumMatrix
72+
73+
[<Benchmark>]
74+
member _.QR_50x50() =
75+
LinearAlgebra.qrDecompose largeMatrix
76+
77+
// ============================================
78+
// LU Decomposition Benchmarks
79+
// ============================================
80+
81+
[<Benchmark>]
82+
member _.LU_10x10() =
83+
LinearAlgebra.luDecompose smallMatrix
84+
85+
[<Benchmark>]
86+
member _.LU_30x30() =
87+
LinearAlgebra.luDecompose mediumMatrix
88+
89+
[<Benchmark>]
90+
member _.LU_50x50() =
91+
LinearAlgebra.luDecompose largeMatrix
92+
93+
// ============================================
94+
// Cholesky Decomposition Benchmarks
95+
// ============================================
96+
97+
[<Benchmark>]
98+
member _.Cholesky_10x10() =
99+
LinearAlgebra.cholesky smallSymmetric
100+
101+
[<Benchmark>]
102+
member _.Cholesky_30x30() =
103+
LinearAlgebra.cholesky mediumSymmetric
104+
105+
[<Benchmark>]
106+
member _.Cholesky_50x50() =
107+
LinearAlgebra.cholesky largeSymmetric
108+
109+
// ============================================
110+
// Eigenvalue Decomposition Benchmarks
111+
// ============================================
112+
113+
[<Benchmark>]
114+
member _.EVD_10x10() =
115+
LinearAlgebra.symmetricEigenspectrum smallSymmetric
116+
117+
[<Benchmark>]
118+
member _.EVD_30x30() =
119+
LinearAlgebra.symmetricEigenspectrum mediumSymmetric
120+
121+
[<Benchmark>]
122+
member _.EVD_50x50() =
123+
LinearAlgebra.symmetricEigenspectrum largeSymmetric
124+
125+
// ============================================
126+
// Linear System Solving Benchmarks
127+
// ============================================
128+
129+
[<Benchmark>]
130+
member _.SolveLinearSystem_10x10() =
131+
LinearAlgebra.solveLinearSystem smallMatrix smallVector
132+
133+
[<Benchmark>]
134+
member _.SolveLinearSystem_30x30() =
135+
LinearAlgebra.solveLinearSystem mediumMatrix mediumVector
136+
137+
[<Benchmark>]
138+
member _.SolveLinearSystem_50x50() =
139+
LinearAlgebra.solveLinearSystem largeMatrix largeVector
140+
141+
// ============================================
142+
// Matrix Inverse Benchmarks
143+
// ============================================
144+
145+
[<Benchmark>]
146+
member _.Inverse_10x10() =
147+
LinearAlgebra.inverse smallMatrix
148+
149+
[<Benchmark>]
150+
member _.Inverse_30x30() =
151+
LinearAlgebra.inverse mediumMatrix
152+
153+
[<Benchmark>]
154+
member _.Inverse_50x50() =
155+
LinearAlgebra.inverse largeMatrix
156+
157+
// ============================================
158+
// Least Squares Benchmarks
159+
// ============================================
160+
161+
[<Benchmark>]
162+
member _.LeastSquares_10x10() =
163+
LinearAlgebra.leastSquares smallMatrix smallVector
164+
165+
[<Benchmark>]
166+
member _.LeastSquares_30x30() =
167+
LinearAlgebra.leastSquares mediumMatrix mediumVector
168+
169+
[<Benchmark>]
170+
member _.LeastSquares_50x50() =
171+
LinearAlgebra.leastSquares largeMatrix largeVector

benchmarks/FsMath.Benchmarks/Program.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ open FsMath.Benchmarks
55
[<EntryPoint>]
66
let Main args =
77
// Register multiple benchmark classes
8-
let switcher = BenchmarkSwitcher [|
8+
let switcher = BenchmarkSwitcher [|
99
typeof<VectorBenchmarks>
10+
typeof<LinearAlgebraBenchmarks>
1011
|]
1112
switcher.Run args |> ignore
1213
0

0 commit comments

Comments
 (0)