Skip to content

Commit

Permalink
Merge pull request #70 from jbrown1618/singular-value-decomposition
Browse files Browse the repository at this point in the history
Implemented Singular Value Decomposition
  • Loading branch information
jbrown1618 authored Jul 27, 2019
2 parents 9cdc6d6 + efe3221 commit d41443c
Show file tree
Hide file tree
Showing 20 changed files with 422 additions and 10 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ A linear algebra library written in TypeScript that focuses on generality, exten
- Matrix exponentials
- Elementary row operations
- Gauss-Jordan elimination
- Matrix Factorizations:
- Cholesky Decomposition
- LU Decomposition
- QR Decomposition
- Singular Value Decomposition
- Differentiation via finite differences
- Least-Squares Regression for arbitrary model functions
- LU Decomposition
- QR Decomposition
- Eigenvalue / Eigenvector finding
- And more to come!

Expand Down
25 changes: 18 additions & 7 deletions benchmarks/benchmark.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
/* tslint:disable:no-console */
import * as fs from 'fs';
import {
calculateLinearLeastSquaresApproximation,
calculateLinearLeastSquares,
calculateSingularValueDecomposition,
inverse,
linspace,
NumberMatrix,
NumberVector,
solveByGaussianElimination
} from '../src';

const repetitions: number = 5;
const repetitions = 5;

