Skip to content

Commit

Permalink
Do not use randomness in tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jecisc committed Mar 13, 2023
1 parent c881227 commit 5fb38e9
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 159 deletions.
48 changes: 29 additions & 19 deletions src/Math-Matrix-Tests/PMAdditionalTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,42 @@ PMAdditionalTest >> testMatrixInversionSmall [

| m c i |
c := PMSymmetricMatrix identity: 5.
3
timesRepeat: [ [ m := PMSymmetricMatrix new: 5 random: 20.
m determinant = 0 ] whileTrue. "singular matrix not allowed"
self assert: (i := m crlInverse) * m closeTo: c.
self assert: i class equals: PMSymmetricMatrix.
self assert: (i := m inversePureLUP) * m closeTo: c.
self assert: i class equals: PMSymmetricMatrix.
self assert: m * (i := m inversePureCRL) closeTo: c.
self assert: i class equals: PMSymmetricMatrix ].
3
timesRepeat: [ [ m := PMMatrix rows: 5 columns: 5 random: 20.
m determinant = 0 ] whileTrue.
self assert: m * (i := m inverse) closeTo: c.
self assert: i class equals: PMMatrix.
self assert: (i := m inversePureCRL) * m closeTo: c.
self assert: i class equals: PMMatrix ]
3 timesRepeat: [
[
m := PMSymmetricMatrix new: 5 random: 20 generator: (Random seed: 42).
m determinant = 0 ] whileTrue. "singular matrix not allowed"
self assert: (i := m crlInverse) * m closeTo: c.
self assert: i class equals: PMSymmetricMatrix.
self assert: (i := m inversePureLUP) * m closeTo: c.
self assert: i class equals: PMSymmetricMatrix.
self assert: m * (i := m inversePureCRL) closeTo: c.
self assert: i class equals: PMSymmetricMatrix ].
3 timesRepeat: [
[
m := PMMatrix
rows: 5
columns: 5
random: 20
generator: (Random seed: 42).
m determinant = 0 ] whileTrue.
self assert: m * (i := m inverse) closeTo: c.
self assert: i class equals: PMMatrix.
self assert: (i := m inversePureCRL) * m closeTo: c.
self assert: i class equals: PMMatrix ]
]

