From 163f69deaabe22542520d248a6a70c6566283fd5 Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Fri, 13 Feb 2026 17:11:31 +0100 Subject: [PATCH 1/7] added column wise operations --- src/Math-Matrix/ManifestMathMatrix.class.st | 10 +- src/Math-Matrix/Number.extension.st | 8 +- .../PMJacobiTransformation.class.st | 39 +-- .../PMJacobiTransformationHelper.class.st | 17 +- src/Math-Matrix/PMLUPDecomposition.class.st | 35 +-- .../PMLargestEigenValueFinder.class.st | 35 +-- .../PMLinearEquationSystem.class.st | 31 +- src/Math-Matrix/PMMatrix.class.st | 273 ++++++++++-------- src/Math-Matrix/PMNDArray.class.st | 55 ++-- src/Math-Matrix/PMQRDecomposition.class.st | 25 +- .../PMSingularMatrixError.class.st | 11 +- .../PMSingularValueDecomposition.class.st | 23 +- src/Math-Matrix/PMSymmetricMatrix.class.st | 75 ++--- src/Math-Matrix/PMVector.extension.st | 8 +- src/Math-Matrix/ShapeMismatch.class.st | 11 +- src/Math-Matrix/package.st | 2 +- 16 files changed, 350 insertions(+), 308 deletions(-) diff --git a/src/Math-Matrix/ManifestMathMatrix.class.st b/src/Math-Matrix/ManifestMathMatrix.class.st index cf14922..11015d7 100644 --- a/src/Math-Matrix/ManifestMathMatrix.class.st +++ b/src/Math-Matrix/ManifestMathMatrix.class.st @@ -2,12 +2,14 @@ Please describe the package using the class comment of the included manifest class. The manifest class also includes other additional metadata for the package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser " Class { - #name : #ManifestMathMatrix, - #superclass : #PackageManifest, - #category : #'Math-Matrix-Manifest' + #name : 'ManifestMathMatrix', + #superclass : 'PackageManifest', + #category : 'Math-Matrix-Manifest', + #package : 'Math-Matrix', + #tag : 'Manifest' } -{ #category : #'meta-data - dependency analyser' } +{ #category : 'meta-data - dependency analyser' } ManifestMathMatrix class >> manuallyResolvedDependencies [ ^ #(#'Collections-Streams' #'Math-Operations-Extensions') ] diff --git a/src/Math-Matrix/Number.extension.st b/src/Math-Matrix/Number.extension.st index c092e34..df6aaba 100644 --- a/src/Math-Matrix/Number.extension.st +++ b/src/Math-Matrix/Number.extension.st @@ -1,12 +1,12 @@ -Extension { #name : #Number } +Extension { #name : 'Number' } -{ #category : #'*Math-Matrix' } +{ #category : '*Math-Matrix' } Number >> addWithRegularMatrix: aMatrix [ "Adds itself to every row of the matrix" ^ PMMatrix rows: (aMatrix rowsCollect: [ :row | row + self ]) ] -{ #category : #'*Math-Matrix' } +{ #category : '*Math-Matrix' } Number >> complexConjugate [ "The complex conjugate of a complex number (a + bi) is another complex number (a - bi). Every real number x is also a complex number with imaginary part equal to 0. @@ -18,7 +18,7 @@ Number >> complexConjugate [ ^ self ] -{ #category : #'*Math-Matrix' } +{ #category : '*Math-Matrix' } Number >> productWithMatrix: aMatrix [ ^aMatrix class rows: (aMatrix rowsCollect: [:r| self productWithVector: r]) ] diff --git a/src/Math-Matrix/PMJacobiTransformation.class.st b/src/Math-Matrix/PMJacobiTransformation.class.st index 4b6335d..5e4bc50 100644 --- a/src/Math-Matrix/PMJacobiTransformation.class.st +++ b/src/Math-Matrix/PMJacobiTransformation.class.st @@ -11,8 +11,8 @@ eigenvectors := jacobi transform columnsCollect: [ :each | each]. ``` " Class { - #name : #PMJacobiTransformation, - #superclass : #Object, + #name : 'PMJacobiTransformation', + #superclass : 'Object', #instVars : [ 'precision', 'desiredPrecision', @@ -21,22 +21,23 @@ Class { 'lowerRows', 'transform' ], - #category : #'Math-Matrix' + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #creation } +{ #category : 'creation' } PMJacobiTransformation class >> matrix: aSymmetricMatrix [ ^ super new initialize: aSymmetricMatrix ] -{ #category : #creation } +{ #category : 'creation' } PMJacobiTransformation class >> new [ "Prevent using this message to create instances." ^ self error: 'Illegal creation message for this class' ] -{ #category : #accessing } +{ #category : 'accessing' } PMJacobiTransformation >> desiredPrecision: aNumber [ "Defines the desired precision for the result." @@ -44,7 +45,7 @@ PMJacobiTransformation >> desiredPrecision: aNumber [ desiredPrecision := aNumber ] -{ #category : #operation } +{ #category : 'operation' } PMJacobiTransformation >> evaluate [ "Perform the iteration until either the desired precision is attained or the number of iterations exceeds the maximum." @@ -58,7 +59,7 @@ PMJacobiTransformation >> evaluate [ ^ result ] -{ #category : #operation } +{ #category : 'operation' } PMJacobiTransformation >> evaluateIteration [ | indices | @@ -67,7 +68,7 @@ PMJacobiTransformation >> evaluateIteration [ ^ precision ] -{ #category : #transformation } +{ #category : 'transformation' } PMJacobiTransformation >> exchangeAt: anInteger [ "Private" @@ -82,7 +83,7 @@ PMJacobiTransformation >> exchangeAt: anInteger [ each at: anInteger put: temp ] ] -{ #category : #operation } +{ #category : 'operation' } PMJacobiTransformation >> finalizeIterations [ "Transfer the eigenValues into a vector and set this as the result. eigen values and transform matrix are sorted using a bubble sort." @@ -95,13 +96,13 @@ PMJacobiTransformation >> finalizeIterations [ self sortEigenValues ] -{ #category : #testing } +{ #category : 'testing' } PMJacobiTransformation >> hasConverged [ ^ precision <= desiredPrecision ] -{ #category : #initialization } +{ #category : 'initialization' } PMJacobiTransformation >> initialize [ super initialize. @@ -109,7 +110,7 @@ PMJacobiTransformation >> initialize [ maximumIterations := 50 ] -{ #category : #initialization } +{ #category : 'initialization' } PMJacobiTransformation >> initialize: aSymmetricMatrix [ "Private" @@ -125,7 +126,7 @@ PMJacobiTransformation >> initialize: aSymmetricMatrix [ yourself) ] ] -{ #category : #accessing } +{ #category : 'accessing' } PMJacobiTransformation >> largestOffDiagonalIndices [ "Private" @@ -143,7 +144,7 @@ PMJacobiTransformation >> largestOffDiagonalIndices [ ^ Array with: m with: n ] -{ #category : #accessing } +{ #category : 'accessing' } PMJacobiTransformation >> maximumIterations: anInteger [ "Defines the maximum number of iterations." @@ -151,14 +152,14 @@ PMJacobiTransformation >> maximumIterations: anInteger [ maximumIterations := anInteger ] -{ #category : #printing } +{ #category : 'printing' } PMJacobiTransformation >> printOn: aStream [ "Append to the argument aStream, a sequence of characters that describes the receiver." lowerRows do: [ :each | each printOn: aStream ] separatedBy: [ aStream cr ] ] -{ #category : #transformation } +{ #category : 'transformation' } PMJacobiTransformation >> sortEigenValues [ "Private - Use a bubble sort." @@ -175,13 +176,13 @@ PMJacobiTransformation >> sortEigenValues [ bound := m ] ] -{ #category : #transformation } +{ #category : 'transformation' } PMJacobiTransformation >> transform [ ^ PMMatrix rows: transform ] -{ #category : #transformation } +{ #category : 'transformation' } PMJacobiTransformation >> transformAt: anInteger1 and: anInteger2 [ "Private" diff --git a/src/Math-Matrix/PMJacobiTransformationHelper.class.st b/src/Math-Matrix/PMJacobiTransformationHelper.class.st index 7675cc0..28daefa 100644 --- a/src/Math-Matrix/PMJacobiTransformationHelper.class.st +++ b/src/Math-Matrix/PMJacobiTransformationHelper.class.st @@ -2,28 +2,29 @@ I store eigenvalues and eigenvectors of a symmetric matrix computed with PMJacobiTransformation " Class { - #name : #PMJacobiTransformationHelper, - #superclass : #Object, + #name : 'PMJacobiTransformationHelper', + #superclass : 'Object', #instVars : [ 'eigenvalues', 'eigenvectors' ], - #category : #'Math-Matrix' + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #creation } +{ #category : 'creation' } PMJacobiTransformationHelper class >> matrix: aSymmetricMatrix [ ^ super new initialize: aSymmetricMatrix ] -{ #category : #creation } +{ #category : 'creation' } PMJacobiTransformationHelper class >> new [ "Prevent using this message to create instances." ^ self error: 'Illegal creation message for this class' ] -{ #category : #initialization } +{ #category : 'initialization' } PMJacobiTransformationHelper >> initialize: aSymmetricMatrix [ | jacobi | @@ -32,13 +33,13 @@ PMJacobiTransformationHelper >> initialize: aSymmetricMatrix [ eigenvectors := jacobi transform columnsCollect: [ :each | each]. ] -{ #category : #accessing } +{ #category : 'accessing' } PMJacobiTransformationHelper >> values [ ^ eigenvalues ] -{ #category : #accessing } +{ #category : 'accessing' } PMJacobiTransformationHelper >> vectors [ ^ eigenvectors diff --git a/src/Math-Matrix/PMLUPDecomposition.class.st b/src/Math-Matrix/PMLUPDecomposition.class.st index 0ff70b6..75c5779 100644 --- a/src/Math-Matrix/PMLUPDecomposition.class.st +++ b/src/Math-Matrix/PMLUPDecomposition.class.st @@ -19,28 +19,29 @@ sol2 := s solve: #(7 10 9). ]]] " Class { - #name : #PMLUPDecomposition, - #superclass : #Object, + #name : 'PMLUPDecomposition', + #superclass : 'Object', #instVars : [ 'rows', 'permutation', 'parity' ], - #category : #'Math-Matrix' + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #creation } +{ #category : 'creation' } PMLUPDecomposition class >> direct: anArrayOfArrays [ ^ self basicNew initialize: anArrayOfArrays. ] -{ #category : #creation } +{ #category : 'creation' } PMLUPDecomposition class >> equations: anArrayOfArrays [ ^ self new initialize: (anArrayOfArrays collect: [ :each | each copy ]) ] -{ #category : #private } +{ #category : 'private' } PMLUPDecomposition >> backwardSubstitution: anArray [ "Private" | n sum answer | @@ -55,7 +56,7 @@ PMLUPDecomposition >> backwardSubstitution: anArray [ ^answer ] -{ #category : #private } +{ #category : 'private' } PMLUPDecomposition >> decompose [ "Private" | n | @@ -68,7 +69,7 @@ PMLUPDecomposition >> decompose [ ]. ] -{ #category : #operations } +{ #category : 'operations' } PMLUPDecomposition >> determinant [ | n | permutation isNil @@ -80,7 +81,7 @@ PMLUPDecomposition >> determinant [ into: [ :det :each | n := n + 1. ( each at: n) * det ] ] -{ #category : #private } +{ #category : 'private' } PMLUPDecomposition >> forwardSubstitution: anArray [ "Private" | n sum answer| @@ -95,14 +96,14 @@ PMLUPDecomposition >> forwardSubstitution: anArray [ ^answer ] -{ #category : #initialization } +{ #category : 'initialization' } PMLUPDecomposition >> initialize: anArrayOfArrays [ rows := anArrayOfArrays. parity := 1. ^ self ] -{ #category : #operations } +{ #category : 'operations' } PMLUPDecomposition >> inverseMatrixComponents [ | n inverseRows column | permutation isNil @@ -120,7 +121,7 @@ PMLUPDecomposition >> inverseMatrixComponents [ ^inverseRows ] -{ #category : #operations } +{ #category : 'operations' } PMLUPDecomposition >> largestPivotFrom: anInteger [ "Private - Answers the largest pivot element in column anInteger, from position anInteger upward." | valueOfMaximum indexOfMaximum value | @@ -136,7 +137,7 @@ PMLUPDecomposition >> largestPivotFrom: anInteger [ ^ indexOfMaximum ] -{ #category : #private } +{ #category : 'private' } PMLUPDecomposition >> pivotAt: anInteger [ "Private" | inversePivot size k | @@ -153,7 +154,7 @@ PMLUPDecomposition >> pivotAt: anInteger [ ]. ] -{ #category : #printing } +{ #category : 'printing' } PMLUPDecomposition >> printOn: aStream [ | delimitingString | @@ -170,13 +171,13 @@ PMLUPDecomposition >> printOn: aStream [ separatedBy: [ aStream cr ] ] -{ #category : #private } +{ #category : 'private' } PMLUPDecomposition >> protectedDecomposition [ "Private - If decomposition fails, set permutation to 0." [ self decompose] on: Error do: [ :signal | permutation := 0. signal return: nil]. ] -{ #category : #private } +{ #category : 'private' } PMLUPDecomposition >> solve: anArrayOrVector [ permutation isNil ifTrue: [ self protectedDecomposition ]. @@ -186,7 +187,7 @@ PMLUPDecomposition >> solve: anArrayOrVector [ [self backwardSubstitution: ( self forwardSubstitution: anArrayOrVector)] on: ZeroDivide do: [:e| nil] ] ] -{ #category : #private } +{ #category : 'private' } PMLUPDecomposition >> swapRow: anInteger1 withRow: anInteger2 [ "Private - Swap the rows indexed by the given integers." | swappedRow | diff --git a/src/Math-Matrix/PMLargestEigenValueFinder.class.st b/src/Math-Matrix/PMLargestEigenValueFinder.class.st index eafea64..b485bbf 100644 --- a/src/Math-Matrix/PMLargestEigenValueFinder.class.st +++ b/src/Math-Matrix/PMLargestEigenValueFinder.class.st @@ -14,8 +14,8 @@ nextEigenvector := nextFinder eigenvector. ``` " Class { - #name : #PMLargestEigenValueFinder, - #superclass : #Object, + #name : 'PMLargestEigenValueFinder', + #superclass : 'Object', #instVars : [ 'precision', 'desiredPrecision', @@ -25,16 +25,17 @@ Class { 'eigenvector', 'transposeEigenvector' ], - #category : #'Math-Matrix' + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #information } +{ #category : 'information' } PMLargestEigenValueFinder class >> defaultPrecision [ "Private - Answers the default precision for newly created instances." ^PMFloatingPointMachine new defaultNumericalPrecision ] -{ #category : #creation } +{ #category : 'creation' } PMLargestEigenValueFinder class >> matrix: aMatrix [ "Create a new instance of the receiver for a given matrix and default precision." @@ -43,7 +44,7 @@ PMLargestEigenValueFinder class >> matrix: aMatrix [ yourself ] -{ #category : #creation } +{ #category : 'creation' } PMLargestEigenValueFinder class >> matrix: aMatrix precision: aNumber [ "Create a new instance of the receiver for a given matrix and desired precision." @@ -53,7 +54,7 @@ PMLargestEigenValueFinder class >> matrix: aMatrix precision: aNumber [ yourself ] -{ #category : #accessing } +{ #category : 'accessing' } PMLargestEigenValueFinder >> desiredPrecision: aNumber [ "Defines the desired precision for the result." @@ -61,21 +62,21 @@ PMLargestEigenValueFinder >> desiredPrecision: aNumber [ desiredPrecision := aNumber ] -{ #category : #information } +{ #category : 'information' } PMLargestEigenValueFinder >> eigenvalue [ "Answer the eigen value found by the receiver." ^ result ] -{ #category : #information } +{ #category : 'information' } PMLargestEigenValueFinder >> eigenvector [ "Answer the normalized eigen vector found by the receiver." ^ eigenvector * (1 / eigenvector norm) ] -{ #category : #operation } +{ #category : 'operation' } PMLargestEigenValueFinder >> evaluate [ "Perform the iteration until either the desired precision is attained or the number of iterations exceeds the maximum." @@ -91,7 +92,7 @@ PMLargestEigenValueFinder >> evaluate [ ^ result ] -{ #category : #operation } +{ #category : 'operation' } PMLargestEigenValueFinder >> evaluateIteration [ "Iterate the product of the matrix of the eigen vector and the transpose." @@ -107,13 +108,13 @@ PMLargestEigenValueFinder >> evaluateIteration [ ifNotNil: [ (result - oldEigenvalue) abs ] ] -{ #category : #testing } +{ #category : 'testing' } PMLargestEigenValueFinder >> hasConverged [ ^ precision <= desiredPrecision ] -{ #category : #initialization } +{ #category : 'initialization' } PMLargestEigenValueFinder >> initialize [ super initialize. @@ -121,14 +122,14 @@ PMLargestEigenValueFinder >> initialize [ maximumIterations := 100 ] -{ #category : #initialization } +{ #category : 'initialization' } PMLargestEigenValueFinder >> initialize: aMatrix [ "Defines the matrix for the receiver." matrix := aMatrix ] -{ #category : #operation } +{ #category : 'operation' } PMLargestEigenValueFinder >> initializeIterations [ "Initialize the iterations (subclasses must write their own method and call this one last)." @@ -138,7 +139,7 @@ PMLargestEigenValueFinder >> initializeIterations [ transposeEigenvector atAllPut: 1.0 ] -{ #category : #accessing } +{ #category : 'accessing' } PMLargestEigenValueFinder >> maximumIterations: anInteger [ "Defines the maximum number of iterations." @@ -146,7 +147,7 @@ PMLargestEigenValueFinder >> maximumIterations: anInteger [ maximumIterations := anInteger ] -{ #category : #creation } +{ #category : 'creation' } PMLargestEigenValueFinder >> nextLargestEigenValueFinder [ "Return an eigen value finder for the same eigen values of the receiver except the one found." diff --git a/src/Math-Matrix/PMLinearEquationSystem.class.st b/src/Math-Matrix/PMLinearEquationSystem.class.st index 875c9ec..5c13714 100644 --- a/src/Math-Matrix/PMLinearEquationSystem.class.st +++ b/src/Math-Matrix/PMLinearEquationSystem.class.st @@ -16,16 +16,17 @@ method ==pivotAt:== when the division with the zero pivot is performed. The meth exception handling structure and sets the solution vector to a special value --- the integer 0 --- as a flag to prevent attempting Gaussian elimination a second time. Then, the value ==nil== is returned to represent the non-existent solution. " Class { - #name : #PMLinearEquationSystem, - #superclass : #Object, + #name : 'PMLinearEquationSystem', + #superclass : 'Object', #instVars : [ 'rows', 'solutions' ], - #category : #'Math-Matrix' + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #creation } +{ #category : 'creation' } PMLinearEquationSystem class >> equations: anArrayOfArrays constant: anArray [ ^ self basicNew @@ -33,7 +34,7 @@ PMLinearEquationSystem class >> equations: anArrayOfArrays constant: anArray [ constants: (Array with: anArray) ] -{ #category : #creation } +{ #category : 'creation' } PMLinearEquationSystem class >> equations: anArrayOfArrays constants: anArrayOfConstantArrays [ ^ self basicNew @@ -41,7 +42,7 @@ PMLinearEquationSystem class >> equations: anArrayOfArrays constants: anArrayOfC constants: anArrayOfConstantArrays ] -{ #category : #transformation } +{ #category : 'transformation' } PMLinearEquationSystem >> backSubstitutionAt: anInteger [ "Private - Perform the back-substitution step corresponding to the anInteger-th constant array." | size answer accumulator | @@ -57,7 +58,7 @@ PMLinearEquationSystem >> backSubstitutionAt: anInteger [ solutions at: anInteger put: answer. ] -{ #category : #initialization } +{ #category : 'initialization' } PMLinearEquationSystem >> initialize: anArrayOfArrays constants: anArrayOfConstantArrays [ "Private - Initialize the receiver with system's matrix in anArrayOfArrays and several constants." | n | @@ -66,7 +67,7 @@ PMLinearEquationSystem >> initialize: anArrayOfArrays constants: anArrayOfConsta ^ self ] -{ #category : #information } +{ #category : 'information' } PMLinearEquationSystem >> largestPivotFrom: anInteger [ "Private - Answers the largest pivot element in column anInteger, from position anInteger upward." | valueOfMaximum indexOfMaximum | @@ -82,7 +83,7 @@ PMLinearEquationSystem >> largestPivotFrom: anInteger [ ^ indexOfMaximum ] -{ #category : #transformation } +{ #category : 'transformation' } PMLinearEquationSystem >> pivotAt: anInteger [ "Private - Performs pivot operation with pivot element at anInteger." | inversePivot rowPivotValue row pivotRow | @@ -99,14 +100,14 @@ PMLinearEquationSystem >> pivotAt: anInteger [ ]. ] -{ #category : #transformation } +{ #category : 'transformation' } PMLinearEquationSystem >> pivotStepAt: anInteger [ "Private - Performs an optimum pivot operation at anInteger." self swapRow: anInteger withRow: (self largestPivotFrom: anInteger); pivotAt: anInteger. ] -{ #category : #printing } +{ #category : 'printing' } PMLinearEquationSystem >> printOn: aStream [ "Append to the argument aStream, a sequence of characters that describes the receiver." | delimitingString n k | @@ -128,13 +129,13 @@ PMLinearEquationSystem >> printOn: aStream [ ] -{ #category : #information } +{ #category : 'information' } PMLinearEquationSystem >> solution [ "Answers the solution corresponding to the first constant array." ^ self solutionAt: 1 ] -{ #category : #information } +{ #category : 'information' } PMLinearEquationSystem >> solutionAt: anInteger [ "Answer the solution corresponding to the anInteger-th constant array." @@ -147,14 +148,14 @@ PMLinearEquationSystem >> solutionAt: anInteger [ ^ solutions at: anInteger ] -{ #category : #transformation } +{ #category : 'transformation' } PMLinearEquationSystem >> solve [ "Private - Perform LU decomposition of the system." 1 to: rows size do: [ :n | self pivotStepAt: n ]. solutions := Array new: ((rows at: 1) size - rows size). ] -{ #category : #transformation } +{ #category : 'transformation' } PMLinearEquationSystem >> swapRow: anInteger1 withRow: anInteger2 [ "Private - Swap the rows indexed by the given integers." diff --git a/src/Math-Matrix/PMMatrix.class.st b/src/Math-Matrix/PMMatrix.class.st index 5f72b19..ca1b356 100644 --- a/src/Math-Matrix/PMMatrix.class.st +++ b/src/Math-Matrix/PMMatrix.class.st @@ -9,16 +9,17 @@ I understand the usual matrix operations. " Class { - #name : #PMMatrix, - #superclass : #Object, + #name : 'PMMatrix', + #superclass : 'Object', #instVars : [ 'rows', 'lupDecomposition' ], - #category : #'Math-Matrix' + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #example } +{ #category : 'example' } PMMatrix class >> example [ "" @@ -68,12 +69,12 @@ matrix as following" "15" ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMMatrix class >> identity: dimension [ ^ PMSymmetricMatrix identity: dimension ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMMatrix class >> join: anArrayOfMatrices [ "Inverse of the split operation." | rows n row rowSize n1 n2 | @@ -102,19 +103,19 @@ PMMatrix class >> join: anArrayOfMatrices [ ^self rows: rows ] -{ #category : #information } +{ #category : 'information' } PMMatrix class >> lupCRLCriticalDimension [ ^ 40 ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMMatrix class >> new: dimension [ "Create an empty square matrix of size dimension x dimension." ^ self new initializeSquare: dimension ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMMatrix class >> onesRows: rows cols: columns [ "Creates MxN matrix of ones" @@ -123,20 +124,20 @@ PMMatrix class >> onesRows: rows cols: columns [ ^ self rows: a ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMMatrix class >> rows: anArrayOrVector [ "Create a new matrix with given components." ^ self new initializeRows: anArrayOrVector ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMMatrix class >> rows: rowsInteger columns: columnsInteger [ ^ self new initializeRows: rowsInteger columns: columnsInteger ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMMatrix class >> rows: nRows columns: nCols element: fillElement [ " Answer a new matrix of nRows x nCols initialized with fillElement in all cells " @@ -146,7 +147,7 @@ PMMatrix class >> rows: nRows columns: nCols element: fillElement [ ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMMatrix class >> rows: aNumberOfRows columns: aNumberOfColumns random: aMaxNumber [ ^ self @@ -156,7 +157,7 @@ PMMatrix class >> rows: aNumberOfRows columns: aNumberOfColumns random: aMaxNumb generator: Random new ] -{ #category : #'instance creation' } +{ #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" @@ -166,7 +167,7 @@ PMMatrix class >> rows: aNumberOfRows columns: aNumberOfColumns random: aMaxNumb ^ self rows: rows ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMMatrix class >> zerosRows: rows cols: columns [ "Creates MxN matrix of zeros" @@ -175,56 +176,63 @@ PMMatrix class >> zerosRows: rows cols: columns [ ^ self rows: a ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> * aNumberOrMatrixOrVector [ "Answers the product of the receiver with the argument. The argument can be a number, matrix or vector." ^ aNumberOrMatrixOrVector productWithMatrix: self ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> + aMatrixOrNumber [ "Answers the sum of the receiver with aMatrix." ^ aMatrixOrNumber addWithRegularMatrix: self ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> - aMatrix [ "Answers the difference between the receiver and aMatrix." ^ aMatrix subtractWithRegularMatrix: self ] -{ #category : #operation } +{ #category : 'operating' } +PMMatrix >> -= aColumn [ + "Assume a collection is a matrix of one row" + + self columnWiseSubstractionWith: aColumn +] + +{ #category : 'operation' } PMMatrix >> < aNumber [ "Apply < operator to each element of the matrix" ^ PMMatrix rows: (self rowsCollect: [ :each | each < aNumber ]) ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrix >> = aNumberOrMatrix [ ^ (aNumberOrMatrix species = self species) and: [ self rows = aNumberOrMatrix rows ] ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> > aNumber [ "Apply > operator to each element of the matrix" ^ PMMatrix rows: (self rowsCollect: [ :each | each > aNumber ]) ] -{ #category : #arithmetic } +{ #category : 'arithmetic' } PMMatrix >> abs [ "Computes the element-wise absolute value." ^ self class rows: (rows collect: #abs). ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMMatrix >> adaptToNumber: rcvr andSend: selector [ "selector must obviously be commutative for this simple solution, but at the moment its only used for multiplication" ^ self perform: selector with: rcvr. ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMMatrix >> addWithRegularMatrix: aMatrix [ "Answers the sum of the receiver with aMatrix as a PMMatrix." | n | @@ -237,39 +245,39 @@ PMMatrix >> addWithRegularMatrix: aMatrix [ ^ PMMatrix rows: ( self rowsCollect: [ :each | n := n + 1. each + ( aMatrix rowAt: n)]) ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMMatrix >> addWithSymmetricMatrix: aMatrix [ ^ aMatrix addWithRegularMatrix: self ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> argMaxOnColumns [ ^ self columnsCollect: [ :each | each argMax ] ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> argMaxOnRows [ ^ self rowsCollect: [ :each | each argMax ] ] -{ #category : #transformation } +{ #category : 'transformation' } PMMatrix >> asSymmetricMatrix [ "Convert the receiver to a symmetric matrix (no check is made)." ^ PMSymmetricMatrix rows: rows ] -{ #category : #converting } +{ #category : 'converting' } PMMatrix >> asVector [ ^ self flattenRows. ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> at: aRowIndex at: aColumnIndex [ "Answers the aRowIndex-th, aColumnIndex-th entry in the receiver." ^ self rowAt: aRowIndex columnAt: aColumnIndex ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> at: rowIndex at: columnIndex put: value [ self rowAt: rowIndex columnAt: columnIndex put: value @@ -277,20 +285,20 @@ PMMatrix >> at: rowIndex at: columnIndex put: value [ ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> atAllPut: element [ "Put element at every one of the receiver's cells." self rowsDo: [ : row | row atAllPut: element ] ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> atColumn: aColumnNumber [ ^ self columnAt: aColumnNumber ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> atColumn: aColumnIndex put: aCollection [ aCollection withIndexDo: [: value : rowIndex | @@ -299,7 +307,7 @@ PMMatrix >> atColumn: aColumnIndex put: aCollection [ ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> atColumn: columnIndex put: aValue repeat: repNumber [ " Example: self atColumn: 1 fillWith: 'BM1818' repeat: 3 produces @@ -312,7 +320,7 @@ PMMatrix >> atColumn: columnIndex put: aValue repeat: repNumber [ 1 to: repNumber do: [ : index | self rowAt: index columnAt: columnIndex put: aValue ]. ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> atColumn: aColumnNumber put: aCollection startingAt: rowNumber [ " Fill the receiver with aCollection at aColumnNumber begining at rowNumber. " @@ -326,13 +334,13 @@ PMMatrix >> atColumn: aColumnNumber put: aCollection startingAt: rowNumber [ ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> atRow: aRowNumber [ "answers the aRowNumber-th row in the receiver" ^ self rowAt: aRowNumber ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> atRow: rowIndex put: aCollection [ aCollection withIndexDo: [: value : columnIndex | @@ -341,7 +349,7 @@ PMMatrix >> atRow: rowIndex put: aCollection [ ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> atRow: rowIndex put: aCollection startingAt: startColumnNumber [ "Fill the receiver with aCollection at rowIndex beggining at startColumnNumber. " @@ -356,7 +364,7 @@ PMMatrix >> atRow: rowIndex put: aCollection startingAt: startColumnNumber [ ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> choleskyDecomposition [ | upperTriangular rowSum partialSum diagonalValue nonDiagonalValue factor | @@ -394,36 +402,57 @@ PMMatrix >> choleskyDecomposition [ ^ upperTriangular ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrix >> closeTo: aPMMatrix [ "Tests that we are within the default Float >> #closeTo: precision of aPMMatrix (0.0001)." ^ self closeTo: aPMMatrix precision: 0.0001 ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrix >> closeTo: aPMMatrix precision: aPrecision [ ^ (self - aPMMatrix) abs sum sum < aPrecision ] -{ #category : #iterators } +{ #category : 'iterators' } PMMatrix >> collect: aBlock [ "Applies aBlock elementwise to each cell of the matrix." ^ self class rows: (rows collect: [ :r | r collect: aBlock ]) ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> columnAt: anInteger [ "Answers the anInteger-th column of the receiver." ^ rows collect: [ :each | each at: anInteger ] ] -{ #category : #'cell accessing' } +{ #category : 'information' } +PMMatrix >> columnAverage [ + + ^ (1 to: self numberOfColumns) collect: [ :colIndex | + (self columnAt: colIndex) average ] +] + +{ #category : 'cell accessing' } PMMatrix >> columnVectorAt: col size: dimension [ ^ (self columnAt: col) copyFrom: col to: dimension ] -{ #category : #iterators } +{ #category : 'operating' } +PMMatrix >> columnWiseSubstractionWith: aColumn [ + "Assume a collection is a matrix of one row" + + | result | + result := self class rows: self numberOfRows columns: self numberOfColumns. + + 1 to: self numberOfColumns do: [ :col | + | me | + me := self atColumn: col. + result atColumn: col put: me - (aColumn at: col) ]. + ^ result +] + +{ #category : 'iterators' } PMMatrix >> columnsCollect: aBlock [ "Perform the collect: operation on the rows of the receiver." | n | @@ -431,7 +460,7 @@ PMMatrix >> columnsCollect: aBlock [ ^ rows last collect: [ :each | n := n + 1. aBlock value: (self columnAt: n)] ] -{ #category : #iterators } +{ #category : 'iterators' } PMMatrix >> columnsDo: aBlock [ "Perform the collect: operation on the rows of the receiver." | n | @@ -439,44 +468,44 @@ PMMatrix >> columnsDo: aBlock [ ^ rows last do: [ :each | n := n + 1. aBlock value: ( self columnAt: n)] ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> cos [ "Apply cos to each element of a matrix" ^ PMMatrix rows: (self rowsCollect: [ :each | each cos ]) ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> cosh [ "Apply cosh to each element of a matrix" ^ PMMatrix rows: (self rowsCollect: [ :each | each cosh ]) ] -{ #category : #transformation } +{ #category : 'transformation' } PMMatrix >> cumsum [ "Computes the cumulative sum for each row." ^ PMMatrix rows: (rows collect: [ :each | each cumsum ]) ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> decomposeSV [ ^ PMSingularValueDecomposition decompose: self ] -{ #category : #accessing } +{ #category : 'accessing' } PMMatrix >> determinant [ ^ self lupDecomposition determinant ] -{ #category : #accessing } +{ #category : 'accessing' } PMMatrix >> dimension [ ^ self rows size @ (self rows at: 1) size ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> eigen [ "Computes all eigenvalues and eigenvectors of a matrix. Usage: @@ -488,7 +517,7 @@ PMMatrix >> eigen [ ifFalse: [ self error: 'Eigenvalues and eigenvectors of non-symmetric matrix are currently not supported' ] ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMMatrix >> elementwiseProductWithMatrix: aMatrix [ "Answers the elementwise product between aMatrix and the receiver as a Matrix." | n | @@ -497,7 +526,7 @@ PMMatrix >> elementwiseProductWithMatrix: aMatrix [ ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> equalsTo: aMatrix [ self @@ -507,7 +536,7 @@ PMMatrix >> equalsTo: aMatrix [ ^ self closeTo: aMatrix ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> flattenColumns [ | answer | answer := #(). @@ -515,7 +544,7 @@ PMMatrix >> flattenColumns [ ^ answer asPMVector ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> flattenRows [ | answer | answer := #(). @@ -523,23 +552,23 @@ PMMatrix >> flattenRows [ ^ answer asPMVector ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> hadamardProduct: aMatrix [ ^ aMatrix elementwiseProductWithMatrix: self ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrix >> hash [ ^ rows hash ] -{ #category : #initialization } +{ #category : 'initialization' } PMMatrix >> initializeRows: anArrayOrVector [ "Defines the components of the recevier. No check is made: components are assumed to be orgainized in rows." rows := anArrayOrVector asPMVector collect: [ :each | each asPMVector]. ] -{ #category : #initialization } +{ #category : 'initialization' } PMMatrix >> initializeRows: rowsInteger columns: columnsInteger [ "Build empty components for a matrix." self assert: [ rowsInteger isInteger and: [ rowsInteger > 0 ] ] description: 'Row size of a matrix must be a positive integer'. @@ -547,13 +576,13 @@ PMMatrix >> initializeRows: rowsInteger columns: columnsInteger [ rows := (1 to: rowsInteger) asPMVector collect: [ :each | PMVector new: columnsInteger ]. ] -{ #category : #initialization } +{ #category : 'initialization' } PMMatrix >> initializeSquare: dimension [ "Build empty components for a square matrix. No check is made: components are assumed to be orgainized in rows." ^ self initializeRows: dimension columns: dimension ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> inverse [ "Answer the inverse of the receiver." @@ -562,7 +591,7 @@ PMMatrix >> inverse [ ifFalse: [ self squared inverse * self transpose ] ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> inversePivotColumns: anArray [ "uses vector encoding of an interchange permutation matrix in anArray as in qrFactorizationWithPivoting. Does inverse pivoting!" | res | @@ -571,13 +600,13 @@ PMMatrix >> inversePivotColumns: anArray [ ^ res ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> inversePureCRL [ "Answer the inverse of the receiver." ^ self squared inversePureCRL * self transpose ] -{ #category : #testing } +{ #category : 'testing' } PMMatrix >> isHermitian [ "Hermitian matrix (or self-adjoint matrix) is a complex square matrix that is equal to its own conjugate transpose — that is, the element in the i-th row and j-th column is equal to the complex conjugate of the element in the j-th row and i-th column, for all indices i and j" @@ -591,52 +620,52 @@ PMMatrix >> isHermitian [ ^ true ] -{ #category : #testing } +{ #category : 'testing' } PMMatrix >> isNegativeDefinite [ "A Hermitian matrix is negative definite if and only if all its eigenvalues are strictly negative" self isHermitian ifFalse: [ ^ false ]. ^ self eigen values allSatisfy: [ :each | each < 0 ] ] -{ #category : #testing } +{ #category : 'testing' } PMMatrix >> isNegativeSemiDefinite [ "A Hermitian matrix is negative semi-definite if and only if all its eigenvalues are non-positive" self isHermitian ifFalse: [ ^ false ]. ^ self eigen values allSatisfy: [ :each | each <= 0 ] ] -{ #category : #testing } +{ #category : 'testing' } PMMatrix >> isPositiveDefinite [ "A Hermitian matrix is positive definite if and only if all its eigenvalues are strictly positive" self isHermitian ifFalse: [ ^ false ]. ^ self eigen values allSatisfy: [ :each | each > 0 ] ] -{ #category : #testing } +{ #category : 'testing' } PMMatrix >> isPositiveSemiDefinite [ "A Hermitian matrix is positive semi-definite if and only if all its eigenvalues are non-negative" self isHermitian ifFalse: [ ^ false ]. ^ self eigen values allSatisfy: [ :each | each >= 0 ] ] -{ #category : #testing } +{ #category : 'testing' } PMMatrix >> isReal [ "Answer true if all values of the matrix are real numbers" ^ rows allSatisfy: [ :vector | vector isReal ]. ] -{ #category : #testing } +{ #category : 'testing' } PMMatrix >> isSquare [ "Answers true if the number of rows is equal to the number of columns." ^ rows size = rows last size ] -{ #category : #testing } +{ #category : 'testing' } PMMatrix >> isSymmetric [ ^ self = self transpose ] -{ #category : #private } +{ #category : 'private' } PMMatrix >> largestPowerOf2SmallerThan: anInteger [ "Private" | m m2| @@ -646,14 +675,14 @@ PMMatrix >> largestPowerOf2SmallerThan: anInteger [ ^m ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> log [ "Apply log to each element of a matrix" ^ PMMatrix rows: ( self rowsCollect: [ :each | each log]) ] -{ #category : #accessing } +{ #category : 'accessing' } PMMatrix >> lupDecomposition [ lupDecomposition isNil @@ -661,14 +690,14 @@ PMMatrix >> lupDecomposition [ ^ lupDecomposition ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> lupInverse [ self lupDecomposition inverseMatrixComponents ifNil: [ PMSingularMatrixError new signal ] ifNotNil: [ :i | ^ self class rows: i ] ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> minor: rowIndex and: columnIndex [ ^ PMMatrix rows: @@ -676,7 +705,7 @@ PMMatrix >> minor: rowIndex and: columnIndex [ aRow allButFirst: rowIndex ]) ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> mpInverse [ "Moore Penrose Inverse. " |f g| @@ -690,32 +719,32 @@ PMMatrix >> mpInverse [ ^ g * ((f *self *g) inverse) *f ] -{ #category : #transformation } +{ #category : 'transformation' } PMMatrix >> negate [ "Inverse the sign of all components of the receiver." rows do: [ :each |each negate ] ] -{ #category : #accessing } +{ #category : 'accessing' } PMMatrix >> numberOfColumns [ "Answer the number of rows of the receiver." ^ rows last size ] -{ #category : #accessing } +{ #category : 'accessing' } PMMatrix >> numberOfRows [ "Answer the number of rows of the receiver." ^ rows size ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> orthogonalize [ "returns an orthonormal basis of column (!) vectors for a matrix of column vectors" ^ self qrFactorizationWithPivoting first ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> principalDiagonal [ "https://en.wikipedia.org/wiki/Diagonal#Matrices for definitions" | diag | @@ -726,7 +755,7 @@ PMMatrix >> principalDiagonal [ ^ diag ] -{ #category : #printing } +{ #category : 'printing' } PMMatrix >> printOn: aStream [ (rows isNil or: [rows first isNil]) ifTrue: [ super printOn: aStream. @@ -738,18 +767,18 @@ PMMatrix >> printOn: aStream [ ] -{ #category : #private } +{ #category : 'private' } PMMatrix >> privateTranspose [ ^ self transpose ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMMatrix >> productWithMatrix: aMatrix [ "Answers the product of aMatrix with the receiver (in this order)." ^ self productWithMatrixFinal: aMatrix ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMMatrix >> productWithMatrixFinal: aMatrix [ "Answers the product of aMatrix with the receiver (in this order)." "speed optimized" @@ -758,25 +787,25 @@ PMMatrix >> productWithMatrixFinal: aMatrix [ ^ PMMatrix rows: ( aMatrix rowsCollect: [ :row | t rowsCollect: [ :col | row * col]]) ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMMatrix >> productWithTransposeMatrix: aMatrix [ "Answers the product of the receiver with the transpose of aMatrix(in this order)." ^ PMMatrix rows: (self rowsCollect: [ :row | aMatrix rowsCollect: [ :col | row * col]]) ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMMatrix >> productWithVector: aVector [ "Answers the product of the receiver with aVector" ^ self columnsCollect: [ :each | each * aVector ] ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> qrFactorization [ ^ (PMQRDecomposition of: self) decompose ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> qrFactorizationWithPivoting [ | identMat q r hh colSize i lengthArray rank mx pivot | @@ -836,7 +865,7 @@ PMMatrix >> qrFactorizationWithPivoting [ ^ Array with: q with: r with: pivot ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> raisedTo: aPower [ " Answers the receiver raised to a power, aPower . @@ -857,61 +886,61 @@ PMMatrix >> raisedTo: aPower [ ^ aRaisedPMMatrix ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> rank [ ^ ((self numberOfRows < self numberOfColumns ifTrue: [ self transpose ] ifFalse: [ self ]) qrFactorizationWithPivoting at: 2) rows size ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> rowAt: anInteger [ "Answers the anInteger-th row of the receiver." ^ rows at: anInteger ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> rowAt: aRowIndex columnAt: aColumnIndex [ "Answers the aRowIndex-th, aColumnIndex-th entry in the receiver." ^ (rows at: aRowIndex) at: aColumnIndex ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> rowAt: aRowIndex columnAt: aColumnIndex put: aValue [ ^(rows at: aRowIndex) at: aColumnIndex put: aValue ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> rows [ ^rows ] -{ #category : #iterators } +{ #category : 'iterators' } PMMatrix >> rowsCollect: aBlock [ "Perform the collect: operation on the rows of the receiver." ^ rows collect: aBlock ] -{ #category : #iterators } +{ #category : 'iterators' } PMMatrix >> rowsDo: aBlock [ "Perform the collect: operation on the rows of the receiver." ^ rows do: aBlock ] -{ #category : #iterators } +{ #category : 'iterators' } PMMatrix >> rowsWithIndexDo: aBlock [ ^ rows withIndexDo: aBlock ] -{ #category : #transformation } +{ #category : 'transformation' } PMMatrix >> scaleBy: aNumber [ rows do: [ :each | each scaleBy: aNumber ] ] -{ #category : #'cell accessing' } +{ #category : 'cell accessing' } PMMatrix >> setDiagonal: aVector [ | n m | @@ -927,33 +956,33 @@ PMMatrix >> setDiagonal: aVector [ ^self ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> sign [ "Apply sign to each element of a matrix" ^ PMMatrix rows: (self rowsCollect: [ :each | each sign ]) ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> sin [ "Apply sin to each element of a matrix" ^ PMMatrix rows: (self rowsCollect: [ :each | each sin ]) ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> sinh [ "Apply sinh to each element of a matrix" ^ PMMatrix rows: (self rowsCollect: [ :each | each sinh ]) ] -{ #category : #private } +{ #category : 'private' } PMMatrix >> species [ ^ PMMatrix ] -{ #category : #private } +{ #category : 'private' } PMMatrix >> split [ "Private - Answers an array of 4 matrices split from the receiver." | n m n1 m1 | @@ -968,14 +997,14 @@ PMMatrix >> split [ with:( self class rows: ( ( (n1 + 1) to: n) asPMVector collect: [ :k | ( rows at: k) copyFrom: (m1 + 1) to: m])) ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> sqrt [ "Apply sqrt to each element of a matrix" ^ PMMatrix rows: ( self rowsCollect: [ :each | each sqrt]) ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> squared [ | transposed | transposed :=self privateTranspose. @@ -985,7 +1014,7 @@ PMMatrix >> squared [ ] -{ #category : #private } +{ #category : 'private' } PMMatrix >> strassenProductWithMatrix: aMatrix [ "Private" | matrixSplit selfSplit p1 p2 p3 p4 p5 p6 p7 | @@ -1013,7 +1042,7 @@ PMMatrix >> strassenProductWithMatrix: aMatrix [ ) ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMMatrix >> subtractWithRegularMatrix: aMatrix [ "Answers the difference between aMatrix and the receiver as a Matrix." | n | @@ -1021,13 +1050,13 @@ PMMatrix >> subtractWithRegularMatrix: aMatrix [ ^ PMMatrix rows: ( aMatrix rowsCollect: [ :each | n := n + 1. each - ( self rowAt: n)]) ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMMatrix >> subtractWithSymmetricMatrix: aMatrix [ "Answers the difference between aMatrix and the receiver." ^ self subtractWithRegularMatrix: aMatrix ] -{ #category : #transformation } +{ #category : 'transformation' } PMMatrix >> sum [ "Computes the row sum." @@ -1037,13 +1066,13 @@ PMMatrix >> sum [ ^ a ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMMatrix >> swapColumn: anIndex withColumn: a2Index [ self rowsDo: [ :r| r swap: anIndex with: a2Index ] ] -{ #category : #arithmetic } +{ #category : 'arithmetic' } PMMatrix >> take: anInteger [ " Answer a with the receiver's binomial coefficient at each element for anInteger " @@ -1051,21 +1080,21 @@ PMMatrix >> take: anInteger [ ^ self collect: [ :each | each numberOfCombinationsTaken: anInteger ] ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> tan [ "Apply tan to each element of a matrix" ^ PMMatrix rows: (self rowsCollect: [ :each | each tan ]) ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> tanh [ "Apply tanh to each element of a matrix" ^ PMMatrix rows: (self rowsCollect: [ :each | each tanh ]) ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> tr [ "Return the trace or sum along diagonals of the array." "https://en.wikipedia.org/wiki/Trace_(linear_algebra)" @@ -1076,13 +1105,13 @@ PMMatrix >> tr [ ^ result ] -{ #category : #operation } +{ #category : 'operation' } PMMatrix >> transpose [ "Answer a new matrix, transpose of the receiver." ^ self class rows: ( self columnsCollect: [ :each | each]) ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMMatrix >> transposeProductWithMatrix: aMatrix [ "Answers the product of the transpose of the receiver with aMatrix (in this order)." "speed optimized" diff --git a/src/Math-Matrix/PMNDArray.class.st b/src/Math-Matrix/PMNDArray.class.st index bf53739..d683e82 100644 --- a/src/Math-Matrix/PMNDArray.class.st +++ b/src/Math-Matrix/PMNDArray.class.st @@ -1,34 +1,35 @@ Class { - #name : #PMNDArray, - #superclass : #Object, + #name : 'PMNDArray', + #superclass : 'Object', #instVars : [ 'array', 'shape', 'first', 'strides' ], - #category : #'Math-Matrix' + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMNDArray class >> fromNestedArray: anArray [ ^ self new array: anArray flattened withShape: (self shape:anArray) ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMNDArray class >> fromScalar: anInteger [ ^ self new array: {anInteger} withShape: #( ) ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMNDArray class >> newWith: anInteger [ ^ self new array: {anInteger} withShape: #( ) ] -{ #category : #accessing } +{ #category : 'accessing' } PMNDArray class >> shape: anArray [ anArray isArray ifFalse:[^#()] @@ -38,14 +39,14 @@ ifTrue:[ ] -{ #category : #comparing } +{ #category : 'comparing' } PMNDArray >> = aPMNDArray [ ^ array = aPMNDArray asArray & (first = aPMNDArray first) & (strides = aPMNDArray strides) & (shape = aPMNDArray shape) ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMNDArray >> array: aFlatArray withShape: aShape [ array := aFlatArray. @@ -54,12 +55,12 @@ PMNDArray >> array: aFlatArray withShape: aShape [ shape ifNotEmpty: [ self updateStrides] ] -{ #category : #private } +{ #category : 'private' } PMNDArray >> asArray [ ^array ] -{ #category : #public } +{ #category : 'public' } PMNDArray >> at: coords [ | position | @@ -67,18 +68,18 @@ PMNDArray >> at: coords [ ^ array at: position ] -{ #category : #initialization } +{ #category : 'initialization' } PMNDArray >> at: coords put: aValue [ array at: (self flattenedIndexOf: coords) put: aValue ] -{ #category : #accessing } +{ #category : 'accessing' } PMNDArray >> first [ ^first ] -{ #category : #'primitives - file' } +{ #category : 'primitives - file' } PMNDArray >> flattenedIndexOf: coords [ | position | @@ -88,7 +89,7 @@ PMNDArray >> flattenedIndexOf: coords [ ^ position ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMNDArray >> fromNestedArray: aFlatArray withShape: aShape [ array := aFlatArray. @@ -97,55 +98,55 @@ PMNDArray >> fromNestedArray: aFlatArray withShape: aShape [ shape ifNotEmpty: [ self updateStrides] ] -{ #category : #operation } +{ #category : 'operation' } PMNDArray >> hadamardProduct: aPMNDArray [ ^ self with: aPMNDArray collect: [:a :b| a*b] ] -{ #category : #testing } +{ #category : 'testing' } PMNDArray >> hasSameShapeAs: aPMNDArray [ ^ self shape = aPMNDArray shape ] -{ #category : #accessing } +{ #category : 'accessing' } PMNDArray >> rank [ ^ shape size ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMNDArray >> reshape: aNewShape [ ^ self viewWithShape: aNewShape. ] -{ #category : #accessing } +{ #category : 'accessing' } PMNDArray >> shape [ ^ shape ] -{ #category : #accessing } +{ #category : 'accessing' } PMNDArray >> size [ ^ shape inject: 1 into: [ :each :product | each * product]. ] -{ #category : #accessing } +{ #category : 'accessing' } PMNDArray >> strides [ ^strides ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMNDArray >> updateFirst [ first := Array new: shape size withAll: 1 ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMNDArray >> updateStrides [ strides := Array new: shape size. @@ -154,7 +155,7 @@ PMNDArray >> updateStrides [ strides at: i put: ((strides at: i + 1) * (shape at: i+1))] ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMNDArray >> view [ "Share only the array" @@ -162,14 +163,14 @@ PMNDArray >> view [ ^ self viewWithShape: shape ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMNDArray >> viewWithShape: aNewShape [ ^ PMNDArray new array: self asArray withShape: aNewShape ] -{ #category : #operation } +{ #category : 'operation' } PMNDArray >> with: aPMNDArray collect: aBlock [ (self hasSameShapeAs: aPMNDArray) ifFalse:[ShapeMismatch signal ]. diff --git a/src/Math-Matrix/PMQRDecomposition.class.st b/src/Math-Matrix/PMQRDecomposition.class.st index e61ad9e..b361301 100644 --- a/src/Math-Matrix/PMQRDecomposition.class.st +++ b/src/Math-Matrix/PMQRDecomposition.class.st @@ -2,25 +2,26 @@ I am responsible for the decomposition of a matrix, A say, into a product A = QR of an orthogonal matrix Q and an upper triangular matrix R " Class { - #name : #PMQRDecomposition, - #superclass : #Object, + #name : 'PMQRDecomposition', + #superclass : 'Object', #instVars : [ 'matrixToDecompose', 'colSize', 'r', 'q' ], - #category : #'Math-Matrix' + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMQRDecomposition class >> of: matrix [ matrix numberOfRows < matrix numberOfColumns ifTrue: [ self error: 'numberOfRows> decompose [ " The method appears to be using Householder reflection. There is a wiki page @@ -57,7 +58,7 @@ https://en.wikipedia.org/wiki/QR_decomposition#Using_Householder_reflections ^ Array with: q with: r ] -{ #category : #arithmetic } +{ #category : 'arithmetic' } PMQRDecomposition >> decomposeWithPivot [ | i vectorOfNormSquareds rank positionOfMaximum pivot matrixOfMinor | @@ -127,7 +128,7 @@ PMQRDecomposition >> decomposeWithPivot [ ^ Array with: q with: r with: pivot ] -{ #category : #private } +{ #category : 'private' } PMQRDecomposition >> householderReflectionOf: columnVector atColumnNumber: columnNumber [ | householderVector v identityMatrix householderMatrix | @@ -140,25 +141,25 @@ PMQRDecomposition >> householderReflectionOf: columnVector atColumnNumber: colum ^ Array with: householderVector with: householderMatrix . ] -{ #category : #private } +{ #category : 'private' } PMQRDecomposition >> initialQMatrix [ ^ PMSymmetricMatrix identity: colSize ] -{ #category : #private } +{ #category : 'private' } PMQRDecomposition >> initialRMatrix [ ^ PMMatrix rows: matrixToDecompose rows deepCopy ] -{ #category : #private } +{ #category : 'private' } PMQRDecomposition >> numberOfColumns [ ^ matrixToDecompose numberOfColumns ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMQRDecomposition >> of: matrix [ matrixToDecompose := matrix. @@ -167,7 +168,7 @@ PMQRDecomposition >> of: matrix [ q := self initialQMatrix. ] -{ #category : #private } +{ #category : 'private' } PMQRDecomposition >> upperTriangularPartOf: matrix With: columnSize [ ^ PMMatrix rows: (r rows copyFrom: 1 to: columnSize) diff --git a/src/Math-Matrix/PMSingularMatrixError.class.st b/src/Math-Matrix/PMSingularMatrixError.class.st index 6aa9392..66bcb06 100644 --- a/src/Math-Matrix/PMSingularMatrixError.class.st +++ b/src/Math-Matrix/PMSingularMatrixError.class.st @@ -3,18 +3,19 @@ some calculations dont work with singular matrices and result eg with errors lik " Class { - #name : #PMSingularMatrixError, - #superclass : #ArithmeticError, - #category : #'Math-Matrix' + #name : 'PMSingularMatrixError', + #superclass : 'ArithmeticError', + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #accessing } +{ #category : 'accessing' } PMSingularMatrixError >> messageText [ "Overwritten to initialize the message text to a standard text if it has not yet been set" ^ messageText ifNil: [ messageText := self standardMessageText ] ] -{ #category : #printing } +{ #category : 'printing' } PMSingularMatrixError >> standardMessageText [ ^ String streamContents: [ :stream | stream << (self signalerContext asString findTokens: '>')last. diff --git a/src/Math-Matrix/PMSingularValueDecomposition.class.st b/src/Math-Matrix/PMSingularValueDecomposition.class.st index e30eb85..50a740a 100644 --- a/src/Math-Matrix/PMSingularValueDecomposition.class.st +++ b/src/Math-Matrix/PMSingularValueDecomposition.class.st @@ -29,29 +29,30 @@ s := svd sForm. " Class { - #name : #PMSingularValueDecomposition, - #superclass : #Object, + #name : 'PMSingularValueDecomposition', + #superclass : 'Object', #instVars : [ 'diagonalSingularValueMatrix', 'leftSingularMatrix', 'rightSingularMatrix' ], - #category : #'Math-Matrix' + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMSingularValueDecomposition class >> decompose: aMatrix [ ^ self new initialize: aMatrix ] -{ #category : #accessing } +{ #category : 'accessing' } PMSingularValueDecomposition >> diagonalSingularValueMatrix [ "Diagonal matrix S in A = USV decomposition. All elements are 0 except those on the main diagonal. The values on the diagonal are singular values of matrix A. By convention, they are sorted in descending order" ^ diagonalSingularValueMatrix ] -{ #category : #initialization } +{ #category : 'initialization' } PMSingularValueDecomposition >> initialize: aMatrix [ | m n symU symV eigenU eigenV diag | @@ -72,7 +73,7 @@ PMSingularValueDecomposition >> initialize: aMatrix [ diagonalSingularValueMatrix setDiagonal: diag sqrt ] -{ #category : #accessing } +{ #category : 'accessing' } PMSingularValueDecomposition >> leftSingularForm [ self @@ -82,14 +83,14 @@ PMSingularValueDecomposition >> leftSingularForm [ ^ leftSingularMatrix ] -{ #category : #accessing } +{ #category : 'accessing' } PMSingularValueDecomposition >> leftSingularMatrix [ "Matrix U in the A = USV decomposition. The columns of this matrix are the eigenvectors of the A * (A transposed) matrix (called left singular vectors). The columns of this matrix are orthonormal" ^ leftSingularMatrix ] -{ #category : #accessing } +{ #category : 'accessing' } PMSingularValueDecomposition >> rightSingularForm [ self @@ -99,14 +100,14 @@ PMSingularValueDecomposition >> rightSingularForm [ ^ rightSingularMatrix ] -{ #category : #accessing } +{ #category : 'accessing' } PMSingularValueDecomposition >> rightSingularMatrix [ "Matrix V in the A = USV decomposition. The columns of this matrix are the eigenvectors of the (A transposed) * A matrix (called right singular vectors). The columns of this matrix are orthonormal" ^ rightSingularMatrix ] -{ #category : #accessing } +{ #category : 'accessing' } PMSingularValueDecomposition >> sForm [ self diff --git a/src/Math-Matrix/PMSymmetricMatrix.class.st b/src/Math-Matrix/PMSymmetricMatrix.class.st index c14624e..2436dbc 100644 --- a/src/Math-Matrix/PMSymmetricMatrix.class.st +++ b/src/Math-Matrix/PMSymmetricMatrix.class.st @@ -2,18 +2,19 @@ This class can be instantiated like PMMatrix via #rows:, but the user has to make sure that this matrix is indeed symmetric as this is not internally checked for speed reasons. " Class { - #name : #PMSymmetricMatrix, - #superclass : #PMMatrix, - #category : #'Math-Matrix' + #name : 'PMSymmetricMatrix', + #superclass : 'PMMatrix', + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMSymmetricMatrix class >> identity: anInteger [ "Create an identity matrix of dimension anInteger" ^self new initializeIdentity: anInteger ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMSymmetricMatrix class >> join: anArrayOfMatrices [ "Inverse of the split operation" | rows n | @@ -33,12 +34,12 @@ PMSymmetricMatrix class >> join: anArrayOfMatrices [ ^self rows: rows ] -{ #category : #information } +{ #category : 'information' } PMSymmetricMatrix class >> lupCRLCriticalDimension [ ^36 ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMSymmetricMatrix class >> new: dim function: aBlock [ "Answer a new symmetric matrix with dimensions dim filled with aBlock value: RowposRespectivelyColpos value: ColposRespectivelyRowpos" @@ -55,13 +56,13 @@ aBlock value: RowposRespectivelyColpos value: ColposRespectivelyRowpos" ^a ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMSymmetricMatrix class >> new: dim random: aMaxNumber [ ^ self new: dim random: aMaxNumber generator: Random new ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMSymmetricMatrix class >> new: dim random: aMaxNumber generator: generator [ "Answer a new symmetric matrix of the given dimensions filled with random numbers" @@ -79,24 +80,24 @@ PMSymmetricMatrix class >> new: dim random: aMaxNumber generator: generator [ ^ matrix ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMSymmetricMatrix class >> rows: rows columns: columns random: aMaxNumber [ ^ self shouldNotImplement ] -{ #category : #operation } +{ #category : 'operation' } PMSymmetricMatrix >> + aMatrix [ "Answers the sum of the receiver with aMatrix." ^ aMatrix addWithSymmetricMatrix: self ] -{ #category : #operation } +{ #category : 'operation' } PMSymmetricMatrix >> - aMatrix [ "Answers the difference between the receiver and aMatrix" ^ aMatrix subtractWithSymmetricMatrix: self ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMSymmetricMatrix >> addWithSymmetricMatrix: aMatrix [ ^self class new: aMatrix numberOfRows @@ -104,51 +105,51 @@ PMSymmetricMatrix >> addWithSymmetricMatrix: aMatrix [ ] -{ #category : #transformation } +{ #category : 'transformation' } PMSymmetricMatrix >> asSymmetricMatrix [ "simple speed up" ^ self ] -{ #category : #information } +{ #category : 'information' } PMSymmetricMatrix >> atColumn: aColumnIndex put: aCollection [ self shouldNotImplement ] -{ #category : #information } +{ #category : 'information' } PMSymmetricMatrix >> atRow: aRowIndex put: aCollection [ self shouldNotImplement ] -{ #category : #initialization } +{ #category : 'initialization' } PMSymmetricMatrix >> basicInitialize: anInteger [ "private" rows := PMVector new: anInteger. ] -{ #category : #initialization } +{ #category : 'initialization' } PMSymmetricMatrix >> clear [ rows do: [ :each | each atAllPut: 0]. ] -{ #category : #information } +{ #category : 'information' } PMSymmetricMatrix >> columnAt: anInteger [ ^ rows at: anInteger ] -{ #category : #iterators } +{ #category : 'iterators' } PMSymmetricMatrix >> columnsCollect: aBlock [ ^ rows collect: aBlock ] -{ #category : #iterators } +{ #category : 'iterators' } PMSymmetricMatrix >> columnsDo: aBlock [ ^ rows do: aBlock ] -{ #category : #operation } +{ #category : 'operation' } PMSymmetricMatrix >> crlInverse [ "corrected sequence of calcs; s1in matrices at:2 has to be calced first (split returns matrices in this order: b, d, c). and taken care of degenerate cases (which is unnecessary, if this method is not called outside of inverse)" @@ -168,7 +169,7 @@ and taken care of degenerate cases (which is unnecessary, if this method is not ^ self class join: matrices ] -{ #category : #operation } +{ #category : 'operation' } PMSymmetricMatrix >> eigen [ "Computes all eigenvalues and eigenvectors for symmetric matrix using Jacobi transformation Usage: @@ -178,13 +179,13 @@ PMSymmetricMatrix >> eigen [ ^ PMJacobiTransformationHelper matrix: self. ] -{ #category : #initialization } +{ #category : 'initialization' } PMSymmetricMatrix >> initializeIdentity: anInteger [ "Build components for an identity matrix." rows := ( 1 to: anInteger) asPMVector collect: [ :n | (PMVector new: anInteger) atAllPut: 0; at: n put: 1; yourself]. ] -{ #category : #operation } +{ #category : 'operation' } PMSymmetricMatrix >> inverse [ "Answer the inverse of the receiver" @@ -193,13 +194,13 @@ PMSymmetricMatrix >> inverse [ ifFalse: [ self crlInverse ] ] -{ #category : #operation } +{ #category : 'operation' } PMSymmetricMatrix >> inverse1By1 [ "Private - Answer the inverse of the receiver when it is a 1x1 matrix (no check is made)." ^ self class rows: ( PMVector with: ( PMVector with: ( 1/ ((rows at: 1) at: 1)))) ] -{ #category : #operation } +{ #category : 'operation' } PMSymmetricMatrix >> inverse2By2 [ "Private - Answer the inverse of the receiver when it is a 2x2 matrix (no check is made)." | line1 line2 | @@ -208,7 +209,7 @@ PMSymmetricMatrix >> inverse2By2 [ ^self class rows: ( PMVector with: line1 with: line2) * (1 / (((rows at: 1) at: 1) * ((rows at: 2) at: 2) - ((rows at: 1) at: 2) squared)) ] -{ #category : #operation } +{ #category : 'operation' } PMSymmetricMatrix >> inversePureCRL [ "Answer the inverse of the receiver." | matrices b1 cb1 cb1ct | @@ -227,7 +228,7 @@ PMSymmetricMatrix >> inversePureCRL [ ^ self class join: matrices ] -{ #category : #operation } +{ #category : 'operation' } PMSymmetricMatrix >> inversePureLUP [ "Answer the inverse of the receiver." @@ -237,36 +238,36 @@ PMSymmetricMatrix >> inversePureLUP [ ifNotNil: [ :i | ^ self class rows: i ] ] -{ #category : #testing } +{ #category : 'testing' } PMSymmetricMatrix >> isHermitian [ "Every real symmetric matrix is Hermitian" ^ self isReal ] -{ #category : #testing } +{ #category : 'testing' } PMSymmetricMatrix >> isSquare [ "Answers true because a symmetric matrix is square." ^true ] -{ #category : #testing } +{ #category : 'testing' } PMSymmetricMatrix >> isSymmetric [ "Answers true because the receiver is a symmetric matrix" ^true ] -{ #category : #information } +{ #category : 'information' } PMSymmetricMatrix >> numberOfColumns [ "Answer the number of columns of the receiver." ^rows size ] -{ #category : #'private ' } +{ #category : 'private' } PMSymmetricMatrix >> privateTranspose [ ^ self ] -{ #category : #transformation } +{ #category : 'transformation' } PMSymmetricMatrix >> split [ "Private - Answers an array of 3 matrices split from the receiver" @@ -282,14 +283,14 @@ PMSymmetricMatrix >> split [ copyFrom: 1 to: n])) ] -{ #category : #'double dispatching' } +{ #category : 'double dispatching' } PMSymmetricMatrix >> subtractWithSymmetricMatrix: aMatrix [ ^ self class new: aMatrix numberOfRows function: [ :x :y|((aMatrix rows at:x)at:y)-(( rows at:x)at:y) ] ] -{ #category : #information } +{ #category : 'information' } PMSymmetricMatrix >> transpose [ "Answer a new matrix, transpose of the receiver. optimized" ^self deepCopy diff --git a/src/Math-Matrix/PMVector.extension.st b/src/Math-Matrix/PMVector.extension.st index bd43674..a65fbd6 100644 --- a/src/Math-Matrix/PMVector.extension.st +++ b/src/Math-Matrix/PMVector.extension.st @@ -1,6 +1,6 @@ -Extension { #name : #PMVector } +Extension { #name : 'PMVector' } -{ #category : #'*Math-Matrix' } +{ #category : '*Math-Matrix' } PMVector >> productWithMatrix: aMatrix [ "Answers the product of aMatrix with the receiver." @@ -8,7 +8,7 @@ PMVector >> productWithMatrix: aMatrix [ ^ aMatrix rowsCollect: [ :each | each * self ] ] -{ #category : #'*Math-Matrix' } +{ #category : '*Math-Matrix' } PMVector >> reshapeWithDimensions: dimensionArray [ | computedRows rowNum colNum | @@ -20,7 +20,7 @@ PMVector >> reshapeWithDimensions: dimensionArray [ ^ PMMatrix rows: computedRows ] -{ #category : #'*Math-Matrix' } +{ #category : '*Math-Matrix' } PMVector >> tensorProduct: aVector [ "Answers the tensor product of the receiver with aVector." ^self == aVector "dont use #=" diff --git a/src/Math-Matrix/ShapeMismatch.class.st b/src/Math-Matrix/ShapeMismatch.class.st index a79537b..bb81cf3 100644 --- a/src/Math-Matrix/ShapeMismatch.class.st +++ b/src/Math-Matrix/ShapeMismatch.class.st @@ -1,17 +1,18 @@ Class { - #name : #ShapeMismatch, - #superclass : #Error, - #category : #'Math-Matrix' + #name : 'ShapeMismatch', + #superclass : 'Error', + #category : 'Math-Matrix', + #package : 'Math-Matrix' } -{ #category : #accessing } +{ #category : 'accessing' } ShapeMismatch >> messageText [ "Overwritten to initialiaze the message text to a standard text if it has not yet been set" ^ messageText ifNil: [ messageText := self standardMessageText ] ] -{ #category : #printing } +{ #category : 'printing' } ShapeMismatch >> standardMessageText [ "Generate a standard textual description" diff --git a/src/Math-Matrix/package.st b/src/Math-Matrix/package.st index 206c13a..333900b 100644 --- a/src/Math-Matrix/package.st +++ b/src/Math-Matrix/package.st @@ -1 +1 @@ -Package { #name : #'Math-Matrix' } +Package { #name : 'Math-Matrix' } From a183aae226f368aca06e6f90b3d5b2b8cd10db5f Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Tue, 17 Feb 2026 11:47:51 +0100 Subject: [PATCH 2/7] Wrote tests for added methods --- .../PMAdditionalTest.class.st | 13 +- .../PMJacobiTransformationTest.class.st | 11 +- src/Math-Matrix-Tests/PMMatrixTest.class.st | 179 ++++++++++-------- src/Math-Matrix-Tests/PMNDArrayTest.class.st | 37 ++-- src/Math-Matrix-Tests/PMQRTest.class.st | 33 ++-- src/Math-Matrix-Tests/PMRestTest.class.st | 13 +- .../PMSingularValueDecompositionTest.class.st | 45 ++--- .../PMSymmetricMatrixTest.class.st | 15 +- src/Math-Matrix-Tests/package.st | 2 +- 9 files changed, 188 insertions(+), 160 deletions(-) diff --git a/src/Math-Matrix-Tests/PMAdditionalTest.class.st b/src/Math-Matrix-Tests/PMAdditionalTest.class.st index 5d48ddd..d9f4bc1 100644 --- a/src/Math-Matrix-Tests/PMAdditionalTest.class.st +++ b/src/Math-Matrix-Tests/PMAdditionalTest.class.st @@ -3,12 +3,13 @@ here are tests that would be in Math-Tests-DHB-Numerical, if it could construct " Class { - #name : #PMAdditionalTest, - #superclass : #TestCase, - #category : #'Math-Matrix-Tests' + #name : 'PMAdditionalTest', + #superclass : 'TestCase', + #category : 'Math-Matrix-Tests', + #package : 'Math-Matrix-Tests' } -{ #category : #tests } +{ #category : 'tests' } PMAdditionalTest >> testMatrixInversionSmall [ "it is here since it uses random matrices" @@ -38,7 +39,7 @@ PMAdditionalTest >> testMatrixInversionSmall [ self assert: i class equals: PMMatrix ] ] -{ #category : #tests } +{ #category : 'tests' } PMAdditionalTest >> testMatrixSquared [ "this tests squared and is not in Math-Tests-Numerical since it uses random matrices" @@ -53,7 +54,7 @@ PMAdditionalTest >> testMatrixSquared [ self assert: a squared class equals: PMSymmetricMatrix ] -{ #category : #tests } +{ #category : 'tests' } PMAdditionalTest >> testTensorProduct [ "this tests if a tensor product of two vectors is calculated correctly" diff --git a/src/Math-Matrix-Tests/PMJacobiTransformationTest.class.st b/src/Math-Matrix-Tests/PMJacobiTransformationTest.class.st index 5b1a60c..1dd7726 100644 --- a/src/Math-Matrix-Tests/PMJacobiTransformationTest.class.st +++ b/src/Math-Matrix-Tests/PMJacobiTransformationTest.class.st @@ -1,10 +1,11 @@ Class { - #name : #PMJacobiTransformationTest, - #superclass : #TestCase, - #category : #'Math-Matrix-Tests' + #name : 'PMJacobiTransformationTest', + #superclass : 'TestCase', + #category : 'Math-Matrix-Tests', + #package : 'Math-Matrix-Tests' } -{ #category : #tests } +{ #category : 'tests' } PMJacobiTransformationTest >> testEigenvalueOfIdentityMatrixIsOne [ "The eigenvalue of I is 1" @@ -17,7 +18,7 @@ PMJacobiTransformationTest >> testEigenvalueOfIdentityMatrixIsOne [ self assert: jacobiTransformation evaluate equals: expected ] -{ #category : #tests } +{ #category : 'tests' } PMJacobiTransformationTest >> testEigenvectorsOfIdentityMatrixAreTheUnitVectors [ "The eigenvectors of I are (1 0) and (0 1), the unit basis vectors" diff --git a/src/Math-Matrix-Tests/PMMatrixTest.class.st b/src/Math-Matrix-Tests/PMMatrixTest.class.st index 6c22fbd..70a7a54 100644 --- a/src/Math-Matrix-Tests/PMMatrixTest.class.st +++ b/src/Math-Matrix-Tests/PMMatrixTest.class.st @@ -1,10 +1,11 @@ Class { - #name : #PMMatrixTest, - #superclass : #TestCase, - #category : #'Math-Matrix-Tests' + #name : 'PMMatrixTest', + #superclass : 'TestCase', + #category : 'Math-Matrix-Tests', + #package : 'Math-Matrix-Tests' } -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testArgMaxOnColumns [ | m1 m2 | m1 := PMMatrix rows: #(#(0 1 2) #(3 4 5)). @@ -13,7 +14,7 @@ PMMatrixTest >> testArgMaxOnColumns [ self assert: m2 argMaxOnColumns equals: #(1 1 2) asPMVector ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testArgMaxOnRows [ | m1 m2 | m1 := PMMatrix rows: #(#(0 1 2) #(3 4 5)). @@ -22,7 +23,7 @@ PMMatrixTest >> testArgMaxOnRows [ self assert: m2 argMaxOnRows equals: #(2 2) asPMVector. ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testAtAllPut [ | a | @@ -32,7 +33,7 @@ PMMatrixTest >> testAtAllPut [ ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testAtColumnPutRepeat [ | a | @@ -48,7 +49,7 @@ PMMatrixTest >> testAtColumnPutRepeat [ self assert: a equals: (PMMatrix rows: #(#(1 nil nil) #(1 nil nil) #(nil nil nil))). ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testAtRow [ | a | @@ -58,7 +59,7 @@ PMMatrixTest >> testAtRow [ self assert: (a atRow: 1) equals: (#(1 2 3) asPMVector). ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testAtRowPutAtColumnPut [ | a | a := PMMatrix rows: #(#(11 12 13) #(21 22 23)). @@ -71,7 +72,7 @@ PMMatrixTest >> testAtRowPutAtColumnPut [ self should: [ a atColumn: 1 put: (a rowAt: 2) ] raise: Error ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testCholeskyDecomposition [ | matrix upperTriangular expected | @@ -94,7 +95,7 @@ PMMatrixTest >> testCholeskyDecomposition [ self assert: upperTriangular equals: expected. ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testCholeskyDecompositionIsDecomposition [ | matrix upperTriangular | @@ -110,7 +111,7 @@ PMMatrixTest >> testCholeskyDecompositionIsDecomposition [ closeTo: matrix. ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testCholeskyDecompositionNonSquare [ | matrix | @@ -121,7 +122,7 @@ PMMatrixTest >> testCholeskyDecompositionNonSquare [ self should: [ matrix choleskyDecomposition ] raise: Error. ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testCholeskyDecompositionNonSymmetric [ | matrix | @@ -133,19 +134,39 @@ PMMatrixTest >> testCholeskyDecompositionNonSymmetric [ self should: [ matrix choleskyDecomposition ] raise: Error. ] -{ #category : #collection } +{ #category : 'collection' } PMMatrixTest >> testCollect [ self assert: ((PMMatrix rows: #((1 2) (3 4))) collect: [ :x | 2 * x ]) equals: (PMMatrix rows: #((2 4) ( 6 8))) ] -{ #category : #'linear algebra' } +{ #category : 'tests' } +PMMatrixTest >> testColumnAverage [ + + | matrix | + matrix := PMMatrix rows: #( #( 1 2 3 ) #( 5 6 7 ) ). + + self assert: matrix columnAverage equals: #( 3 4 5 ) +] + +{ #category : 'tests' } +PMMatrixTest >> testColumnWiseSubstractionWith [ + + | matrix vector expected | + matrix := PMMatrix rows: #( #( 1 2 3 ) #( 5 6 7 ) ). + vector := #( 1 2 3 ) asPMVector. + expected := PMMatrix rows: #( #( 0 0 0 ) #( 4 4 4 ) ). + + self assert: (matrix columnWiseSubstractionWith: vector) equals: expected +] + +{ #category : 'linear algebra' } PMMatrixTest >> testDeterminant [ | m | m := PMMatrix rows: #(#(3 2 4) #(2 -5 -1) #(1 -2 2)). self assert: m determinant equals: -42 ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testDimension [ | a | a := PMMatrix rows: #( ( 1 0 1) (-1 -2 3)). @@ -153,7 +174,7 @@ PMMatrixTest >> testDimension [ ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testEigenvalues [ "Code Example 8.15" @@ -175,7 +196,7 @@ PMMatrixTest >> testEigenvalues [ self assert: actual closeTo: expected ]. ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testEigenvaluesLargest [ "Code Example 8.13" @@ -200,21 +221,21 @@ PMMatrixTest >> testEigenvaluesLargest [ self assert: secondEigenvalue closeTo: expectedEigenvalues second. ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testFlattenColumns [ | m | m := PMMatrix rows: #(#(1 2 3) #(4 5 6) #(7 8 9)). self assert: m flattenColumns equals: #(1 4 7 2 5 8 3 6 9) asPMVector ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testFlattenRows [ | m | m := PMMatrix rows: #(#(1 2 3) #(4 5 6) #(7 8 9)). self assert: m flattenRows equals: #(1 2 3 4 5 6 7 8 9) asPMVector ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testIdentityMatrix [ |expectedIdentityMatrix identityMatrix| @@ -228,7 +249,7 @@ PMMatrixTest >> testIdentityMatrix [ self assert: identityMatrix equals: expectedIdentityMatrix. ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testInversePureCRLSingularMatrixError [ self @@ -236,7 +257,7 @@ PMMatrixTest >> testInversePureCRLSingularMatrixError [ raise: PMSingularMatrixError. ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testInversePureLUPSingularMatrixError [ self @@ -244,7 +265,7 @@ PMMatrixTest >> testInversePureLUPSingularMatrixError [ raise: PMSingularMatrixError. ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testInverseSingularMatrixError [ self @@ -252,7 +273,7 @@ PMMatrixTest >> testInverseSingularMatrixError [ raise: PMSingularMatrixError. ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testLUPDecomposition [ "Code Example 8.10" @@ -270,7 +291,7 @@ PMMatrixTest >> testLUPDecomposition [ self assert: (sol2 at: 3) equals: 2 ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testLinearEquations [ "Code Example 8.6" @@ -290,7 +311,7 @@ PMMatrixTest >> testLinearEquations [ self assert: (sol2 at: 3) equals: 2 ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testLinearEquationsSingle [ | s sol | @@ -304,7 +325,7 @@ PMMatrixTest >> testLinearEquationsSingle [ self assert: ((sol at: 3) closeTo: 3.0) ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testLinearEquationsSingular [ | s sol | s := PMLinearEquationSystem @@ -314,7 +335,7 @@ PMMatrixTest >> testLinearEquationsSingular [ self assert: sol isNil ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixAdd [ | a b c | a := PMMatrix rows: #(#(1 0 1) #(-1 -2 3)). @@ -330,7 +351,7 @@ PMMatrixTest >> testMatrixAdd [ self assert: ((c rowAt: 2) at: 3) equals: 10 ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixAddSizeMismatch [ | a b | "Matrices of different dimensions should signal SizeMismatch on #+." @@ -342,14 +363,14 @@ PMMatrixTest >> testMatrixAddSizeMismatch [ self should: [ b transpose + a ] raise: SizeMismatch ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrixTest >> testMatrixCloseTo [ self assert: ((PMMatrix rows: #(#(1.00001 2.00002) #(3.00001 4.00002))) closeTo: (PMMatrix rows: #(#(1.00002 2.00001) #(3.00002 4.00001)))). self assert: (PMMatrix rows: #(#(1.00001 2.00002) #(3.00001 4.00002))) closeTo: (PMMatrix rows: #(#(1.00002 2.00001) #(3.00002 4.00001))). "Double check that the TestAsserter >> #assert:closeTo: functions properly here." self deny: ((PMMatrix rows: #(#(1.00001 2.00004) #(3.00001 4.00004))) closeTo: (PMMatrix rows: #(#(1.00004 2.00001) #(3.00004 4.00001)))). ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrixTest >> testMatrixCloseToPrecision [ | a b | a := PMMatrix rows: #(#(1.2 2.4) #(1.2 2.4)). @@ -359,7 +380,7 @@ PMMatrixTest >> testMatrixCloseToPrecision [ self deny: (a closeTo: b precision: 0.2) ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testMatrixConversionWithBothDims [ | vect result expected | @@ -371,14 +392,14 @@ PMMatrixTest >> testMatrixConversionWithBothDims [ self assert: result equals: expected ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrixTest >> testMatrixCos [ | a | a := PMMatrix rows: (Array with: (Array with: Float pi with: Float pi) with: #(0 0)). self assert: a cos equals: (PMMatrix rows:#((-1 -1) (1 1))) ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixCumulativeSum [ | a b | a := PMMatrix rows: #(#(1 0 1) #(-1 -2 3)). @@ -393,7 +414,7 @@ PMMatrixTest >> testMatrixCumulativeSum [ self assert: ((b rowAt: 2) at: 3) equals: 0 ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixDo [ | a | a := PMMatrix rows: #(#(1 2 3) #(1 2 3) #(1 2 3)). @@ -403,7 +424,7 @@ PMMatrixTest >> testMatrixDo [ self assert: (a rowAt: 1) equals: #(2 3 3) asPMVector ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixElementwiseAdd [ | a b | a := PMMatrix rows: #(#(1 2) #(3 4)). @@ -416,7 +437,7 @@ PMMatrixTest >> testMatrixElementwiseAdd [ self assert: b + -1 equals: a. ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixEquality [ | a c | a := PMMatrix rows: #(#(1 0 1) #(-1 -2 3)). @@ -426,7 +447,7 @@ PMMatrixTest >> testMatrixEquality [ self assert: (c = a and: [ a = c ]) ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixExtensions [ "testing at:at: and at:at:put:" @@ -438,7 +459,7 @@ PMMatrixTest >> testMatrixExtensions [ self shouldnt: [ (c at: 1 at: 1) = (a at: 1 at: 1) ] ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixExtensionsAtColumn [ "testing at:at: and at:at:put:" @@ -456,7 +477,7 @@ PMMatrixTest >> testMatrixExtensionsAtColumn [ self shouldnt: [ (c at: 1 at: 1) = (a at: 1 at: 1) ] ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixExtensionsAtRow [ "testing at:at: and at:at:put:" @@ -473,7 +494,7 @@ PMMatrixTest >> testMatrixExtensionsAtRow [ self shouldnt: [ (c at: 1 at: 2) = (a at: 1 at: 2) ] ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrixTest >> testMatrixGreater [ | a b | a := PMMatrix rows: #(#(1 -1 2) #(-4 0 1)). @@ -488,7 +509,7 @@ PMMatrixTest >> testMatrixGreater [ self assert: ((b rowAt: 2) at: 3) equals: true ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixHadamardProduct [ | a b c | a := PMMatrix rows: #(#(1 0 1) #(-1 -2 3)). @@ -504,7 +525,7 @@ PMMatrixTest >> testMatrixHadamardProduct [ self assert: ((c rowAt: 2) at: 3) equals: 21 ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrixTest >> testMatrixHash [ | a b c | a := PMMatrix rows: #(#(1 0) #(0 1)). @@ -514,7 +535,7 @@ PMMatrixTest >> testMatrixHash [ self shouldnt: [ a hash = c hash ] ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixInitializationWithNegativeDimensions [ " matrices with negative dimension and zero dimension should not be allowed." @@ -522,7 +543,7 @@ PMMatrixTest >> testMatrixInitializationWithNegativeDimensions [ self should: [ PMMatrix rows: 0 columns: 4 ] raise: AssertionFailure. ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixInitializeSquare [ | aPMMatrix | aPMMatrix := PMMatrix new initializeSquare: 2. @@ -531,7 +552,7 @@ PMMatrixTest >> testMatrixInitializeSquare [ ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixInversionSmall [ | m c | m := PMMatrix rows: #(#(3 2 4) #(2 -5 -1) #(1 -2 2)). @@ -549,7 +570,7 @@ PMMatrixTest >> testMatrixInversionSmall [ self assert: ((c rowAt: 3) at: 3) equals: 1 ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrixTest >> testMatrixLess [ | a b | a := PMMatrix rows: #(#(1 -1 2) #(-4 0 1)). @@ -564,7 +585,7 @@ PMMatrixTest >> testMatrixLess [ self assert: ((b rowAt: 2) at: 3) equals: false ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixMultiply [ "Code Example 8.1" @@ -582,7 +603,7 @@ PMMatrixTest >> testMatrixMultiply [ self assert: ((c rowAt: 2) at: 3) equals: 4 ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixNew [ | aPMMatrix | aPMMatrix := PMMatrix new: 3. @@ -591,21 +612,21 @@ PMMatrixTest >> testMatrixNew [ ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixPrincipalDiagonal [ | a | a := PMMatrix rows: #(#(1 2 3) #(4 5 6) #(7 8 9)). self assert: a principalDiagonal equals: #(1 5 9) asPMVector. ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrixTest >> testMatrixSign [ | a | a := PMMatrix rows: #(#(-2 2 0) #(2 0 -2)). self assert: a sign equals: (PMMatrix rows: #((-1 1 0) (1 0 -1))) ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixSubtract [ | a b c | a := PMMatrix rows: #(#(1 0 1) #(-1 -2 3)). @@ -621,7 +642,7 @@ PMMatrixTest >> testMatrixSubtract [ self assert: ((c rowAt: 2) at: 3) equals: -4 ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixSum [ "Code Example 8.1" @@ -633,14 +654,14 @@ PMMatrixTest >> testMatrixSum [ self assert: (v at: 2) equals: 0 ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMatrixTrace [ | a | a := PMMatrix rows: #(#(1 2 3) #(4 5 6) #(7 8 9)). self assert: a tr equals: 15 ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMinorsOfNonSquareMatrix [ | matrix expected | @@ -656,7 +677,7 @@ PMMatrixTest >> testMinorsOfNonSquareMatrix [ self assert: (matrix minor: 1 and: 1) equals: expected ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testMinorsOfSquareMatrix [ | matrix expected | @@ -675,7 +696,7 @@ PMMatrixTest >> testMinorsOfSquareMatrix [ equals: (PMMatrix rows: { { 1 } }) ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testOnesMatrix [ | a | a := PMMatrix onesRows: 2 cols: 3. @@ -689,7 +710,7 @@ PMMatrixTest >> testOnesMatrix [ self assert: ((a rowAt: 2) at: 3) equals: 1 ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testPrintOn [ | m stream | stream := String new writeStream. @@ -697,7 +718,7 @@ PMMatrixTest >> testPrintOn [ m printOn: stream ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testRaisedToNegativeInteger [ |aPMMatrix expected| @@ -710,7 +731,7 @@ PMMatrixTest >> testRaisedToNegativeInteger [ self assert: aPMMatrix equals: expected. ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testRaisedToNonSquareMatrix [ |aPMMatrix| @@ -721,7 +742,7 @@ PMMatrixTest >> testRaisedToNonSquareMatrix [ ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testRaisedToPositiveInteger [ |aPMMatrix expected| @@ -734,7 +755,7 @@ PMMatrixTest >> testRaisedToPositiveInteger [ self assert: aPMMatrix equals: expected. ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testRaisedToZero [ |aPMMatrix expected| @@ -747,7 +768,7 @@ PMMatrixTest >> testRaisedToZero [ self assert: aPMMatrix equals: expected. ] -{ #category : #comparing } +{ #category : 'comparing' } PMMatrixTest >> testRowsColumns [ | a | @@ -755,7 +776,7 @@ PMMatrixTest >> testRowsColumns [ self assert: a dimension equals: 3 @ 4. ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testRowsColumnsElement [ | a | @@ -766,7 +787,7 @@ PMMatrixTest >> testRowsColumnsElement [ ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testSimpleMatrixOperations [ | s m s2 r r2 | "a mix of unsymmetric and symmetric matrices" @@ -818,7 +839,7 @@ PMMatrixTest >> testSimpleMatrixOperations [ self assert: m transpose * m equals: m squared ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testSkalarMultiplication [ | a r | a := PMMatrix rows: #(#(1 2) #(3 3)). @@ -836,7 +857,7 @@ PMMatrixTest >> testSkalarMultiplication [ self assert: r class equals: PMSymmetricMatrix ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testStrassenProductWithMatrix [ | aPMMatrix expected strassenProduct | @@ -847,7 +868,7 @@ PMMatrixTest >> testStrassenProductWithMatrix [ self assert: strassenProduct equals: expected. ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testStrassenProductWithMatrixWithInvalidShapes [ | aPMMatrix | @@ -859,7 +880,7 @@ PMMatrixTest >> testStrassenProductWithMatrixWithInvalidShapes [ ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testSymmetric [ |a m| a:=#(1 2 3)asPMVector. @@ -874,7 +895,7 @@ self assert: (m isSymmetric ). ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testSymmetricMatrixAdd [ | a b c | a := (PMMatrix rows: #(#(11 12 13) #(12 22 23) #(13 23 33))) @@ -888,7 +909,7 @@ PMMatrixTest >> testSymmetricMatrixAdd [ self assert: ((c rowAt: 1) at: 3) equals: 16 ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testSymmetricMatrixAdd2 [ | a b c | a := PMSymmetricMatrix rows: #(#(11 12 13) #(12 22 23) #(13 23 33)). @@ -901,7 +922,7 @@ PMMatrixTest >> testSymmetricMatrixAdd2 [ self assert: ((c rowAt: 1) at: 3) equals: 16 ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testSymmetricMatrixAdd3 [ | a b c | a := PMMatrix rows: #(#(11 12 13) #(21 22 23) #(31 32 33)). @@ -918,7 +939,7 @@ PMMatrixTest >> testSymmetricMatrixAdd3 [ self assert: ((c rowAt: 3) at: 1) equals: 31 ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testTake [ | m expected | @@ -935,14 +956,14 @@ PMMatrixTest >> testTake [ self assert: (m take: 2) equals: expected. ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testVectorConversion [ | m | m := PMMatrix rows: #(#(1 2 3) #(4 5 6) #(7 8 9)). self assert: m asVector equals: #(1 2 3 4 5 6 7 8 9) asPMVector ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testVectorMatrixOperation [ "Code Example 8.1" @@ -955,7 +976,7 @@ PMMatrixTest >> testVectorMatrixOperation [ self assert: (v at: 2) equals: 4 ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testVectorToVectorConversion [ | vect result expected | @@ -967,7 +988,7 @@ PMMatrixTest >> testVectorToVectorConversion [ self assert: result equals: expected ] -{ #category : #'linear algebra' } +{ #category : 'linear algebra' } PMMatrixTest >> testVectorTransposeMatrixOperation [ "Code Example 8.1" @@ -981,7 +1002,7 @@ PMMatrixTest >> testVectorTransposeMatrixOperation [ self assert: (w at: 3) equals: 56 ] -{ #category : #tests } +{ #category : 'tests' } PMMatrixTest >> testZerosMatrix [ |a| a:=PMMatrix zerosRows: 2 cols: 3. diff --git a/src/Math-Matrix-Tests/PMNDArrayTest.class.st b/src/Math-Matrix-Tests/PMNDArrayTest.class.st index 190813a..27520f6 100644 --- a/src/Math-Matrix-Tests/PMNDArrayTest.class.st +++ b/src/Math-Matrix-Tests/PMNDArrayTest.class.st @@ -1,10 +1,11 @@ Class { - #name : #PMNDArrayTest, - #superclass : #TestCase, - #category : #'Math-Matrix-Tests' + #name : 'PMNDArrayTest', + #superclass : 'TestCase', + #category : 'Math-Matrix-Tests', + #package : 'Math-Matrix-Tests' } -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testArray [ | t1 t2 | @@ -18,7 +19,7 @@ PMNDArrayTest >> testArray [ equals: #( 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ) ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testAt [ | t1 t2 | @@ -32,7 +33,7 @@ PMNDArrayTest >> testAt [ self should:[t1 at: #( 4 4 )] raise:Error ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testAtPut [ | t1 t2 | @@ -48,7 +49,7 @@ PMNDArrayTest >> testAtPut [ self assert: (t2 at: #( 2 2 1 )) equals: 10 ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testCreateScalarNDArray [ | s | @@ -62,7 +63,7 @@ PMNDArrayTest >> testCreateScalarNDArray [ self assert: s size equals: 1 ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testFirst [ | a b | @@ -72,7 +73,7 @@ PMNDArrayTest >> testFirst [ self assert: b first equals: #( 1 1 ) ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testFlattenedIndexOf [ | t1 t2 | @@ -84,7 +85,7 @@ PMNDArrayTest >> testFlattenedIndexOf [ self assert: (t2 flattenedIndexOf: #( 1 2 2 )) equals: 4 ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testFromNestedArray [ | t1 t2 | @@ -100,7 +101,7 @@ PMNDArrayTest >> testFromNestedArray [ ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testHadamardProduct [ |t1 t2 expectedHadamardProduct| @@ -144,7 +145,7 @@ self assert: (t1 hadamardProduct: t2) equals: expectedHadamardProduct ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testHadamardProductWithDifferentShapesFails [ |t1 t2| t1 := PMNDArray fromNestedArray: #( #( 1 2) #(3 4) #(5 6) #(7 8)). @@ -152,7 +153,7 @@ PMNDArrayTest >> testHadamardProductWithDifferentShapesFails [ self should: [t1 hadamardProduct: t2] raise: ShapeMismatch ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testRank [ | t1 t2 | @@ -165,7 +166,7 @@ PMNDArrayTest >> testRank [ self assert: t2 rank equals: 3 ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testReshape [ | t t1 | @@ -177,7 +178,7 @@ PMNDArrayTest >> testReshape [ self assert: t1 asArray == t asArray equals: true ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testShape [ | t1 t2 | @@ -192,7 +193,7 @@ PMNDArrayTest >> testShape [ self assert: t2 shape equals: #( 4 2 2 ) ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testSize [ | t1 t2 | @@ -204,7 +205,7 @@ PMNDArrayTest >> testSize [ self assert: t2 size equals: 16 ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testStrides [ | a b | @@ -223,7 +224,7 @@ PMNDArrayTest >> testStrides [ self assert: (b flattenedIndexOf: #( 2 2 3 )) equals: 19 ] -{ #category : #tests } +{ #category : 'tests' } PMNDArrayTest >> testView [ | t t1 | diff --git a/src/Math-Matrix-Tests/PMQRTest.class.st b/src/Math-Matrix-Tests/PMQRTest.class.st index 7fafb74..4f1e753 100644 --- a/src/Math-Matrix-Tests/PMQRTest.class.st +++ b/src/Math-Matrix-Tests/PMQRTest.class.st @@ -1,10 +1,11 @@ Class { - #name : #PMQRTest, - #superclass : #TestCase, - #category : #'Math-Matrix-Tests' + #name : 'PMQRTest', + #superclass : 'TestCase', + #category : 'Math-Matrix-Tests', + #package : 'Math-Matrix-Tests' } -{ #category : #running } +{ #category : 'running' } PMQRTest >> assert: inverse isMoorePenroseInverseOf: aMatrix [ "https://en.wikipedia.org/wiki/Moore–Penrose_inverse#Definition" @@ -27,7 +28,7 @@ PMQRTest >> assert: inverse isMoorePenroseInverseOf: aMatrix [ closeTo: aMatrix mpInverse transpose. ] -{ #category : #tests } +{ #category : 'tests' } PMQRTest >> testDecompositionOfMatrixCausingErraticFailure [ | a qrDecomposition matricesAndPivot q r expectedMatrix pivot | @@ -60,7 +61,7 @@ PMQRTest >> testDecompositionOfMatrixCausingErraticFailure [ self assert: pivot equals: #( 3 4 3 nil ) ] -{ #category : #tests } +{ #category : 'tests' } PMQRTest >> testHorizontalRectangularMatrixCannotBeDecomposed [ | horizontalRectangularMatrix | @@ -74,7 +75,7 @@ PMQRTest >> testHorizontalRectangularMatrixCannotBeDecomposed [ raise: Error ] -{ #category : #tests } +{ #category : 'tests' } PMQRTest >> testMoorePenroseInverseOfLargeNonRandomMatrixAndItsTranspose [ | a inverse transposeOfA | a := PMMatrix new initializeRows: @@ -87,7 +88,7 @@ PMQRTest >> testMoorePenroseInverseOfLargeNonRandomMatrixAndItsTranspose [ self assert: inverse isMoorePenroseInverseOf: transposeOfA. ] -{ #category : #tests } +{ #category : 'tests' } PMQRTest >> testMoorePenroseInverseOfNonRandomMatrix [ | a inverse | a := PMMatrix new initializeRows: @@ -96,7 +97,7 @@ PMQRTest >> testMoorePenroseInverseOfNonRandomMatrix [ self assert: inverse isMoorePenroseInverseOf: a. ] -{ #category : #tests } +{ #category : 'tests' } PMQRTest >> testMoorePenroseInverseOfProductOfMatrices [ | a inverse | @@ -111,7 +112,7 @@ PMQRTest >> testMoorePenroseInverseOfProductOfMatrices [ self assert: inverse isMoorePenroseInverseOf: a ] -{ #category : #tests } +{ #category : 'tests' } PMQRTest >> testMoorePenroseInverseOfRandomMatrixIsAnInverse [ " Proofs for the properties below can be found in literature: @@ -124,7 +125,7 @@ If A is invertible, its pseudoinverse is its inverse. That is, A+ = A**−1 self assert: (a mpInverse closeTo: a inverse) ] -{ #category : #tests } +{ #category : 'tests' } PMQRTest >> testOrthogonalize [ | a b i | @@ -150,7 +151,7 @@ PMQRTest >> testOrthogonalize [ i < 10 ] whileTrue ] -{ #category : #tests } +{ #category : 'tests' } PMQRTest >> testQRFactorization [ | a qr | @@ -182,7 +183,7 @@ PMQRTest >> testQRFactorization [ 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 } +{ #category : 'tests' } PMQRTest >> testRank [ | random randomNumber matrix | @@ -205,7 +206,7 @@ PMQRTest >> testRank [ self assert: matrix transpose rank equals: 3 ] ] ] -{ #category : #tests } +{ #category : 'tests' } PMQRTest >> testSimpleQRDecomposition [ | a qrDecomposition decomposition | @@ -221,7 +222,7 @@ PMQRTest >> testSimpleQRDecomposition [ self assert: decomposition first * decomposition second equals: a ] -{ #category : #tests } +{ #category : 'tests' } PMQRTest >> testSimpleQRDecompositionWithPivot [ | a qrDecomposition decomposition expected | @@ -244,7 +245,7 @@ PMQRTest >> testSimpleQRDecompositionWithPivot [ closeTo: expected ] -{ #category : #tests } +{ #category : 'tests' } PMQRTest >> testVectorHouseholder [ "result is householdermatrix * v" diff --git a/src/Math-Matrix-Tests/PMRestTest.class.st b/src/Math-Matrix-Tests/PMRestTest.class.st index 009956e..54f1210 100644 --- a/src/Math-Matrix-Tests/PMRestTest.class.st +++ b/src/Math-Matrix-Tests/PMRestTest.class.st @@ -1,10 +1,11 @@ Class { - #name : #PMRestTest, - #superclass : #TestCase, - #category : #'Math-Matrix-Tests' + #name : 'PMRestTest', + #superclass : 'TestCase', + #category : 'Math-Matrix-Tests', + #package : 'Math-Matrix-Tests' } -{ #category : #tests } +{ #category : 'tests' } PMRestTest >> testEqualsTo [ | a b | @@ -19,7 +20,7 @@ PMRestTest >> testEqualsTo [ self deny: (a closeTo: b) ] -{ #category : #tests } +{ #category : 'tests' } PMRestTest >> testNewRandom [ | a | @@ -27,7 +28,7 @@ PMRestTest >> testNewRandom [ self assert: a isSymmetric ] -{ #category : #tests } +{ #category : 'tests' } PMRestTest >> testSwapColumnWithColumn [ | a | a := PMMatrix new initializeRows: #(#(5 40 1) #(3 0 1) #(2 7 1)). diff --git a/src/Math-Matrix-Tests/PMSingularValueDecompositionTest.class.st b/src/Math-Matrix-Tests/PMSingularValueDecompositionTest.class.st index d4f20dd..a1bafc1 100644 --- a/src/Math-Matrix-Tests/PMSingularValueDecompositionTest.class.st +++ b/src/Math-Matrix-Tests/PMSingularValueDecompositionTest.class.st @@ -27,18 +27,19 @@ Internal Representation and Key Implementation Points. Implementation Points " Class { - #name : #PMSingularValueDecompositionTest, - #superclass : #TestCase, + #name : 'PMSingularValueDecompositionTest', + #superclass : 'TestCase', #instVars : [ 'matrix', 'actualU', 'actualV', 'actualS' ], - #category : #'Math-Matrix-Tests' + #category : 'Math-Matrix-Tests', + #package : 'Math-Matrix-Tests' } -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMSingularValueDecompositionTest >> loadExample1 [ "Simple example. Square matrix with real values" @@ -59,7 +60,7 @@ PMSingularValueDecompositionTest >> loadExample1 [ (0 0)). ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMSingularValueDecompositionTest >> loadExample2 [ "Simple example. Square matrix with real values" @@ -88,7 +89,7 @@ PMSingularValueDecompositionTest >> loadExample2 [ (0 0 0 0)). ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMSingularValueDecompositionTest >> loadExample3 [ "Rectangular matrix with real values" @@ -113,7 +114,7 @@ PMSingularValueDecompositionTest >> loadExample3 [ with: (Array with: 0 with: 1 with: 0) ). ] -{ #category : #'as yet unclassified' } +{ #category : 'as yet unclassified' } PMSingularValueDecompositionTest >> loadExample4 [ "Rectangular matrix with real values" @@ -145,7 +146,7 @@ PMSingularValueDecompositionTest >> loadExample4 [ ) ] -{ #category : #initialization } +{ #category : 'initialization' } PMSingularValueDecompositionTest >> setUp [ super setUp. self loadExample1 @@ -154,7 +155,7 @@ PMSingularValueDecompositionTest >> setUp [ "self loadExample4." ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testIsExampleCorrect [ "Verifying that the example SVD is correct" @@ -163,7 +164,7 @@ PMSingularValueDecompositionTest >> testIsExampleCorrect [ self assert: reconstructed closeTo: matrix. ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testIsExampleOrthonormalU [ "Verifying that matrix U in the given example is orthonormal. That is, all columns of U are unit vectors and orthogonal to each other." @@ -175,7 +176,7 @@ PMSingularValueDecompositionTest >> testIsExampleOrthonormalU [ self assert: (actualU transpose * actualU) closeTo: identity ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testIsExampleOrthonormalV [ "Verifying that matrix V in the given example is orthonormal. That is, all columns of V are unit vectors and orthogonal to each other." @@ -187,7 +188,7 @@ PMSingularValueDecompositionTest >> testIsExampleOrthonormalV [ self assert: (actualV transpose * actualV) closeTo: identity ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testIsOrthonormalU [ "Verifying that matrix U is orthonormal. That is, all columns of U are unit vectors and orthogonal to each other." @@ -199,7 +200,7 @@ PMSingularValueDecompositionTest >> testIsOrthonormalU [ self assert: u transpose * u closeTo: identity ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testIsOrthonormalV [ "Verifying that matrix U is orthonormal. That is, all columns of U are unit vectors and orthogonal to each other." @@ -211,7 +212,7 @@ PMSingularValueDecompositionTest >> testIsOrthonormalV [ self assert: v transpose * v closeTo: identity ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testIsSquareU [ "U should be a square matrix" @@ -221,7 +222,7 @@ PMSingularValueDecompositionTest >> testIsSquareU [ self assert: u numberOfRows equals: u numberOfColumns ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testIsSquareV [ "V should be a square matrix" @@ -231,7 +232,7 @@ PMSingularValueDecompositionTest >> testIsSquareV [ self assert: v numberOfRows equals: v numberOfColumns ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testReconstruction [ | svd u v s reconstructed | @@ -243,7 +244,7 @@ PMSingularValueDecompositionTest >> testReconstruction [ self assert: reconstructed closeTo: matrix ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testShapeS [ "If A is an (m x n) matrix, then S should be an (m x n) matrix" @@ -256,7 +257,7 @@ PMSingularValueDecompositionTest >> testShapeS [ self assert: s numberOfColumns equals: n ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testShapeU [ "If A is an (m x n) matrix, then U should be an (m x m) matrix" @@ -268,7 +269,7 @@ PMSingularValueDecompositionTest >> testShapeU [ self assert: u numberOfColumns equals: m ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testShapeV [ "If A is an (m x n) matrix, then V should be an (n x n) matrix" @@ -280,7 +281,7 @@ PMSingularValueDecompositionTest >> testShapeV [ self assert: v numberOfColumns equals: n ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testValueS [ "Comparing S to its known value" @@ -290,7 +291,7 @@ PMSingularValueDecompositionTest >> testValueS [ self assert: s closeTo: actualS ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testValueU [ "Comparing U to its known value" @@ -300,7 +301,7 @@ PMSingularValueDecompositionTest >> testValueU [ self assert: u closeTo: actualU ] -{ #category : #tests } +{ #category : 'tests' } PMSingularValueDecompositionTest >> testValueV [ "Comparing V to its known value" diff --git a/src/Math-Matrix-Tests/PMSymmetricMatrixTest.class.st b/src/Math-Matrix-Tests/PMSymmetricMatrixTest.class.st index 7a0875a..9c8ff36 100644 --- a/src/Math-Matrix-Tests/PMSymmetricMatrixTest.class.st +++ b/src/Math-Matrix-Tests/PMSymmetricMatrixTest.class.st @@ -1,10 +1,11 @@ Class { - #name : #PMSymmetricMatrixTest, - #superclass : #TestCase, - #category : #'Math-Matrix-Tests' + #name : 'PMSymmetricMatrixTest', + #superclass : 'TestCase', + #category : 'Math-Matrix-Tests', + #package : 'Math-Matrix-Tests' } -{ #category : #tests } +{ #category : 'tests' } PMSymmetricMatrixTest >> testCrlInverse [ | m i | m := PMSymmetricMatrix rows: #(#(2 2 3) #(2 4 5) #(3 5 6)). @@ -16,7 +17,7 @@ a PMVector(0 1 -40) a PMVector(2 4 -51)" ] -{ #category : #tests } +{ #category : 'tests' } PMSymmetricMatrixTest >> testEqual [ "= should work like in a SequenceableCollection eg a PMVector and a Array can be equal" @@ -38,7 +39,7 @@ PMSymmetricMatrixTest >> testEqual [ self assert: b ~= a ] -{ #category : #tests } +{ #category : 'tests' } PMSymmetricMatrixTest >> testIdentityMatrix [ |expectedIdentityMatrix identityMatrix| @@ -48,7 +49,7 @@ PMSymmetricMatrixTest >> testIdentityMatrix [ self assert: identityMatrix equals: expectedIdentityMatrix. ] -{ #category : #tests } +{ #category : 'tests' } PMSymmetricMatrixTest >> testInversePureLUP [ | m i | m := PMSymmetricMatrix rows: #(#(2 2 3) #(2 4 5) #(3 5 6)). diff --git a/src/Math-Matrix-Tests/package.st b/src/Math-Matrix-Tests/package.st index 990a5a9..2628d8c 100644 --- a/src/Math-Matrix-Tests/package.st +++ b/src/Math-Matrix-Tests/package.st @@ -1 +1 @@ -Package { #name : #'Math-Matrix-Tests' } +Package { #name : 'Math-Matrix-Tests' } From 1215b877de6d418fde4c00fc4c969b9d33eda576 Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Tue, 17 Feb 2026 14:55:51 +0100 Subject: [PATCH 3/7] fixed confusion in method name, code is still the same --- src/Math-Matrix/PMMatrix.class.st | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Math-Matrix/PMMatrix.class.st b/src/Math-Matrix/PMMatrix.class.st index ca1b356..986bfca 100644 --- a/src/Math-Matrix/PMMatrix.class.st +++ b/src/Math-Matrix/PMMatrix.class.st @@ -198,7 +198,7 @@ PMMatrix >> - aMatrix [ PMMatrix >> -= aColumn [ "Assume a collection is a matrix of one row" - self columnWiseSubstractionWith: aColumn + self rowWiseSubstractionWith: aColumn ] { #category : 'operation' } @@ -438,20 +438,6 @@ PMMatrix >> columnVectorAt: col size: dimension [ ^ (self columnAt: col) copyFrom: col to: dimension ] -{ #category : 'operating' } -PMMatrix >> columnWiseSubstractionWith: aColumn [ - "Assume a collection is a matrix of one row" - - | result | - result := self class rows: self numberOfRows columns: self numberOfColumns. - - 1 to: self numberOfColumns do: [ :col | - | me | - me := self atColumn: col. - result atColumn: col put: me - (aColumn at: col) ]. - ^ result -] - { #category : 'iterators' } PMMatrix >> columnsCollect: aBlock [ "Perform the collect: operation on the rows of the receiver." @@ -911,6 +897,20 @@ PMMatrix >> rowAt: aRowIndex columnAt: aColumnIndex put: aValue [ ^(rows at: aRowIndex) at: aColumnIndex put: aValue ] +{ #category : 'operating' } +PMMatrix >> rowWiseSubstractionWith: aRow [ + "Assume a collection is a matrix of one row" + + | result | + result := self class rows: self numberOfRows columns: self numberOfColumns. + + 1 to: self numberOfColumns do: [ :col | + | me | + me := self atColumn: col. + result atColumn: col put: me - (aRow at: col) ]. + ^ result +] + { #category : 'cell accessing' } PMMatrix >> rows [ ^rows From 4668c37d696767cca94cc221c9c6d9055b38a3c7 Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Tue, 17 Feb 2026 14:56:13 +0100 Subject: [PATCH 4/7] updated test with new method name --- src/Math-Matrix-Tests/PMMatrixTest.class.st | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Math-Matrix-Tests/PMMatrixTest.class.st b/src/Math-Matrix-Tests/PMMatrixTest.class.st index 70a7a54..cf79d35 100644 --- a/src/Math-Matrix-Tests/PMMatrixTest.class.st +++ b/src/Math-Matrix-Tests/PMMatrixTest.class.st @@ -148,17 +148,6 @@ PMMatrixTest >> testColumnAverage [ self assert: matrix columnAverage equals: #( 3 4 5 ) ] -{ #category : 'tests' } -PMMatrixTest >> testColumnWiseSubstractionWith [ - - | matrix vector expected | - matrix := PMMatrix rows: #( #( 1 2 3 ) #( 5 6 7 ) ). - vector := #( 1 2 3 ) asPMVector. - expected := PMMatrix rows: #( #( 0 0 0 ) #( 4 4 4 ) ). - - self assert: (matrix columnWiseSubstractionWith: vector) equals: expected -] - { #category : 'linear algebra' } PMMatrixTest >> testDeterminant [ | m | @@ -768,6 +757,17 @@ PMMatrixTest >> testRaisedToZero [ self assert: aPMMatrix equals: expected. ] +{ #category : 'tests' } +PMMatrixTest >> testRowWiseSubstractionWith [ + + | matrix vector expected | + matrix := PMMatrix rows: #( #( 1 2 3 ) #( 5 6 7 ) ). + vector := #( 1 2 3 ) asPMVector. + expected := PMMatrix rows: #( #( 0 0 0 ) #( 4 4 4 ) ). + + self assert: (matrix rowWiseSubstractionWith: vector) equals: expected +] + { #category : 'comparing' } PMMatrixTest >> testRowsColumns [ | a | From 2203a8b0203866b13f0d739ae8a66c76947c4a30 Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Tue, 17 Feb 2026 14:58:53 +0100 Subject: [PATCH 5/7] updated parameter name --- src/Math-Matrix/PMMatrix.class.st | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Math-Matrix/PMMatrix.class.st b/src/Math-Matrix/PMMatrix.class.st index 986bfca..55bc545 100644 --- a/src/Math-Matrix/PMMatrix.class.st +++ b/src/Math-Matrix/PMMatrix.class.st @@ -195,10 +195,10 @@ PMMatrix >> - aMatrix [ ] { #category : 'operating' } -PMMatrix >> -= aColumn [ +PMMatrix >> -= aRow [ "Assume a collection is a matrix of one row" - self rowWiseSubstractionWith: aColumn + self rowWiseSubstractionWith: aRow ] { #category : 'operation' } From b6a3a978f7df1ae8829bdfcdd1405c7572ea7865 Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Tue, 17 Feb 2026 15:10:30 +0100 Subject: [PATCH 6/7] fix return --- src/Math-Matrix/PMMatrix.class.st | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Math-Matrix/PMMatrix.class.st b/src/Math-Matrix/PMMatrix.class.st index 55bc545..cc4bea4 100644 --- a/src/Math-Matrix/PMMatrix.class.st +++ b/src/Math-Matrix/PMMatrix.class.st @@ -198,7 +198,7 @@ PMMatrix >> - aMatrix [ PMMatrix >> -= aRow [ "Assume a collection is a matrix of one row" - self rowWiseSubstractionWith: aRow + ^ self rowWiseSubstractionWith: aRow ] { #category : 'operation' } From f95ddabc6fd340450b68e9d859ac030988bd22da Mon Sep 17 00:00:00 2001 From: DurieuxPol Date: Tue, 17 Feb 2026 15:13:11 +0100 Subject: [PATCH 7/7] update test --- src/Math-Matrix-Tests/PMMatrixTest.class.st | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Math-Matrix-Tests/PMMatrixTest.class.st b/src/Math-Matrix-Tests/PMMatrixTest.class.st index cf79d35..6bbd4e6 100644 --- a/src/Math-Matrix-Tests/PMMatrixTest.class.st +++ b/src/Math-Matrix-Tests/PMMatrixTest.class.st @@ -765,7 +765,8 @@ PMMatrixTest >> testRowWiseSubstractionWith [ vector := #( 1 2 3 ) asPMVector. expected := PMMatrix rows: #( #( 0 0 0 ) #( 4 4 4 ) ). - self assert: (matrix rowWiseSubstractionWith: vector) equals: expected + self assert: (matrix rowWiseSubstractionWith: vector) equals: expected. + self assert: matrix -= vector equals: expected ] { #category : 'comparing' }