interface Benchmark {
description: string;
Expand All @@ -25,7 +26,7 @@ interface BenchmarkEntry {

generateBenchmarks();

function generateBenchmarks() {
function generateBenchmarks(): void {
generateBenchmark(
'matrix-plus-matrix',
1,
Expand Down Expand Up @@ -91,7 +92,17 @@ function generateBenchmarks() {
.fromColumnVectors([xs, ys])
.getRowVectors();
},
dataPoints => calculateLinearLeastSquaresApproximation(dataPoints)
dataPoints => calculateLinearLeastSquares(dataPoints)
);

generateBenchmark(
'singular-value-decomposition',
1,
32,
N => ({
A: NumberMatrix.builder().random(N)
}),
({ A }) => calculateSingularValueDecomposition(A)
);
}

Expand All @@ -101,7 +112,7 @@ function generateBenchmark<T>(
maxSize: number,
prepare: (N: number) => T,
runProcess: (data: T) => void
) {
): void {
console.log(`Benchmarking ${description}...`);

const benchmark: Benchmark = {
Expand All @@ -127,7 +138,7 @@ function generateBenchmark<T>(
writeBenchmarkToFile(benchmark);
}

function generateEntry(size: number, timings: number[]) {
function generateEntry(size: number, timings: number[]): BenchmarkEntry {
let minTime = Number.MAX_VALUE;
let maxTime = -Number.MAX_VALUE;
let total = 0;
Expand All @@ -147,7 +158,7 @@ function generateEntry(size: number, timings: number[]) {
return { size, minTime, maxTime, meanTime };
}

function writeBenchmarkToFile(benchmark: Benchmark) {
function writeBenchmarkToFile(benchmark: Benchmark): void {
const csvHeader = `Size,Min Time,Max Time,Mean Time\n`;
const csvBody = benchmark.entries
.map(entry => `${entry.size},${entry.minTime},${entry.maxTime},${entry.meanTime}`)
Expand Down
33 changes: 33 additions & 0 deletions benchmarks/latest/singular-value-decomposition.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Size,Min Time,Max Time,Mean Time
1,0,3,1.2
2,2,5,3.2
3,2,5,3.6
4,4,8,5.4
5,7,9,8.2
6,11,12,11.8
7,15,20,17.2
8,23,26,24.2
9,32,39,34
10,45,46,45.6
11,59,63,60.6
12,81,88,85
13,104,106,105
14,132,137,134
15,165,179,169.4
16,205,219,211.2
17,251,266,255.6
18,311,325,316
19,380,394,384.6
20,460,469,464.8
21,542,554,547.6
22,682,696,688.8
23,800,834,810.6
24,935,990,951.4
25,1092,1105,1099.2
26,1269,1287,1277.4
27,1464,1482,1471.2
28,1679,1694,1685.4
29,1962,2229,2113
30,2233,2843,2520.2
31,2482,2793,2586.4
32,2807,3444,3173.4
25 changes: 25 additions & 0 deletions docs/VECTOR.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ export abstract class ArrayVector<S> implements Vector<S> {
// @public
export function backwardDifferenceMatrix(binCount: number): NumberMatrix;

// @public
export function calculateCholeskyDecomposition<S>(A: Matrix<S>): CholeskyDecomposition<S> | undefined;

// @public
export function calculateEigenvalues<S>(A: Matrix<S>, numIterations?: number, throwOnFailure?: boolean): Vector<S>;

Expand All @@ -82,9 +85,18 @@ export function calculateLUDecomposition<S>(A: Matrix<S>): LUDecomposition<S>;
// @public
export function calculateQRDecomposition<S>(A: Matrix<S>): QRDecomposition<S>;

// @public
export function calculateSingularValueDecomposition<S>(A: Matrix<S>): SingularValueDecomposition<S>;

// @public
export function centralDifferenceMatrix(binCount: number): NumberMatrix;

// @public
export interface CholeskyDecomposition<S> {
// (undocumented)
L: Matrix<S>;
}

// @public
export function columnSumSupremumNorm<S>(A: Matrix<S>): number;

Expand Down Expand Up @@ -425,6 +437,9 @@ export interface QRDecomposition<S> {
R: Matrix<S>;
}

// @public
export function rank<S>(matrix: Matrix<S>): number;

// @public
export function reducedRowEchelonForm<S>(matrix: Matrix<S>): Matrix<S>;

Expand Down Expand Up @@ -465,6 +480,16 @@ export abstract class ScalarOperations<S> {
zero(): S;
}

// @public
export interface SingularValueDecomposition<S> {
// (undocumented)
Sigma: Matrix<S>;
// (undocumented)
U: Matrix<S>;
// (undocumented)
V: Matrix<S>;
}

// Warning: (ae-forgotten-export) The symbol "LinearSolution" needs to be exported by the entry point index.d.ts
//
// @public
Expand Down
30 changes: 30 additions & 0 deletions docs/api/vector.calculatecholeskydecomposition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@josh-brown/vector](./vector.md) &gt; [calculateCholeskyDecomposition](./vector.calculatecholeskydecomposition.md)

## calculateCholeskyDecomposition() function

Uses the serial version of the Cholesky algorith to calculate the Cholesky decomposition of a matrix `A`<!-- -->.

<b>Signature:</b>

```typescript
export declare function calculateCholeskyDecomposition<S>(A: Matrix<S>): CholeskyDecomposition<S> | undefined;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| A | <code>Matrix&lt;S&gt;</code> | The matrix to decompose |

<b>Returns:</b>

`CholeskyDecomposition<S> | undefined`

## Remarks

A Cholesky decomposition of a matrix `A` consists of a lower-triangular matrix `L` such that \_LL\* = A\_.

A Cholesky decomposition only exists if `A` is symmetrix and positive-definite.

28 changes: 28 additions & 0 deletions docs/api/vector.calculatesingularvaluedecomposition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@josh-brown/vector](./vector.md) &gt; [calculateSingularValueDecomposition](./vector.calculatesingularvaluedecomposition.md)

## calculateSingularValueDecomposition() function

Uses the Power Method to calculate the Singular Value Decomposition of a matrix `A`

<b>Signature:</b>

```typescript
export declare function calculateSingularValueDecomposition<S>(A: Matrix<S>): SingularValueDecomposition<S>;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| A | <code>Matrix&lt;S&gt;</code> | the matrix to decompose |

<b>Returns:</b>

`SingularValueDecomposition<S>`

## Remarks

A Singular Value Decomposition consists of orthogonal matrices `U` and `V` and a diagonal matrix `Sigma` such that \_USigmaV\* = A\_

11 changes: 11 additions & 0 deletions docs/api/vector.choleskydecomposition.l.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@josh-brown/vector](./vector.md) &gt; [CholeskyDecomposition](./vector.choleskydecomposition.md) &gt; [L](./vector.choleskydecomposition.l.md)

## CholeskyDecomposition.L property

<b>Signature:</b>

```typescript
L: Matrix<S>;
```
20 changes: 20 additions & 0 deletions docs/api/vector.choleskydecomposition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@josh-brown/vector](./vector.md) &gt; [CholeskyDecomposition](./vector.choleskydecomposition.md)

## CholeskyDecomposition interface

The result of a Cholesky Decomposition

<b>Signature:</b>

```typescript
export interface CholeskyDecomposition<S>
```

## Properties

| Property | Type | Description |
| --- | --- | --- |
| [L](./vector.choleskydecomposition.l.md) | <code>Matrix&lt;S&gt;</code> | |

5 changes: 5 additions & 0 deletions docs/api/vector.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@
| [addRowToRow(matrix, targetRow, rowToAdd)](./vector.addrowtorow.md) | An elementary row operations which returns a new matrix whose row at <code>targetRow</code> has had the row at <code>rowToAdd</code> added to it. |
| [addScalarMultipleOfRowToRow(matrix, targetRow, rowToAdd, scalar)](./vector.addscalarmultipleofrowtorow.md) | An elementary row operations which returns a new matrix whose row at <code>targetRow</code> has had a scalar multiple of <code>rowToAdd</code> added to it. |
| [backwardDifferenceMatrix(binCount)](./vector.backwarddifferencematrix.md) | Builds a matrix that transforms a vector to a vector of backward differences |
| [calculateCholeskyDecomposition(A)](./vector.calculatecholeskydecomposition.md) | Uses the serial version of the Cholesky algorith to calculate the Cholesky decomposition of a matrix <code>A</code>. |
| [calculateEigenvalues(A, numIterations, throwOnFailure)](./vector.calculateeigenvalues.md) | Uses the QR algorithm to compute the eigenvalues of a matrix <code>A</code> |
| [calculateGeneralLeastSquares(dataPoints, functionTemplate, numberOfTerms)](./vector.calculategeneralleastsquares.md) | Calculates a regression model for an arbitrary function. |
| [calculateLinearLeastSquares(dataPoints)](./vector.calculatelinearleastsquares.md) | Calculates a linear regression model for the provided <code>dataPoints</code>. |
| [calculateLUDecomposition(A)](./vector.calculateludecomposition.md) | Uses the Doolittle algorithm to calculate the LU Decomposition of a matrix A. |
| [calculateQRDecomposition(A)](./vector.calculateqrdecomposition.md) | Uses the Graham-Schmidt process to calculate the QR decomposition of the matrix A. |
| [calculateSingularValueDecomposition(A)](./vector.calculatesingularvaluedecomposition.md) | Uses the Power Method to calculate the Singular Value Decomposition of a matrix <code>A</code> |
| [centralDifferenceMatrix(binCount)](./vector.centraldifferencematrix.md) | Builds a matrix that transforms a vector to a vector of central differences |
| [columnSumSupremumNorm(A)](./vector.columnsumsupremumnorm.md) | Calculates the 1-Norm of a matrix <code>A</code> |
| [crossProduct(first, second)](./vector.crossproduct.md) | Calculates the cross-product (vector-product) of two vectors. This is defined only for vectors with three dimensions. |
Expand Down Expand Up @@ -67,6 +69,7 @@
| [prettyPrint(num)](./vector.prettyprint.md) | Returns an easy-to-read string representing a <code>number</code> |
| [prettyPrint(vector)](./vector.prettyprint_1.md) | Returns an easy-to-read string representing the contents of a [Vector](./vector.vector.md) |
| [prettyPrint(matrix)](./vector.prettyprint_2.md) | Returns an easy-to-read string representing the contents of a [Matrix](./vector.matrix.md) |
| [rank(matrix)](./vector.rank.md) | Calculates the rank of a matrix |
| [reducedRowEchelonForm(matrix)](./vector.reducedrowechelonform.md) | Uses Gauss-Jordan elimination with pivoting to convert a matrix to Reduced Row-Echelon Form (RREF) |
| [rowEchelonForm(matrix)](./vector.rowechelonform.md) | Uses Gauss-Jordan elimination with pivoting to convert a matrix to Row-Echelon Form (REF) |
| [rowSumSupremumNorm(A)](./vector.rowsumsupremumnorm.md) | Calculates the Infinity-Norm of a matrix <code>A</code> |
Expand All @@ -80,13 +83,15 @@

| Interface | Description |
| --- | --- |
| [CholeskyDecomposition](./vector.choleskydecomposition.md) | The result of a Cholesky Decomposition |
| [EigenPair](./vector.eigenpair.md) | An eigenvector and its corresponding eigenvalue |
| [LeastSquaresApproximation](./vector.leastsquaresapproximation.md) | The result of a least squares approximation. |
| [LinearTransformation](./vector.lineartransformation.md) | An abstract linear transformation between vectors of type <code>V</code> and vectors of type <code>U</code>. |
| [LUDecomposition](./vector.ludecomposition.md) | The result of an LU Decomposition |
| [Matrix](./vector.matrix.md) | A generalized Matrix - one of the core data types |
| [QRDecomposition](./vector.qrdecomposition.md) | The result of a QR decomposition. |
| [RowOperationResult](./vector.rowoperationresult.md) | The result of a row operation (<code>result</code>), and the matrix that we multiply by the original matrix to yield that result (<code>operator</code>) |
| [SingularValueDecomposition](./vector.singularvaluedecomposition.md) | The result of a Singular Value Decomposition |
| [Vector](./vector.vector.md) | A generalized Vector - one of the core data types |

## Type Aliases
Expand Down
28 changes: 28 additions & 0 deletions docs/api/vector.rank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@josh-brown/vector](./vector.md) &gt; [rank](./vector.rank.md)

## rank() function

Calculates the rank of a matrix

<b>Signature:</b>

```typescript
export declare function rank<S>(matrix: Matrix<S>): number;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| matrix | <code>Matrix&lt;S&gt;</code> | the matrix for which to determine the rank |

<b>Returns:</b>

`number`

## Remarks

The rank of a matrix A is the dimension of the vector space spanned by the columns of A. Equivalently, it is the number of pivot entries in the row-echelon form of A, or the number of nonzero rows in the row echelon form of A.

22 changes: 22 additions & 0 deletions docs/api/vector.singularvaluedecomposition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@josh-brown/vector](./vector.md) &gt; [SingularValueDecomposition](./vector.singularvaluedecomposition.md)

## SingularValueDecomposition interface

The result of a Singular Value Decomposition

<b>Signature:</b>

```typescript
export interface SingularValueDecomposition<S>
```

## Properties

| Property | Type | Description |
| --- | --- | --- |
| [Sigma](./vector.singularvaluedecomposition.sigma.md) | <code>Matrix&lt;S&gt;</code> | |
| [U](./vector.singularvaluedecomposition.u.md) | <code>Matrix&lt;S&gt;</code> | |
| [V](./vector.singularvaluedecomposition.v.md) | <code>Matrix&lt;S&gt;</code> | |

11 changes: 11 additions & 0 deletions docs/api/vector.singularvaluedecomposition.sigma.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@josh-brown/vector](./vector.md) &gt; [SingularValueDecomposition](./vector.singularvaluedecomposition.md) &gt; [Sigma](./vector.singularvaluedecomposition.sigma.md)

## SingularValueDecomposition.Sigma property

<b>Signature:</b>

```typescript
Sigma: Matrix<S>;
```
11 changes: 11 additions & 0 deletions docs/api/vector.singularvaluedecomposition.u.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@josh-brown/vector](./vector.md) &gt; [SingularValueDecomposition](./vector.singularvaluedecomposition.md) &gt; [U](./vector.singularvaluedecomposition.u.md)

## SingularValueDecomposition.U property

<b>Signature:</b>

```typescript
U: Matrix<S>;
```
11 changes: 11 additions & 0 deletions docs/api/vector.singularvaluedecomposition.v.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@josh-brown/vector](./vector.md) &gt; [SingularValueDecomposition](./vector.singularvaluedecomposition.md) &gt; [V](./vector.singularvaluedecomposition.v.md)

## SingularValueDecomposition.V property

<b>Signature:</b>

```typescript
V: Matrix<S>;
```
Loading

0 comments on commit d41443c

Please sign in to comment.