{ #category : #tests }
PMAdditionalTest >> testMatrixSquared [
"this tests squared and is not in Math-Tests-Numerical since it uses random matrices"

| a |
10
timesRepeat: [ a := PMMatrix rows: 20 columns: 21 random: 10.0.
self assert: a squared equals: a transpose * a ].
10 timesRepeat: [
a := PMMatrix
rows: 20
columns: 21
random: 10.0
generator: (Random seed: 42).
self assert: a squared equals: a transpose * a ].
self assert: a squared class equals: PMSymmetricMatrix
]

Expand Down
106 changes: 53 additions & 53 deletions src/Math-Matrix-Tests/PMQRTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -98,25 +98,29 @@ PMQRTest >> testMoorePenroseInverseOfNonRandomMatrix [

{ #category : #tests }
PMQRTest >> testMoorePenroseInverseOfProductOfMatrices [

| a inverse |
a := PMMatrix new initializeRows:
#( #( 5 40 1 ) #( 0 0 1 ) #( 0 0 1 ) ).

a := a * (PMMatrix rows: 3 columns: 3 random: 5.0).
inverse := a mpInverse .
self assert: inverse isMoorePenroseInverseOf: a.
a := PMMatrix new initializeRows: #( #( 5 40 1 ) #( 0 0 1 ) #( 0 0 1 ) ).

a := a * (PMMatrix
rows: 3
columns: 3
random: 5.0
generator: (Random seed: 42)).
inverse := a mpInverse.
self assert: inverse isMoorePenroseInverseOf: a
]

{ #category : #tests }
PMQRTest >> testMoorePenroseInverseOfRandomMatrixIsAnInverse [
"
"
Proofs for the properties below can be found in literature:
If A has real entries, then so does A+
If A is invertible, its pseudoinverse is its inverse. That is, A+ = A**−1
"

| a |
a := PMSymmetricMatrix new: 4 random: 1.0.
a := PMSymmetricMatrix new: 4 random: 1.0 generator: (Random seed: 42).
self assert: (a mpInverse closeTo: a inverse)
]

Expand All @@ -125,9 +129,13 @@ PMQRTest >> testOrthogonalize [

| a b i |
i := 0.
[
a := PMMatrix rows: 5 columns: 5 random: 5.0.
a rank = 5 ifTrue: [
[
a := PMMatrix
rows: 5
columns: 5
random: 5.0
generator: (Random seed: 42).
a rank = 5 ifTrue: [
a atRow: 2 put: (a rowAt: 1) + (3 * (a rowAt: 3)).
a atRow: 4 put: 3.11 * (a rowAt: 2).
b := a orthogonalize.
Expand All @@ -146,60 +154,55 @@ PMQRTest >> testOrthogonalize [
PMQRTest >> testQRFactorization [

| a qr |
5 timesRepeat: [
a := PMMatrix rows: 5 columns: 4 random: 10.0.
5 timesRepeat: [
a := PMMatrix
rows: 5
columns: 4
random: 10.0
generator: (Random seed: 42).
qr := a qrFactorization.
self assert: (a closeTo: qr first * qr second).
self assert: (qr first squared closeTo:
(PMSymmetricMatrix identity: qr first numberOfColumns)).
2 to: qr second numberOfRows do: [ :r |
self assert: (((qr second rowAt: r) first: r - 1) closeTo:
(Array new: r - 1 withAll: 0)) ].
self assert: (qr first squared closeTo: (PMSymmetricMatrix identity: qr first numberOfColumns)).
2 to: qr second numberOfRows do: [ :r | self assert: (((qr second rowAt: r) first: r - 1) closeTo: (Array new: r - 1 withAll: 0)) ].

qr := a qrFactorizationWithPivoting.
self assert:
(a closeTo: qr first * (qr second inversePivotColumns: (qr at: 3))).
self assert: (qr first squared closeTo:
(PMSymmetricMatrix identity: qr first numberOfColumns)).
2 to: qr second numberOfRows do: [ :r |
self assert: (((qr second rowAt: r) first: r - 1) closeTo:
(Array new: r - 1 withAll: 0)) ].

a := PMSymmetricMatrix new: 4 random: 10.0.
self assert: (a closeTo: qr first * (qr second inversePivotColumns: (qr at: 3))).
self assert: (qr first squared closeTo: (PMSymmetricMatrix identity: qr first numberOfColumns)).
2 to: qr second numberOfRows do: [ :r | self assert: (((qr second rowAt: r) first: r - 1) closeTo: (Array new: r - 1 withAll: 0)) ].

a := PMSymmetricMatrix new: 4 random: 10.0 generator: (Random seed: 42).
qr := a qrFactorization.
self assert: (a closeTo: qr first * qr second).
self assert: (qr first squared closeTo:
(PMSymmetricMatrix identity: qr first numberOfColumns)).
2 to: qr second numberOfRows do: [ :r |
self assert: (((qr second rowAt: r) first: r - 1) closeTo:
(Array new: r - 1 withAll: 0)) ].
self assert: (qr first squared closeTo: (PMSymmetricMatrix identity: qr first numberOfColumns)).
2 to: qr second numberOfRows do: [ :r | self assert: (((qr second rowAt: r) first: r - 1) closeTo: (Array new: r - 1 withAll: 0)) ].

qr := a qrFactorizationWithPivoting.
self assert:
(a closeTo: qr first * (qr second inversePivotColumns: (qr at: 3))).
self assert: (qr first squared closeTo:
(PMSymmetricMatrix identity: qr first numberOfColumns)).
2 to: qr second numberOfRows do: [ :r |
self assert: (((qr second rowAt: r) first: r - 1) closeTo:
(Array new: r - 1 withAll: 0)) ] ]
self assert: (a closeTo: qr first * (qr second inversePivotColumns: (qr at: 3))).
self assert: (qr first squared closeTo: (PMSymmetricMatrix identity: qr first numberOfColumns)).
2 to: qr second numberOfRows do: [ :r | self assert: (((qr second rowAt: r) first: r - 1) closeTo: (Array new: r - 1 withAll: 0)) ] ]
]

{ #category : #tests }
PMQRTest >> testRank [

| random randomNumber matrix |
random := Random new.

10 timesRepeat: [
matrix := PMMatrix rows: 5 columns: 7 random: 5.0.
matrix := PMMatrix
rows: 5
columns: 7
random: 5.0
generator: (Random seed: 42).
matrix rank = 5 ifTrue: [
randomNumber := random nextBetween: 0 and: 3.
matrix atRow: 2 put: (matrix rowAt: 1) + (randomNumber * (matrix rowAt: 3)).

randomNumber := random nextBetween: 0 and: 3.
matrix atRow: 4 put: (0.5 + randomNumber) * (matrix rowAt: 5).
matrix atRow: 4 put: 0.5 + randomNumber * (matrix rowAt: 5).

self assert: matrix rank equals: 3.
self assert: matrix transpose rank equals: 3 ] ].
self assert: matrix transpose rank equals: 3 ] ]
]

{ #category : #tests }
Expand Down Expand Up @@ -243,17 +246,14 @@ PMQRTest >> testSimpleQRDecompositionWithPivot [

{ #category : #tests }
PMQRTest >> testVectorHouseholder [

"result is householdermatrix * v"

(2 to: 5) do: [ :i |
(2 to: 5) do: [ :i |
| v h result |
(1 to: 9) do: [ :unimportant |
v := PMVector new: i random: 5.8.
(1 to: 9) do: [ :unimportant |
v := PMVector new: i random: 5.8 generator: (Random seed: 42).
h := v householder.
result := (PMSymmetricMatrix identity: i)
- ((h at: 1) * (h at: 2) tensorProduct: (h at: 2)) * v.
result := (PMSymmetricMatrix identity: i) - ((h at: 1) * (h at: 2) tensorProduct: (h at: 2)) * v.
self deny: (result first closeTo: 0).
result allButFirst do: [ :aNumber |
self assert: (aNumber closeTo: 0) ] ] ]
result allButFirst do: [ :aNumber | self assert: (aNumber closeTo: 0) ] ] ]
]
14 changes: 8 additions & 6 deletions src/Math-Matrix-Tests/PMRestTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ Class {
PMRestTest >> testEqualsTo [

| a b |
a := PMMatrix rows: 5 columns: 7 random: 5.0.
a := PMMatrix
rows: 5
columns: 7
random: 5.0
generator: (Random seed: 42).
b := a deepCopy.
self assert: (a closeTo: b).
b rowAt: 4 columnAt: 6 put: 6.
Expand All @@ -17,12 +21,10 @@ PMRestTest >> testEqualsTo [

{ #category : #tests }
PMRestTest >> testNewRandom [
|a |
a:=PMSymmetricMatrix new:7 random: 5.0 .
a:=PMMatrix rows: a rows.
self assert: (a isSymmetric ).


| a |
a := PMSymmetricMatrix new: 7 random: 5.0 generator: (Random seed: 42).
self assert: a isSymmetric
]

{ #category : #tests }
Expand Down
90 changes: 49 additions & 41 deletions src/Math-Matrix/PMMatrix.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -20,51 +20,52 @@ Class {

{ #category : #example }
PMMatrix class >> example [
""
|a b c d|
"This is how we can create a matrix, a and b are 2x3 matrices in
""

| a b c d |
"This is how we can create a matrix, a and b are 2x3 matrices in
this example"
a := PMMatrix rows: #( ( 1 0 1 ) (-1 -2 3)).
b := PMMatrix rows: #( ( 1 2 3 ) (-2 1 7)).
a := PMMatrix rows: #( #( 1 0 1 ) #( -1 -2 3 ) ).
b := PMMatrix rows: #( #( 1 2 3 ) #( -2 1 7 ) ).

"Matrix product"
c := a * b.
"Matrix product"
c := a * b.

"Elementwise matrix product"
d := a hadamardProduct: b.
"Elementwise matrix product"
d := a hadamardProduct: b.

"This is how we can create a vector"
a := #(1 4 9 16 25) asPMVector.
"This is how we can create a vector"
a := #( 1 4 9 16 25 ) asPMVector.

"Vectors and Matrices support basic logical and arithmetic
"Vectors and Matrices support basic logical and arithmetic
operations"
Float pi sin * d.
a sqrt.
a > 3.
c cos.
c < 0.
Float pi sin * d.
a sqrt.
a > 3.
c cos.
c < 0.

"It is possible to create a vector/matrix of random numbers"
a := PMVector randomSize: 10 maxNumber: 3.
b := PMMatrix rows: 2 columns: 3 random: 5.
"It is possible to create a vector/matrix of random numbers"
a := PMVector randomSize: 10 maxNumber: 3.
b := PMMatrix rows: 2 columns: 3 random: 5.

"It is also easy to create a vector/matrix of zeros/ones"
a := PMVector ones:15.
b := PMMatrix zerosRows: 2 cols: 3.
"It is also easy to create a vector/matrix of zeros/ones"
a := PMVector ones: 15.
b := PMMatrix zerosRows: 2 cols: 3.

"We can also compute the cumulative sum or regular sum the vector/
"We can also compute the cumulative sum or regular sum the vector/
matrix as following"
a := PMMatrix rows: #( ( 1 0 1 ) (-1 -2 3)).
a cumsum.
"a PMVector(1 1 2)"
"a PMVector(-1 -3 0)"
a sum.
"a PMVector(2 0)"
a := PMMatrix rows: #( #( 1 0 1 ) #( -1 -2 3 ) ).
a cumsum.
"a PMVector(1 1 2)"
"a PMVector(-1 -3 0)"
a sum.
"a PMVector(2 0)"

"Matrix trace (sum of a diagonal elements for a square matrix)"
a := PMMatrix rows: #((1 2 3)(4 5 6)(7 8 9)).
a tr.
"15"
"Matrix trace (sum of a diagonal elements for a square matrix)"
a := PMMatrix rows: #( #( 1 2 3 ) #( 4 5 6 ) #( 7 8 9 ) ).
a tr
"15"
]

{ #category : #'instance creation' }
Expand Down Expand Up @@ -147,14 +148,21 @@ PMMatrix class >> rows: nRows columns: nCols element: fillElement [

{ #category : #'instance creation' }
PMMatrix class >> rows: aNumberOfRows columns: aNumberOfColumns random: aMaxNumber [

^ self
rows: aNumberOfRows
columns: aNumberOfColumns
random: aMaxNumber
generator: Random new
]

{ #category : #'instance creation' }
PMMatrix class >> rows: aNumberOfRows columns: aNumberOfColumns random: aMaxNumber generator: aGenerator [
"Answer a new Matrix of the given dimensions filled with random numbers"
| random rows |
random := Random new.

rows := (1 to: aNumberOfRows) collect: [ :i |
(1 to: aNumberOfColumns) collect: [ :j |
random nextBetween: 0 and: aMaxNumber ] ].


| rows |
rows := (1 to: aNumberOfRows) collect: [ :i | (1 to: aNumberOfColumns) collect: [ :j | aGenerator nextBetween: 0 and: aMaxNumber ] ].

^ self rows: rows
]

Expand Down
Loading

0 comments on commit 5fb38e9

Please sign in to comment.