Huge Matrices Library [Updated] - TarotRedhand - 05-04-2022
I initially created this library in the late 1990s. Having found QB64, I have now updated and expanded this library to work with it. At 2622 lines (including comments) it is obviously too large to post in a single code box. So the actual code is split into the six posts after this one. Also the sheer size and number of edits I made means that you should really treat this being a beta/release candidate version.
This library is all to do with matrices. There are six sections to it. Each section deals with matrix operations for arrays that contain a particular TYPE of data - Integer, Long Integer, _INTEGER64, Single precision floating point, Double precision floating point and _FLOAT. Overall this gives us 1 private routine and 114 public routines.
Having split it into 6 parts, I have made it so that each part should be able to be used independently of any other. The consequence of this is that if you want to use two (or more) parts you may well need to do minor editing on one (or more) parts.
Bug reports - either in here or pm me.
[Edit]
Now with a ridiculously small BI file that works all varieties of the library. '$INCLUDE: 'MATRIX.BI' at the top of the program that uses any of the library parts.
MATRIX.BI
Code: (Select All) '$DYNAMIC
Option Base 1
Note all parts of this library have been updated to reflect this.
Next post Integer Matrices -
TR
RE: Huge Matrices Library - TarotRedhand - 05-04-2022
This section contains the following public routines -
Code: (Select All) ' Integer
SUB IdentityIMatrix(A%(), MatrixSize%)
SUB ZeroIMatrix(A%())
SUB ConIMatrix(A%())
SUB IMatrixNegate(A%())
SUB IMatrixTransPose(A%(), B%())
SUB IMatrixCopy(This%(), ToThis%())
SUB IMatrixPrint(A%())
SUB IMatrixFilePrint(A%(), FileNumber)
SUB IMatrixInput(A%())
SUB IMatrixFileInput(A%() , FileNum)
SUB IMatrixAdd(A%(), B%(), C%())
SUB IMatrixScalarAdd(A%(), B%, C%())
SUB IMatrixSubtract(A%(), B%(), C%())
SUB IMatrixScalarSubtract(A%(), B%, C%())
SUB IMatrixMultiply(A%(), B%(), C%())
SUB IMatrixScalarMultiply(A%(), B%, C%())
FUNCTION IMatrixMaximum%(A%())
FUNCTION IMatrixMinimum%(A%())
And here is the library -
Code: (Select All) REM ******************************************************************
REM * This library deals with 2 dimensional arrays that are treated *
REM * as though they were mathematical matrices. I have included *
REM * all the routines that are associated with matrices that make *
REM * sense for the various TYPEs that are used. So for integers *
REM * and longs there no routines for mean, variance, inverse or *
REM * determinant. Also for singles and doubles I have left out *
REM * routines for inverse and determinant as their use is very *
REM * limited and specialised. *
REM ******************************************************************
REM ******************************************************************
REM * Private SUB only intended for use by the routines in this *
REM * library. *
REM ******************************************************************
SUB MatrixError(Where$, Fault$)
PRINT "Error in ";Where$;" - ";Fault$
STOP
END SUB ' | MatrixError
REM ******************************************************************
REM * Integer Matrices *
REM ******************************************************************
REM ******************************************************************
REM * A%() is REDIM'ed to be a square matrix with MatrixSize& rows *
REM * and MatrixSize& columns. All the elements of A%() are set to *
REM * zero except those where the row and the column are equal which *
REM * are set to one e.g. A%(1,1) = 1, A%(1,2) = 0. *
REM ******************************************************************
SUB IdentityIMatrix(A%(), MatrixSize&)
MatrixSize& = ABS(MatrixSize&)
REDIM A%(1 TO MatrixSize&, 1 TO MatrixSize&)
FOR Column& = 1 TO MatrixSize&
FOR Row& = 1 TO MatrixSize&
IF Row& = Column& THEN
A%(Row&,Column&) = 1
ELSE
A%(Row&,Column&) = 0
END IF
NEXT Row&
NEXT Column&
END SUB ' | IdentityIMatrix
REM ******************************************************************
REM * All the elements of A%() are set to zero. *
REM ******************************************************************
SUB ZeroIMatrix(A%())
ARowStart& = LBOUND(A%)
ARowEnd& = UBOUND(A%)
AColStart& = LBOUND(A%, 2)
AColEnd& = UBOUND(A%, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A%(Row&,Column&) = 0
NEXT Row&
NEXT Column&
END SUB ' | ZeroIMatrix
REM ******************************************************************
REM * All the elements of A%() are set to one. *
REM ******************************************************************
SUB ConIMatrix(A%())
ARowStart& = LBOUND(A%)
ARowEnd& = UBOUND(A%)
AColStart& = LBOUND(A%, 2)
AColEnd& = UBOUND(A%, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A%(Row&,Column&) = 1
NEXT Row&
NEXT Column&
END SUB ' | ConIMatrix
REM ******************************************************************
REM * LET A%() = -A%() e.g if A%(1,1) = 5 then after this routine *
REM * A%(1,1) = -5. *
REM ******************************************************************
SUB IMatrixNegate(A%())
ARowStart& = LBOUND(A%)
ARowEnd& = UBOUND(A%)
AColStart& = LBOUND(A%, 2)
AColEnd& = UBOUND(A%, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A%(Row&,Column&) = -A%(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | IMatrixNegate
REM ******************************************************************
REM * B%() is REDIM'ed to have the same number of columns as A%() *
REM * has rows and to have the same number of rows as A%() has *
REM * columns, and then the rows of A%() are copied to the columns *
REM * of B%(). *
REM ******************************************************************
SUB IMatrixTransPose(A%(), B%())
ARowStart& = LBOUND(A%)
AColStart& = LBOUND(A%, 2)
ARowEnd& = UBOUND(A%)
AColEnd& = UBOUND(A%, 2)
REDIM B%(AColStart& TO AColEnd&, ARowStart& TO ARowEnd&)
FOR P& = AColStart& TO AColEnd&
FOR Q& = ARowStart& TO ARowEnd&
B%(P&, Q&) = A%(Q&, P&)
NEXT Q&
NEXT P&
END SUB ' | IMatrixTransPose
REM ******************************************************************
REM * REDIM's ToThis%() to be the same size as This%() and then *
REM * copies the contents of This%() to ToThis%(). *
REM ******************************************************************
SUB IMatrixCopy(This%(), ToThis%())
RowStart& = LBOUND(This%)
RowFinish& = UBOUND(This%)
ColStart& = LBOUND(This%, 2)
ColFinish& = UBOUND(This%,2)
REDIM ToThis%(RowStart& TO RowFinish&, ColStart& TO ColFinish&)
FOR Column& = ColStart& TO ColFinish&
FOR Row& = RowStart& To RowFinish&
ToThis%(Row&,Column&) = This%(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | IMatrixCopy
REM ******************************************************************
REM * Display the contents of A%() on screen, formatted in columns. *
REM ******************************************************************
SUB IMatrixPrint(A%())
ARowStart& = LBOUND(A%)
ARowEnd& = UBOUND(A%)
AColStart& = LBOUND(A%, 2)
AColEnd& = UBOUND(A%, 2)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT A%(Row&,Column&);" ";
NEXT Column&
PRINT
NEXT Row&
END SUB ' | IMatrixPrint
REM ******************************************************************
REM * Saves the contents of A%() to the file specified by FileNumber *
REM ******************************************************************
SUB IMatrixFilePrint(A%(), FileNumber)
ARowStart& = LBOUND(A%)
PRINT #FileNumber, ARowStart&;" ";
ARowEnd& = UBOUND(A%)
PRINT #FileNumber, ARowEnd&;" ";
AColStart& = LBOUND(A%, 2)
PRINT #FileNumber, AColStart&;" ";
AColEnd& = UBOUND(A%, 2)
PRINT #FileNumber, AColEnd&;" ";
PRINT #FileNumber,
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT #FileNumber, A%(Row&,Column&);" ";
NEXT Column&
PRINT #FileNumber,
NEXT Row&
END SUB ' | IMatrixFilePrint
REM ******************************************************************
REM * This routine is for the sadists and masochists among you in *
REM * that it inputs all the information necessary to create and *
REM * fill a matrix fromthe keyboard. *
REM ******************************************************************
SUB IMatrixInput(A%())
INPUT"Lowest subscript for A%(1):",A
INPUT"Highest subscript for A%(1):",B
INPUT"Lowest subscript for A%(2):",C
INPUT"Lowest subscript for A%(2):",D
REDIM A%(A TO B, C TO D)
PRINT
FOR Row& = A TO B
FOR Column& = C TO D
PRINT "Enter value for position ";Row&;", ";Column&;":";
INPUT A
A%(Row&,Column&) = FIX(A)
NEXT Column&
NEXT Row&
END SUB ' | IMatrixInput
REM ******************************************************************
REM * This routine reads all the information necessary to create and *
REM * fill a matrix ( A%() ) from a file specified by filenum. This *
REM * routine is the complement to IMatrixFilePrint and retrieves *
REM * the information in the same order as that routine writes it. *
REM ******************************************************************
SUB IMatrixFileInput(A%() , FileNum)
INPUT #FileNum, A
INPUT #FileNum, B
INPUT #FileNum, C
INPUT #FileNum, D
A = ABS(FIX(A))
B = ABS(FIX(B))
C = ABS(FIX(C))
D = ABS(FIX(D))
REDIM A%(A TO B, C TO D)
FOR Row& = A TO B
FOR Column& = C TO D
INPUT #FileNum, A
A%(Row&,Column&) = FIX(A)
NEXT Column&
NEXT Row&
END SUB ' | IMatrixFileInput
REM ******************************************************************
REM * Matrix addition e.g. C%() = A%() + B%(). A%() and B%() must *
REM * have identical upper and lower bounds. C%() is REDIM'ed to be *
REM * the same size. Each element of C%() is assigned the result of *
REM * adding the equivalent elements in A%() and B%(). *
REM ******************************************************************
SUB IMatrixAdd(A%(), B%(), C%())
ID$ = "IMatrixAdd"
ARowStart& = LBOUND(A%)
BRowStart& = LBOUND(B%)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A%)
BRowEnd& = UBOUND(B%)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A%, 2)
BColStart&& = LBOUND(B%, 2)
IF AColStart& <> BColStart&& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
AColEnd& = UBOUND(A%, 2)
BColEnd& = UBOUND(B%, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
REDIM C%(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C%(Row&,Column&) = A%(Row&,Column&) + B%(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | IMatrixAdd
REM ******************************************************************
REM * Matrix scalar addition e.g. C%() = A%() + B%. C%() is *
REM * REDIM'ed to be identical in size to A%(). Each element of *
REM * C%() is assigned the result of adding B% to the equivalent *
REM * elements in A%(). *
REM ******************************************************************
SUB IMatrixScalarAdd(A%(), B%, C%())
ARowStart& = LBOUND(A%)
ARowEnd& = UBOUND(A%)
AColStart& = LBOUND(A%, 2)
AColEnd& = UBOUND(A%, 2)
REDIM C%(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C%(Row&,Column&) = A%(Row&,Column&) + B%
NEXT Row&
NEXT Column&
END SUB ' | IMatrixScalarAdd
REM ******************************************************************
REM * Matrix subtraction e.g. C%() = A%() - B%(). A%() and B%() *
REM * must have identical upper and lower bounds. C%() is REDIM'ed *
REM * to be the same size. Each element of C%() is assigned the *
REM * result of subtracting the equivalent element of B%() from the *
REM * equivalent element of A%(). *
REM ******************************************************************
SUB IMatrixSubtract(A%(), B%(), C%())
ID$ = "IMatrixSubtract"
ARowStart& = LBOUND(A%)
BRowStart& = LBOUND(B%)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A%)
BRowEnd& = UBOUND(B%)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A%, 2)
BColStart& = LBOUND(B%, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
AColEnd& = UBOUND(A%, 2)
BColEnd& = UBOUND(B%, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
REDIM C%(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C%(Row&,Column&) = A%(Row&,Column&) - B%(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | IMatrixSubtract
REM ******************************************************************
REM * Matrix scalar subtraction e.g. C%() = A%() - B%. C%() is *
REM * REDIM'ed to be the same size as A%(). Each element of C%() is *
REM * assigned the result of subtracting B% from the equivalent of *
REM * A%(). *
REM ******************************************************************
SUB IMatrixScalarSubtract(A%(), B%, C%())
ARowStart& = LBOUND(A%)
ARowEnd& = UBOUND(A%)
AColStart& = LBOUND(A%, 2)
AColEnd& = UBOUND(A%, 2)
REDIM C%(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C%(Row&,Column&) = A%(Row&,Column&) - B%
NEXT Row&
NEXT Column&
END SUB ' | IMatrixScalarSubtract
REM ******************************************************************
REM * Matrix multiplication e.g. C%() = A%() * B%(). As such it is *
REM * easier to direct you to look at the source code for this *
REM * routine rather than to try to explain it, other than to say *
REM * that C%() is REDIM'ed according to the standard matrix formula *
REM ******************************************************************
SUB IMatrixMultiply(A%(), B%(), C%())
ID$ = "IMatrixMultiply"
ARowStart& = LBOUND(A%)
BRowStart& = LBOUND(B%)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A%, 2)
BColStart& = LBOUND(B%, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
BRowEnd& = UBOUND(B%)
AColEnd& = UBOUND(A%, 2)
IF AColEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(2) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A%)
BColEnd& = UBOUND(B%, 2)
REDIM C%(ARowStart& TO ARowEnd&, BColStart& TO BColEnd&)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = BColStart& To BColEnd&
Sum% = 0
FOR Z& = AColStart& TO AColEnd&
Sum% = Sum% + (A%(Row&, Z&) * B%(Z&, Column&))
NEXT Z&
C%(Row&,Column&) = Sum%
NEXT Column&
NEXT Row&
END SUB ' | IMatrixMultiply
REM ******************************************************************
REM * Matrix scalar multiplication e.g. C%() = A%() * B%. C%() is *
REM * REDIM'ed to be the same size as A%(). Each element of C%() is *
REM * assigned the result of multiplying the equivalent element of *
REM * A%() by B%. *
REM ******************************************************************
SUB IMatrixScalarMultiply(A%(), B%, C%())
ARowStart& = LBOUND(A%)
AColStart& = LBOUND(A%, 2)
ARowEnd& = UBOUND(A%)
AColEnd& = UBOUND(A%, 2)
REDIM C%(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C%(Row&,Column&) = A%(Row&,Column&) * B%
NEXT Row&
NEXT Column&
END SUB ' | IMatrixScalarMultiply
REM ******************************************************************
REM * Returns the maximum element contained in A%(). *
REM ******************************************************************
FUNCTION IMatrixMaximum%(A%())
MyMax% = -32768
ARowStart& = LBOUND(A%)
ARowEnd& = UBOUND(A%)
AColStart& = LBOUND(A%, 2)
AColEnd& = UBOUND(A%, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMax% < A%(Row&, Column&) THEN
MyMax% = A%(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
IMatrixMaximum% = MyMax%
END FUNCTION ' | IMatrixMaximum%
REM ******************************************************************
REM * Returns the minimum element contained in A%(). *
REM ******************************************************************
FUNCTION IMatrixMinimum%(A%())
MyMin% = 32767
ARowStart& = LBOUND(A%)
ARowEnd& = UBOUND(A%)
AColStart& = LBOUND(A%, 2)
AColEnd& = UBOUND(A%, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMin% > A%(Row&, Column&) THEN
MyMin% = A%(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
IMatrixMinimum% = MyMin%
END FUNCTION ' | IMatrixMinimum%
Next up is LONG Integer -
TR
RE: Huge Matrices Library - TarotRedhand - 05-04-2022
This section contains the following public routines -
Code: (Select All) ' Long Integer
SUB IdentityLMatrix(A&(), MatrixSize&)
SUB ZeroLMatrix(A&())
SUB ConLMatrix(A&())
SUB LMatrixNegate(A&())
SUB LMatrixTransPose(A&(), B&())
SUB LMatrixCopy(This&(), ToThis&())
SUB LMatrixPrint(A&())
SUB LMatrixFilePrint(A&(), FileNumber)
SUB LMatrixInput(A&())
SUB LMatrixFileInput(A&() , FileNum)
SUB LMatrixAdd(A&(), B&(), C&())
SUB LMatrixScalarAdd(A&(), B&, C&())
SUB LMatrixSubtract(A&(), B&(), C&())
SUB LMatrixScalarSubtract(A&(), B&, C&())
SUB LMatrixMultiply(A&(), B&(), C&())
SUB LMatrixScalarMultiply(A&(), B&, C&())
FUNCTION LMatrixMaximum&(A&())
FUNCTION LMatrixMinimum&(A&())
Actual code -
Code: (Select All) REM ******************************************************************
REM * This library deals with 2 dimensional arrays that are treated *
REM * as though they were mathematical matrices. I have included *
REM * all the routines that are associated with matrices that make *
REM * sense for the various TYPEs that are used. So for integers *
REM * and longs there no routines for mean, variance, inverse or *
REM * determinant. Also for singles and doubles I have left out *
REM * routines for inverse and determinant as their use is very *
REM * limited and specialised. *
REM ******************************************************************
REM ******************************************************************
REM * Private SUB only intended for use by the routines in this *
REM * library. *
REM ******************************************************************
SUB MatrixError(Where$, Fault$)
PRINT "Error in ";Where$;" - ";Fault$
STOP
END SUB ' | MatrixError
REM ******************************************************************
REM * Long Integer Matrices *
REM ******************************************************************
REM ******************************************************************
REM * A&() is REDIM'ed to be a square matrix with MatrixSize& rows *
REM * and MatrixSize& columns. All the elements of A&() are set to *
REM * zero except those where the row and the column are equal which *
REM * are set to one e.g. A&(1,1) = 1, A&(1,2) = 0. *
REM ******************************************************************
SUB IdentityLMatrix(A&(), MatrixSize&)
MatrixSize& = ABS(MatrixSize&)
REDIM A&(1 TO MatrixSize&, 1 TO MatrixSize&)
FOR Column& = 1 TO MatrixSize&
FOR Row& = 1 TO MatrixSize&
IF Row& = Column& THEN
A&(Row&,Column&) = 1
ELSE
A&(Row&,Column&) = 0
END IF
NEXT Row&
NEXT Column&
END SUB ' | IdentityLMatrix
REM ******************************************************************
REM * All the elements of A&() are set to zero. *
REM ******************************************************************
SUB ZeroLMatrix(A&())
ARowStart& = LBOUND(A&)
ARowEnd& = UBOUND(A&)
AColStart& = LBOUND(A&, 2)
AColEnd& = UBOUND(A&, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A&(Row&,Column&) = 0
NEXT Row&
NEXT Column&
END SUB ' | ZeroLMatrix
REM ******************************************************************
REM * All the elements of A&() are set to one. *
REM ******************************************************************
SUB ConLMatrix(A&())
ARowStart& = LBOUND(A&)
ARowEnd& = UBOUND(A&)
AColStart& = LBOUND(A&, 2)
AColEnd& = UBOUND(A&, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A&(Row&,Column&) = 1
NEXT Row&
NEXT Column&
END SUB ' | ConLMatrix
REM ******************************************************************
REM * LET A&() = -A&() e.g if A&(1,1) = 5 then after this routine *
REM * A&(1,1) = -5. *
REM ******************************************************************
SUB LMatrixNegate(A&())
ARowStart& = LBOUND(A&)
ARowEnd& = UBOUND(A&)
AColStart& = LBOUND(A&, 2)
AColEnd& = UBOUND(A&, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A&(Row&,Column&) = -A&(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | LMatrixNegate
REM ******************************************************************
REM * B&() is REDIM'ed to have the same number of columns as A&() *
REM * has rows and to have the same number of rows as A&() has *
REM * columns, and then the rows of A&() are copied to the columns *
REM * of B&(). *
REM ******************************************************************
SUB LMatrixTransPose(A&(), B&())
ARowStart& = LBOUND(A&)
AColStart& = LBOUND(A&, 2)
ARowEnd& = UBOUND(A&)
AColEnd& = UBOUND(A&, 2)
REDIM B&(AColStart& TO AColEnd&, ARowStart& TO ARowEnd&)
FOR P& = AColStart& TO AColEnd&
FOR Q& = ARowStart& TO ARowEnd&
B&(P&, Q&) = A&(Q&, P&)
NEXT Q&
NEXT P&
END SUB ' | LMatrixTransPose
REM ******************************************************************
REM * REDIM's ToThis&() to be the same size as This&() and then *
REM * copies the contents of This&() to ToThis&(). *
REM ******************************************************************
SUB LMatrixCopy(This&(), ToThis&())
RowStart& = LBOUND(This&)
RowFinish& = UBOUND(This&)
ColStart& = LBOUND(This&, 2)
ColFinish& = UBOUND(This&,2)
REDIM ToThis&(RowStart& TO RowFinish&, ColStart& TO ColFinish&)
FOR Column& = ColStart& TO ColFinish&
FOR Row& = RowStart& To RowFinish&
ToThis&(Row&,Column&) = This&(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | LMatrixCopy
REM ******************************************************************
REM * Display the contents of A&() on screen, formatted in columns. *
REM ******************************************************************
SUB LMatrixPrint(A&())
ARowStart& = LBOUND(A&)
ARowEnd& = UBOUND(A&)
AColStart& = LBOUND(A&, 2)
AColEnd& = UBOUND(A&, 2)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT A&(Row&,Column&);" ";
NEXT Column&
PRINT
NEXT Row&
END SUB ' | LMatrixPrint
REM ******************************************************************
REM * Saves the contents of A&() to the file specified by FileNumber *
REM ******************************************************************
SUB LMatrixFilePrint(A&(), FileNumber)
ARowStart& = LBOUND(A&)
PRINT #FileNumber, ARowStart&;" ";
ARowEnd& = UBOUND(A&)
PRINT #FileNumber, ARowEnd&;" ";
AColStart& = LBOUND(A&, 2)
PRINT #FileNumber, AColStart&;" ";
AColEnd& = UBOUND(A&, 2)
PRINT #FileNumber, AColEnd&;" ";
PRINT #FileNumber,
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT #FileNumber, A&(Row&,Column&);" ";
NEXT Column&
PRINT #FileNumber,
NEXT Row&
END SUB ' | LMatrixFilePrint
REM ******************************************************************
REM * This routine is for the sadists and masochists among you in *
REM * that it inputs all the information necessary to create and *
REM * fill a matrix from the keyboard. *
REM ******************************************************************
SUB LMatrixInput(A&())
INPUT"Lowest subscript for A&(1):",A
INPUT"Highest subscript for A&(1):",B
INPUT"Lowest subscript for A&(2):",C
INPUT"Lowest subscript for A&(2):",D
REDIM A&(A TO B, C TO D)
PRINT
FOR Row& = A TO B
FOR Column& = C TO D
PRINT "Enter value for position ";Row&;", ";Column&;":";
INPUT A
A&(Row&,Column&) = FIX(A)
NEXT Column&
NEXT Row&
END SUB ' | LMatrixInput
REM ******************************************************************
REM * This routine reads all the information necessary to create and *
REM * fill a matrix ( A&() ) from a file specified by filenum. This *
REM * routine is the complement to IMatrixFilePrint and retrieves *
REM * the information in the same order as that routine writes it. *
REM ******************************************************************
SUB LMatrixFileInput(A&() , FileNum)
INPUT #FileNum, A
INPUT #FileNum, B
INPUT #FileNum, C
INPUT #FileNum, D
A = ABS(FIX(A))
B = ABS(FIX(B))
C = ABS(FIX(C))
D = ABS(FIX(D))
REDIM A&(A TO B, C TO D)
FOR Row& = A TO B
FOR Column& = C TO D
INPUT #FileNum, A
A&(Row&,Column&) = FIX(A)
NEXT Column&
NEXT Row&
END SUB ' | LMatrixFileInput
REM ******************************************************************
REM * Matrix addition e.g. C&() = A&() + B&(). A&() and B&() must *
REM * have identical upper and lower bounds. C&() is REDIM'ed to be *
REM * the same size. Each element of C&() is assigned the result of *
REM * adding the equivalent elements in A&() and B&(). *
REM ******************************************************************
SUB LMatrixAdd(A&(), B&(), C&())
ID$ = "LMatrixAdd"
ARowStart& = LBOUND(A&)
BRowStart& = LBOUND(B&)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A&)
BRowEnd& = UBOUND(B&)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A&, 2)
BColStart& = LBOUND(B&, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
AColEnd& = UBOUND(A&, 2)
BColEnd& = UBOUND(B&, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
REDIM C&(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C&(Row&,Column&) = A&(Row&,Column&) + B&(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | LMatrixAdd
REM ******************************************************************
REM * Matrix scalar addition e.g. C&() = A&() + B&. C&() is *
REM * REDIM'ed to be identical in size to A&(). Each element of *
REM * C&() is assigned the result of adding B& to the equivalent *
REM * elements in A&(). *
REM ******************************************************************
SUB LMatrixScalarAdd(A&(), B&, C&())
ARowStart& = LBOUND(A&)
ARowEnd& = UBOUND(A&)
AColStart& = LBOUND(A&, 2)
AColEnd& = UBOUND(A&, 2)
REDIM C&(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C&(Row&,Column&) = A&(Row&,Column&) + B&
NEXT Row&
NEXT Column&
END SUB ' | LMatrixScalarAdd
REM ******************************************************************
REM * Matrix subtraction e.g. C&() = A&() - B&(). A&() and B&() *
REM * must have identical upper and lower bounds. C&() is REDIM'ed *
REM * to be the same size. Each element of C&() is assigned the *
REM * result of subtracting the equivalent element of B&() from the *
REM * equivalent element of A&(). *
REM ******************************************************************
SUB LMatrixSubtract(A&(), B&(), C&())
ID$ = "LMatrixSubtract"
ARowStart& = LBOUND(A&)
BRowStart& = LBOUND(B&)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A&)
BRowEnd& = UBOUND(B&)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A&, 2)
BColStart& = LBOUND(B&, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
AColEnd& = UBOUND(A&, 2)
BColEnd& = UBOUND(B&, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
REDIM C&(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C&(Row&,Column&) = A&(Row&,Column&) - B&(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | LMatrixSubtract
REM ******************************************************************
REM * Matrix scalar subtraction e.g. C&() = A&() - B&. C&() is *
REM * REDIM'ed to be the same size as A&(). Each element of C&() is *
REM * assigned the result of subtracting B& from the equivalent of *
REM * A&(). *
REM ******************************************************************
SUB LMatrixScalarSubtract(A&(), B&, C&())
ARowStart& = LBOUND(A&)
ARowEnd& = UBOUND(A&)
AColStart& = LBOUND(A&, 2)
AColEnd& = UBOUND(A&, 2)
REDIM C&(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C&(Row&,Column&) = A&(Row&,Column&) - B&
NEXT Row&
NEXT Column&
END SUB ' | LMatrixScalarSubtract
REM ******************************************************************
REM * Matrix multiplication e.g. C&() = A&() * B&(). As such it is *
REM * easier to direct you to look at the source code for this *
REM * routine rather than to try to explain it, other than to say *
REM * that C&() is REDIM'ed according to the standard matrix formula *
REM ******************************************************************
SUB LMatrixMultiply(A&(), B&(), C&())
ID$ = "LMatrixMultiply"
ARowStart& = LBOUND(A&)
BRowStart& = LBOUND(B&)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A&, 2)
BColStart& = LBOUND(B&, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
BRowEnd& = UBOUND(B&)
AColEnd& = UBOUND(A&, 2)
IF AColEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(2) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A&)
BColEnd& = UBOUND(B&, 2)
REDIM C&(ARowStart& TO ARowEnd&, BColStart& TO BColEnd&)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = BColStart& To BColEnd&
Sum& = 0
FOR Z& = AColStart& TO AColEnd&
Sum& = Sum& + (A&(Row&, Z&) * B&(Z&, Column&))
NEXT Z&
C&(Row&,Column&) = Sum&
NEXT Column&
NEXT Row&
END SUB ' | LMatrixMultiply
REM ******************************************************************
REM * Matrix scalar multiplication e.g. C&() = A&() * B&. C&() is *
REM * REDIM'ed to be the same size as A&(). Each element of C&() is *
REM * assigned the result of multiplying the equivalent element of *
REM * A&() by B&. *
REM ******************************************************************
SUB LMatrixScalarMultiply(A&(), B&, C&())
ARowStart& = LBOUND(A&)
AColStart& = LBOUND(A&, 2)
ARowEnd& = UBOUND(A&)
AColEnd& = UBOUND(A&, 2)
REDIM C&(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C&(Row&,Column&) = A&(Row&,Column&) * B&
NEXT Row&
NEXT Column&
END SUB ' | LMatrixScalarMultiply
REM ******************************************************************
REM * Returns the maximum element contained in A&(). *
REM ******************************************************************
FUNCTION LMatrixMaximum&(A&())
MyMax& = -2147483648
ARowStart& = LBOUND(A&)
ARowEnd& = UBOUND(A&)
AColStart& = LBOUND(A&, 2)
AColEnd& = UBOUND(A&, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMax& < A&(Row&, Column&) THEN
MyMax& = A&(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
LMatrixMaximum& = MyMax&
END FUNCTION ' | LMatrixMaximum&
REM ******************************************************************
REM * Returns the minimum element contained in A&(). *
REM ******************************************************************
FUNCTION LMatrixMinimum&(A&())
MyMin& = 2147483647
ARowStart& = LBOUND(A&)
ARowEnd& = UBOUND(A&)
AColStart& = LBOUND(A&, 2)
AColEnd& = UBOUND(A&, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMin& > A&(Row&, Column&) THEN
MyMin& = A&(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
LMatrixMinimum& = MyMin&
END FUNCTION ' | LMatrixMinimum&
Next up _INTEGER64 -
TR
RE: Huge Matrices Library - TarotRedhand - 05-04-2022
This section contains the following public routines -
Code: (Select All) ' _INTEGER64
SUB IdentityHMatrix(A&&(), MatrixSize%)
SUB ZeroHMatrix(A&&())
SUB ConHMatrix(A&&())
SUB HMatrixNegate(A&&())
SUB HMatrixTransPose(A&&(), B&&())
SUB HMatrixCopy(This&&(), ToThis&&())
SUB HMatrixPrint(A&&())
SUB HMatrixFilePrint(A&&(), FileNumber)
SUB HMatrixInput(A&&())
SUB HMatrixFileInput(A&&() , FileNum)
SUB HMatrixAdd(A&&(), B&&(), C&&())
SUB HMatrixScalarAdd(A&&(), B&&, C&&())
SUB HMatrixSubtract(A&&(), B&&(), C&&())
SUB HMatrixScalarSubtract(A&&(), B&&, C&&())
SUB HMatrixMultiply(A&&(), B&&(), C&&())
SUB HMatrixScalarMultiply(A&&(), B&&, C&&())
FUNCTION HMatrixMaximum&&(A&&())
FUNCTION HMatrixMinimum&&(A&&())
Actual SUBs/FUNCTIONs -
Code: (Select All) REM ******************************************************************
REM * This library deals with 2 dimensional arrays that are treated *
REM * as though they were mathematical matrices. I have included *
REM * all the routines that are associated with matrices that make *
REM * sense for the various TYPEs that are used. So for integers *
REM * and longs there no routines for mean, variance, inverse or *
REM * determinant. Also for singles and doubles I have left out *
REM * routines for inverse and determinant as their use is very *
REM * limited and specialised. *
REM ******************************************************************
REM ******************************************************************
REM * Private SUB only intended for use by the routines in this *
REM * library. *
REM ******************************************************************
SUB MatrixError(Where$, Fault$)
PRINT "Error in ";Where$;" - ";Fault$
STOP
END SUB ' | MatrixError
REM ******************************************************************
REM * _INTEGER64 Matrices *
REM ******************************************************************
REM ******************************************************************
REM * A&&() is REDIM'ed to be a square matrix with MatrixSize&& rows *
REM * and MatrixSize&& columns. All the elements of A&&() are set to *
REM * zero except those where the row and the column are equal which *
REM * are set to one e.g. A&&(1,1) = 1, A&&(1,2) = 0. *
REM ******************************************************************
SUB IdentityHMatrix(A&&(), MatrixSize&&)
MatrixSize&& = ABS(MatrixSize&&)
REDIM A&&(1 TO MatrixSize&&, 1 TO MatrixSize&&)
FOR Column& = 1 TO MatrixSize&&
FOR Row& = 1 TO MatrixSize&&
IF Row& = Column& THEN
A&&(Row&,Column&) = 1
ELSE
A&&(Row&,Column&) = 0
END IF
NEXT Row&
NEXT Column&
END SUB ' | IdentityHMatrix
REM ******************************************************************
REM * All the elements of A&&() are set to zero. *
REM ******************************************************************
SUB ZeroHMatrix(A&&())
ARowStart& = LBOUND(A&&)
ARowEnd& = UBOUND(A&&)
AColStart& = LBOUND(A&&, 2)
AColEnd& = UBOUND(A&&, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A&&(Row&,Column&) = 0
NEXT Row&
NEXT Column&
END SUB ' | ZeroHMatrix
REM ******************************************************************
REM * All the elements of A&&() are set to one. *
REM ******************************************************************
SUB ConHMatrix(A&&())
ARowStart& = LBOUND(A&&)
ARowEnd& = UBOUND(A&&)
AColStart& = LBOUND(A&&, 2)
AColEnd& = UBOUND(A&&, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A&&(Row&,Column&) = 1
NEXT Row&
NEXT Column&
END SUB ' | ConHMatrix
REM ******************************************************************
REM * LET A&&() = -A&&() e.g if A&&(1,1) = 5 then after this routine *
REM * A&&(1,1) = -5. *
REM ******************************************************************
SUB HMatrixNegate(A&&())
ARowStart& = LBOUND(A&&)
ARowEnd& = UBOUND(A&&)
AColStart& = LBOUND(A&&, 2)
AColEnd& = UBOUND(A&&, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A&&(Row&,Column&) = -A&&(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | HMatrixNegate
REM ******************************************************************
REM * B&&() is REDIM'ed to have the same number of columns as A&&() *
REM * has rows and to have the same number of rows as A&&() has *
REM * columns, and then the rows of A&&() are copied to the columns *
REM * of B&&(). *
REM ******************************************************************
SUB HMatrixTransPose(A&&(), B&&())
ARowStart& = LBOUND(A&&)
AColStart& = LBOUND(A&&, 2)
ARowEnd& = UBOUND(A&&)
AColEnd& = UBOUND(A&&, 2)
REDIM B&&(AColStart& TO AColEnd&, ARowStart& TO ARowEnd&)
FOR P& = AColStart& TO AColEnd&
FOR Q& = ARowStart& TO ARowEnd&
B&&(P&, Q&) = A&&(Q&, P&)
NEXT Q&
NEXT P&
END SUB ' | HMatrixTransPose
REM ******************************************************************
REM * REDIM's ToThis&&() to be the same size as This&&() and then *
REM * copies the contents of This&&() to ToThis&&(). *
REM ******************************************************************
SUB HMatrixCopy(This&&(), ToThis&&())
RowStart& = LBOUND(This&&)
RowFinish& = UBOUND(This&&)
ColStart& = LBOUND(This&&, 2)
ColFinish& = UBOUND(This&&,2)
REDIM ToThis&&(RowStart& TO RowFinish&, ColStart& TO ColFinish&)
FOR Column& = ColStart& TO ColFinish&
FOR Row& = RowStart& To RowFinish&
ToThis&&(Row&,Column&) = This&&(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | HMatrixCopy
REM ******************************************************************
REM * Display the contents of A&&() on screen, formatted in columns. *
REM ******************************************************************
SUB HMatrixPrint(A&&())
ARowStart& = LBOUND(A&&)
ARowEnd& = UBOUND(A&&)
AColStart& = LBOUND(A&&, 2)
AColEnd& = UBOUND(A&&, 2)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT A&&(Row&,Column&);" ";
NEXT Column&
PRINT
NEXT Row&
END SUB ' | HMatrixPrint
REM ******************************************************************
REM * Saves the contents of A&&() to the file specified by FileNumber *
REM ******************************************************************
SUB HMatrixFilePrint(A&&(), FileNumber)
ARowStart& = LBOUND(A&&)
PRINT #FileNumber, ARowStart&;" ";
ARowEnd& = UBOUND(A&&)
PRINT #FileNumber, ARowEnd&;" ";
AColStart& = LBOUND(A&&, 2)
PRINT #FileNumber, AColStart&;" ";
AColEnd& = UBOUND(A&&, 2)
PRINT #FileNumber, AColEnd&;" ";
PRINT #FileNumber,
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT #FileNumber, A&&(Row&,Column&);" ";
NEXT Column&
PRINT #FileNumber,
NEXT Row&
END SUB ' | HMatrixFilePrint
REM ******************************************************************
REM * This routine is for the sadists and masochists among you in *
REM * that it inputs all the information necessary to create and *
REM * fill a matrix from the keyboard. *
REM ******************************************************************
SUB HMatrixInput(A&&())
INPUT"Lowest subscript for A&&(1):",A
INPUT"Highest subscript for A&&(1):",B
INPUT"Lowest subscript for A&&(2):",C
INPUT"Lowest subscript for A&&(2):",D
REDIM A&&(A TO B, C TO D)
PRINT
FOR Row& = A TO B
FOR Column& = C TO D
PRINT "Enter value for position ";Row&;", ";Column&;":";
INPUT A
A&&(Row&,Column&) = FIX(A)
NEXT Column&
NEXT Row&
END SUB ' | HMatrixInput
REM ******************************************************************
REM * This routine reads all the information necessary to create and *
REM * fill a matrix ( A&&() ) from a file specified by filenum. This *
REM * routine is the complement to IMatrixFilePrint and retrieves *
REM * the information in the same order as that routine writes it. *
REM ******************************************************************
SUB HMatrixFileInput(A&&() , FileNum)
INPUT #FileNum, A
INPUT #FileNum, B
INPUT #FileNum, C
INPUT #FileNum, D
A = ABS(FIX(A))
B = ABS(FIX(B))
C = ABS(FIX(C))
D = ABS(FIX(D))
REDIM A&&(A TO B, C TO D)
FOR Row& = A TO B
FOR Column& = C TO D
INPUT #FileNum, A
A&&(Row&,Column&) = FIX(A)
NEXT Column&
NEXT Row&
END SUB ' | HMatrixFileInput
REM ******************************************************************
REM * Matrix addition e.g. C&&() = A&&() + B&&(). A&&() and B&&() must *
REM * have identical upper and lower bounds. C&&() is REDIM'ed to be *
REM * the same size. Each element of C&&() is assigned the result of *
REM * adding the equivalent elements in A&&() and B&&(). *
REM ******************************************************************
SUB HMatrixAdd(A&&(), B&&(), C&&())
ID$ = "HMatrixAdd"
ARowStart& = LBOUND(A&&)
BRowStart& = LBOUND(B&&)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A&&)
BRowEnd& = UBOUND(B&&)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A&&, 2)
BColStart& = LBOUND(B&&, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
AColEnd& = UBOUND(A&&, 2)
BColEnd& = UBOUND(B&&, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
REDIM C&&(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C&&(Row&,Column&) = A&&(Row&,Column&) + B&&(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | HMatrixAdd
REM ******************************************************************
REM * Matrix scalar addition e.g. C&&() = A&&() + B&&. C&&() is *
REM * REDIM'ed to be identical in size to A&&(). Each element of *
REM * C&&() is assigned the result of adding B&& to the equivalent *
REM * elements in A&&(). *
REM ******************************************************************
SUB HMatrixScalarAdd(A&&(), B&&, C&&())
ARowStart& = LBOUND(A&&)
ARowEnd& = UBOUND(A&&)
AColStart& = LBOUND(A&&, 2)
AColEnd& = UBOUND(A&&, 2)
REDIM C&&(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C&&(Row&,Column&) = A&&(Row&,Column&) + B&&
NEXT Row&
NEXT Column&
END SUB ' | HMatrixScalarAdd
REM ******************************************************************
REM * Matrix subtraction e.g. C&&() = A&&() - B&&(). A&&() and B&&() *
REM * must have identical upper and lower bounds. C&&() is REDIM'ed *
REM * to be the same size. Each element of C&&() is assigned the *
REM * result of subtracting the equivalent element of B&&() from the *
REM * equivalent element of A&&(). *
REM ******************************************************************
SUB HMatrixSubtract(A&&(), B&&(), C&&())
ID$ = "HMatrixSubtract"
ARowStart& = LBOUND(A&&)
BRowStart& = LBOUND(B&&)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A&&)
BRowEnd& = UBOUND(B&&)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A&&, 2)
BColStart& = LBOUND(B&&, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
AColEnd& = UBOUND(A&&, 2)
BColEnd& = UBOUND(B&&, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
REDIM C&&(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C&&(Row&,Column&) = A&&(Row&,Column&) - B&&(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | HMatrixSubtract
REM ******************************************************************
REM * Matrix scalar subtraction e.g. C&&() = A&&() - B&&. C&&() is *
REM * REDIM'ed to be the same size as A&&(). Each element of C&&() is *
REM * assigned the result of subtracting B&& from the equivalent of *
REM * A&&(). *
REM ******************************************************************
SUB HMatrixScalarSubtract(A&&(), B&&, C&&())
ARowStart& = LBOUND(A&&)
ARowEnd& = UBOUND(A&&)
AColStart& = LBOUND(A&&, 2)
AColEnd& = UBOUND(A&&, 2)
REDIM C&&(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C&&(Row&,Column&) = A&&(Row&,Column&) - B&&
NEXT Row&
NEXT Column&
END SUB ' | HMatrixScalarSubtract
REM ******************************************************************
REM * Matrix multiplication e.g. C&&() = A&&() * B&&(). As such it is *
REM * easier to direct you to look at the source code for this *
REM * routine rather than to try to explain it, other than to say *
REM * that C&&() is REDIM'ed according to the standard matrix formula *
REM ******************************************************************
SUB HMatrixMultiply(A&&(), B&&(), C&&())
ID$ = "HMatrixMultiply"
ARowStart& = LBOUND(A&&)
BRowStart& = LBOUND(B&&)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A&&, 2)
BColStart& = LBOUND(B&&, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
BRowEnd& = UBOUND(B&&)
AColEnd& = UBOUND(A&&, 2)
IF AColEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(2) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A&&)
BColEnd& = UBOUND(B&&, 2)
REDIM C&&(ARowStart& TO ARowEnd&, BColStart& TO BColEnd&)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = BColStart& To BColEnd&
Sum&& = 0
FOR Z& = AColStart& TO AColEnd&
Sum&& = Sum&& + (A&&(Row&, Z&) * B&&(Z&, Column&))
NEXT Z&
C&&(Row&,Column&) = Sum&&
NEXT Column&
NEXT Row&
END SUB ' | HMatrixMultiply
REM ******************************************************************
REM * Matrix scalar multiplication e.g. C&&() = A&&() * B&&. C&&() is *
REM * REDIM'ed to be the same size as A&&(). Each element of C&&() is *
REM * assigned the result of multiplying the equivalent element of *
REM * A&&() by B&&. *
REM ******************************************************************
SUB HMatrixScalarMultiply(A&&(), B&&, C&&())
ARowStart& = LBOUND(A&&)
AColStart& = LBOUND(A&&, 2)
ARowEnd& = UBOUND(A&&)
AColEnd& = UBOUND(A&&, 2)
REDIM C&&(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C&&(Row&,Column&) = A&&(Row&,Column&) * B&&
NEXT Row&
NEXT Column&
END SUB ' | HMatrixScalarMultiply
REM ******************************************************************
REM * Returns the maximum element contained in A&&(). *
REM ******************************************************************
FUNCTION HMatrixMaximum&&(A&&())
MyMax&& = -9223372036854775808
ARowStart& = LBOUND(A&&)
ARowEnd& = UBOUND(A&&)
AColStart& = LBOUND(A&&, 2)
AColEnd& = UBOUND(A&&, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMax&& < A&&(Row&, Column&) THEN
MyMax&& = A&&(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
HMatrixMaximum&& = MyMax&&
END FUNCTION ' | HMatrixMaximum&&
REM ******************************************************************
REM * Returns the minimum element contained in A&&(). *
REM ******************************************************************
FUNCTION HMatrixMinimum&&(A&&())
MyMin&& = 9223372036854775807
ARowStart& = LBOUND(A&&)
ARowEnd& = UBOUND(A&&)
AColStart& = LBOUND(A&&, 2)
AColEnd& = UBOUND(A&&, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMin&& > A&&(Row&, Column&) THEN
MyMin&& = A&&(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
HMatrixMinimum&& = MyMin&&
END FUNCTION ' | HMatrixMinimum&&
SINGLE precision floating point next post -
TR
RE: Huge Matrices Library - TarotRedhand - 05-04-2022
This section contains the following public routines -
Code: (Select All) ' Single precision floating point
SUB IdentitySMatrix(A!(), MatrixSize%)
SUB ZeroSMatrix(A!())
SUB ConSMatrix(A!())
SUB SMatrixNegate(A!())
SUB SMatrixTransPose(A!(), B!())
SUB SMatrixCopy(This!(), ToThis!())
SUB SMatrixPrint(A!())
SUB SMatrixFilePrint(A!(), FileNumber)
SUB SMatrixInput(A!())
SUB SMatrixFileInput(A!() , FileNum)
SUB SMatrixAdd(A!(), B!(), C!())
SUB SMatrixScalarAdd(A!(), B!, C!())
SUB SMatrixSubtract(A!(), B!(), C!())
SUB SMatrixScalarSubtract(A!(), B!, C!())
SUB SMatrixMultiply(A!(), B!(), C!())
SUB SMatrixScalarMultiply(A!(), B!, C!())
FUNCTION SMatrixMaximum!(A!())
FUNCTION SMatrixMinimum!(A!())
FUNCTION SMatrixMean!(A!())
FUNCTION SMatrixVariance!(A!())
Actual library -
Code: (Select All) REM ******************************************************************
REM * This library deals with 2 dimensional arrays that are treated *
REM * as though they were mathematical matrices. I have included *
REM * all the routines that are associated with matrices that make *
REM * sense for the various TYPEs that are used. So for integers *
REM * and longs there no routines for mean, variance, inverse or *
REM * determinant. Also for singles and doubles I have left out *
REM * routines for inverse and determinant as their use is very *
REM * limited and specialised. *
REM ******************************************************************
REM ******************************************************************
REM * Private SUB only intended for use by the routines in this *
REM * library. *
REM ******************************************************************
SUB MatrixError(Where$, Fault$)
PRINT "Error in ";Where$;" - ";Fault$
STOP
END SUB ' | MatrixError
REM ******************************************************************
REM * Single precision floating point Matrices *
REM ******************************************************************
REM ******************************************************************
REM * A!() is REDIM'ed to be a square matrix with MatrixSize! rows *
REM * and MatrixSize! columns. All the elements of A!() are set to *
REM * zero except those where the row and the column are equal which *
REM * are set to one e.g. A!(1,1) = 1, A!(1,2) = 0. *
REM ******************************************************************
SUB IdentitySMatrix(A!(), MatrixSize&)
MatrixSize& = ABS(MatrixSize&)
REDIM A!(1 TO MatrixSize&, 1 TO MatrixSize&)
FOR Column& = 1 TO MatrixSize&
FOR Row& = 1 TO MatrixSize&
IF Row& = Column& THEN
A!(Row&,Column&) = 1.0
ELSE
A!(Row&,Column&) = 0.0
END IF
NEXT Row&
NEXT Column&
END SUB ' | IdentitySMatrix
REM ******************************************************************
REM * All the elements of A!() are set to zero. *
REM ******************************************************************
SUB ZeroSMatrix(A!())
ARowStart& = LBOUND(A!)
ARowEnd& = UBOUND(A!)
AColStart& = LBOUND(A!, 2)
AColEnd& = UBOUND(A!, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A!(Row&,Column&) = 0.0
NEXT Row&
NEXT Column&
END SUB ' | ZeroSMatrix
REM ******************************************************************
REM * All the elements of A!() are set to one. *
REM ******************************************************************
SUB ConSMatrix(A!())
ARowStart& = LBOUND(A!)
ARowEnd& = UBOUND(A!)
AColStart& = LBOUND(A!, 2)
AColEnd& = UBOUND(A!, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A!(Row&,Column&) = 1.0
NEXT Row&
NEXT Column&
END SUB ' | ConSMatrix
REM ******************************************************************
REM * LET A!() = -A!() e.g if A!(1,1) = 5 then after this routine *
REM * A!(1,1) = -5. *
REM ******************************************************************
SUB SMatrixNegate(A!())
ARowStart& = LBOUND(A!)
ARowEnd& = UBOUND(A!)
AColStart& = LBOUND(A!, 2)
AColEnd& = UBOUND(A!, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A!(Row&,Column&) = -A!(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | SMatrixNegate
REM ******************************************************************
REM * B!() is REDIM'ed to have the same number of columns as A!() *
REM * has rows and to have the same number of rows as A!() has *
REM * columns, and then the rows of A!() are copied to the columns *
REM * of B!(). *
REM ******************************************************************
SUB SMatrixTransPose(A!(), B!())
ARowStart& = LBOUND(A!)
AColStart& = LBOUND(A!, 2)
ARowEnd& = UBOUND(A!)
AColEnd& = UBOUND(A!, 2)
REDIM B!(AColStart& TO AColEnd&, ARowStart& TO ARowEnd&)
FOR P& = AColStart& TO AColEnd&
FOR Q& = ARowStart& TO ARowEnd&
B!(P&, Q&) = A!(Q&, P&)
NEXT Q&
NEXT P&
END SUB ' | SMatrixTransPose
REM ******************************************************************
REM * REDIM's ToThis!() to be the same size as This!() and then *
REM * copies the contents of This!() to ToThis!(). *
REM ******************************************************************
SUB SMatrixCopy(This!(), ToThis!())
RowStart& = LBOUND(This!)
RowFinish& = UBOUND(This!)
ColStart& = LBOUND(This!, 2)
ColFinish& = UBOUND(This!,2)
REDIM ToThis!(RowStart& TO RowFinish&, ColStart& TO ColFinish&)
FOR Column& = ColStart& TO ColFinish&
FOR Row& = RowStart& To RowFinish&
ToThis!(Row&,Column&) = This!(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | SMatrixCopy
REM ******************************************************************
REM * Display the contents of A!() on screen, formatted in columns. *
REM ******************************************************************
SUB SMatrixPrint(A!())
ARowStart& = LBOUND(A!)
ARowEnd& = UBOUND(A!)
AColStart& = LBOUND(A!, 2)
AColEnd& = UBOUND(A!, 2)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT A!(Row&,Column&);" ";
NEXT Column&
PRINT
NEXT Row&
END SUB ' | SMatrixPrint
REM ******************************************************************
REM * Saves the contents of A!() to the file specified by FileNumber *
REM ******************************************************************
SUB SMatrixFilePrint(A!(), FileNumber)
ARowStart& = LBOUND(A!)
PRINT #FileNumber, ARowStart&;" ";
ARowEnd& = UBOUND(A!)
PRINT #FileNumber, ARowEnd&;" ";
AColStart& = LBOUND(A!, 2)
PRINT #FileNumber, AColStart&;" ";
AColEnd& = UBOUND(A!, 2)
PRINT #FileNumber, AColEnd&;" ";
PRINT #FileNumber,
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT #FileNumber, A!(Row&,Column&);" ";
NEXT Column&
PRINT #FileNumber,
NEXT Row&
END SUB ' | SMatrixFilePrint
REM ******************************************************************
REM * This routine is for the sadists and masochists among you in *
REM * that it inputs all the information necessary to create and *
REM * fill a matrix fromthe keyboard. *
REM ******************************************************************
SUB SMatrixInput(A!())
INPUT"Lowest subscript for A!(1):",A
INPUT"Highest subscript for A!(1):",B
INPUT"Lowest subscript for A!(2):",C
INPUT"Lowest subscript for A!(2):",D
REDIM A!(A TO B, C TO D)
PRINT
FOR Row& = A TO B
FOR Column& = C TO D
PRINT "Enter value for position ";Row&;", ";Column&;":";
INPUT A
A!(Row&,Column&) = FIX(A)
NEXT Column&
NEXT Row&
END SUB ' | SMatrixInput
REM ******************************************************************
REM * This routine reads all the information necessary to create and *
REM * fill a matrix ( A!() ) from a file specified by filenum. This *
REM * routine is the complement to IMatrixFilePrint and retrieves *
REM * the information in the same order as that routine writes it. *
REM ******************************************************************
SUB SMatrixFileInput(A!() , FileNum)
INPUT #FileNum, A
INPUT #FileNum, B
INPUT #FileNum, C
INPUT #FileNum, D
A = ABS(FIX(A))
B = ABS(FIX(B))
C = ABS(FIX(C))
D = ABS(FIX(D))
REDIM A!(A TO B, C TO D)
FOR Row& = A TO B
FOR Column& = C TO D
INPUT #FileNum, A!(Row&,Column&)
NEXT Column&
NEXT Row&
END SUB ' | SMatrixFileInput
REM ******************************************************************
REM * Matrix addition e.g. C!() = A!() + B!(). A!() and B!() must *
REM * have identical upper and lower bounds. C!() is REDIM'ed to be *
REM * the same size. Each element of C!() is assigned the result of *
REM * adding the equivalent elements in A!() and B!(). *
REM ******************************************************************
SUB SMatrixAdd(A!(), B!(), C!())
ID$ = "SMatrixAdd"
ARowStart& = LBOUND(A!)
BRowStart& = LBOUND(B!)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A!)
BRowEnd& = UBOUND(B!)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A!, 2)
BColStart& = LBOUND(B!, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
AColEnd& = UBOUND(A!, 2)
BColEnd& = UBOUND(B!, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
REDIM C!(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C!(Row&,Column&) = A!(Row&,Column&) + B!(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | SMatrixAdd
REM ******************************************************************
REM * Matrix scalar addition e.g. C!() = A!() + B!. C!() is *
REM * REDIM'ed to be identical in size to A!(). Each element of *
REM * C!() is assigned the result of adding B! to the equivalent *
REM * elements in A!(). *
REM ******************************************************************
SUB SMatrixScalarAdd(A!(), B!, C!())
ARowStart& = LBOUND(A!)
ARowEnd& = UBOUND(A!)
AColStart& = LBOUND(A!, 2)
AColEnd& = UBOUND(A!, 2)
REDIM C!(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C!(Row&,Column&) = A!(Row&,Column&) + B!
NEXT Row&
NEXT Column&
END SUB ' | SMatrixScalarAdd
REM ******************************************************************
REM * Matrix subtraction e.g. C!() = A!() - B!(). A!() and B!() *
REM * must have identical upper and lower bounds. C!() is REDIM'ed *
REM * to be the same size. Each element of C!() is assigned the *
REM * result of subtracting the equivalent element of B!() from the *
REM * equivalent element of A!(). *
REM ******************************************************************
SUB SMatrixSubtract(A!(), B!(), C!())
ID$ = "SMatrixSubtract"
ARowStart& = LBOUND(A!)
BRowStart& = LBOUND(B!)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A!)
BRowEnd& = UBOUND(B!)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A!, 2)
BColStart& = LBOUND(B!, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
AColEnd& = UBOUND(A!, 2)
BColEnd& = UBOUND(B!, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical!"
END IF
REDIM C!(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C!(Row&,Column&) = A!(Row&,Column&) - B!(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | SMatrixSubtract
REM ******************************************************************
REM * Matrix scalar subtraction e.g. C!() = A!() - B!. C!() is *
REM * REDIM'ed to be the same size as A!(). Each element of C!() is *
REM * assigned the result of subtracting B! from the equivalent of *
REM * A!(). *
REM ******************************************************************
SUB SMatrixScalarSubtract(A!(), B!, C!())
ARowStart& = LBOUND(A!)
ARowEnd& = UBOUND(A!)
AColStart& = LBOUND(A!, 2)
AColEnd& = UBOUND(A!, 2)
REDIM C!(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C!(Row&,Column&) = A!(Row&,Column&) - B!
NEXT Row&
NEXT Column&
END SUB ' | SMatrixScalarSubtract
REM ******************************************************************
REM * Matrix multiplication e.g. C!() = A!() * B!(). As such it is *
REM * easier to direct you to look at the source code for this *
REM * routine rather than to try to explain it, other than to say *
REM * that C!() is REDIM'ed according to the standard matrix formula *
REM ******************************************************************
SUB SMatrixMultiply(A!(), B!(), C!())
ID$ = "SMatrixMultiply"
ARowStart& = LBOUND(A!)
BRowStart& = LBOUND(B!)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical!"
END IF
AColStart& = LBOUND(A!, 2)
BColStart& = LBOUND(B!, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical!"
END IF
BRowEnd& = UBOUND(B!)
AColEnd& = UBOUND(A!, 2)
IF AColEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(2) and B(1) not identical!"
END IF
ARowEnd& = UBOUND(A!)
BColEnd& = UBOUND(B!, 2)
REDIM C!(ARowStart& TO ARowEnd&, BColStart& TO BColEnd&)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = BColStart& To BColEnd&
Sum! = 0.0
FOR Z& = AColStart& TO AColEnd&
Sum! = Sum! + (A!(Row&, Z&) * B!(Z&, Column&))
NEXT Z&
C!(Row&,Column&) = Sum!
NEXT Column&
NEXT Row&
END SUB ' | SMatrixMultiply
REM ******************************************************************
REM * Matrix scalar multiplication e.g. C!() = A!() * B!. C!() is *
REM * REDIM'ed to be the same size as A!(). Each element of C!() is *
REM * assigned the result of multiplying the equivalent element of *
REM * A!() by B!. *
REM ******************************************************************
SUB SMatrixScalarMultiply(A!(), B!, C!())
ARowStart& = LBOUND(A!)
AColStart& = LBOUND(A!, 2)
ARowEnd& = UBOUND(A!)
AColEnd& = UBOUND(A!, 2)
REDIM C!(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C!(Row&,Column&) = A!(Row&,Column&) * B!
NEXT Row&
NEXT Column&
END SUB ' | SMatrixScalarMultiply
REM ******************************************************************
REM * Returns the maximum element contained in A!(). *
REM ******************************************************************
FUNCTION SMatrixMaximum!(A!())
MyMax! = -2.802597E-45
ARowStart& = LBOUND(A!)
ARowEnd& = UBOUND(A!)
AColStart& = LBOUND(A!, 2)
AColEnd& = UBOUND(A!, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMax! < A!(Row&, Column&) THEN
MyMax! = A!(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
SMatrixMaximum! = MyMax!
END FUNCTION ' | SMatrixMaximum!
REM ******************************************************************
REM * Returns the minimum element contained in A!(). *
REM ******************************************************************
FUNCTION SMatrixMinimum!(A!())
MyMin! = 3.402823E+38
ARowStart& = LBOUND(A!)
ARowEnd& = UBOUND(A!)
AColStart& = LBOUND(A!, 2)
AColEnd& = UBOUND(A!, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMin! > A!(Row&, Column&) THEN
MyMin! = A!(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
SMatrixMinimum! = MyMin!
END FUNCTION ' | SMatrixMinimum!
REM ******************************************************************
REM * Returns the Average of all the values contained in A!(). *
REM ******************************************************************
FUNCTION SMatrixMean!(A!())
Sum! = 0.0
ARowStart& = LBOUND(A!)
AColStart& = LBOUND(A!, 2)
ARowEnd& = UBOUND(A!)
AColEnd& = UBOUND(A!, 2)
FOR Column& = AColStart& TO AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
Sum! = Sum! + A!(Row&,Column&)
NEXT Row&
NEXT Column&
MatrixSize! = (1.0 + ARowEnd& - ARowStart&) * (1.0 + AColEnd& - AColStart&)
SMatrixMean! = Sum! / MatrixSize!
END FUNCTION ' | SMatrixMean!
REM ******************************************************************
REM * Returns the variance of all the values contained in A!(). *
REM ******************************************************************
FUNCTION SMatrixVariance!(A!())
SumSquared! = 0.0
MyMean! = SMatrixMean!(A!())
ARowStart& = LBOUND(A!)
AColStart& = LBOUND(A!, 2)
ARowEnd& = UBOUND(A!)
AColEnd& = UBOUND(A!, 2)
FOR Column& = AColStart& TO AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
Temp! = A!(Row&,Column&) - MyMean!
Temp! = Temp! * Temp!
SumSquared! = SumSquared! + Temp!
NEXT Row&
NEXT Column&
MatrixSize! = (1.0 + ARowEnd& - ARowStart&) * (1.0 + AColEnd& - AColStart&)
SMatrixVariance! = SumSquared! / (MatrixSize! - 1.0)
END FUNCTION ' | SMatrixVariance!
Next part DOUBLE precision floating point -
TR
RE: Huge Matrices Library - TarotRedhand - 05-04-2022
Contents are -
Code: (Select All) ' Double precision floating point
SUB IdentityDMatrix(A#(), MatrixSize%)
SUB ZeroDMatrix(A#())
SUB ConDMatrix(A#())
SUB DMatrixNegate(A#())
SUB DMatrixTransPose(A#(), B#())
SUB DMatrixCopy(This#(), ToThis#())
SUB DMatrixPrint(A#())
SUB DMatrixFilePrint(A#(), FileNumber)
SUB DMatrixInput(A#())
SUB DMatrixFileInput(A#() , FileNum)
SUB DMatrixAdd(A#(), B#(), C#())
SUB DMatrixScalarAdd(A#(), B#, C#())
SUB DMatrixSubtract(A#(), B#(), C#())
SUB DMatrixScalarSubtract(A#(), B#, C#())
SUB DMatrixMultiply(A#(), B#(), C#())
SUB DMatrixScalarMultiply(A#(), B#, C#())
FUNCTION DMatrixMaximum#(A#())
FUNCTION DMatrixMinimum#(A#())
FUNCTION DMatrixMean#(A#())
FUNCTION DMatrixVariance#(A#())
Library in this code box -
Code: (Select All) REM ******************************************************************
REM * This library deals with 2 dimensional arrays that are treated *
REM * as though they were mathematical matrices. I have included *
REM * all the routines that are associated with matrices that make *
REM * sense for the various TYPEs that are used. So for integers *
REM * and longs there no routines for mean, variance, inverse or *
REM * determinant. Also for singles and doubles I have left out *
REM * routines for inverse and determinant as their use is very *
REM * limited and specialised. *
REM ******************************************************************
REM ******************************************************************
REM * Private SUB only intended for use by the routines in this *
REM * library. *
REM ******************************************************************
SUB MatrixError(Where$, Fault$)
PRINT "Error in ";Where$;" - ";Fault$
STOP
END SUB ' | MatrixError
REM ******************************************************************
REM * Double precision floating point Matrices *
REM ******************************************************************
REM ******************************************************************
REM * A#() is REDIM'ed to be a square matrix with MatrixSize# rows *
REM * and MatrixSize# columns. All the elements of A#() are set to *
REM * zero except those where the row and the column are equal which *
REM * are set to one e.g. A#(1,1) = 1, A#(1,2) = 0. *
REM ******************************************************************
SUB IdentityDMatrix(A#(), MatrixSize&)
MatrixSize& = ABS(MatrixSize&)
REDIM A#(1 TO MatrixSize&, 1 TO MatrixSize&)
FOR Column& = 1 TO MatrixSize&
FOR Row& = 1 TO MatrixSize&
IF Row& = Column& THEN
A#(Row&,Column&) = 1.0
ELSE
A#(Row&,Column&) = 0.0
END IF
NEXT Row&
NEXT Column&
END SUB ' | IdentityDMatrix
REM ******************************************************************
REM * All the elements of A#() are set to zero. *
REM ******************************************************************
SUB ZeroDMatrix(A#())
ARowStart& = LBOUND(A#)
ARowEnd& = UBOUND(A#)
AColStart& = LBOUND(A#, 2)
AColEnd& = UBOUND(A#, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A#(Row&,Column&) = 0.0
NEXT Row&
NEXT Column&
END SUB ' | ZeroDMatrix
REM ******************************************************************
REM * All the elements of A#() are set to one. *
REM ******************************************************************
SUB ConDMatrix(A#())
ARowStart& = LBOUND(A#)
ARowEnd& = UBOUND(A#)
AColStart& = LBOUND(A#, 2)
AColEnd& = UBOUND(A#, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A#(Row&,Column&) = 1.0
NEXT Row&
NEXT Column&
END SUB ' | ConDMatrix
REM ******************************************************************
REM * LET A#() = -A#() e.g if A#(1,1) = 5 then after this routine *
REM * A#(1,1) = -5. *
REM ******************************************************************
SUB DMatrixNegate(A#())
ARowStart& = LBOUND(A#)
ARowEnd& = UBOUND(A#)
AColStart& = LBOUND(A#, 2)
AColEnd& = UBOUND(A#, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A#(Row&,Column&) = -A#(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | DMatrixNegate
REM ******************************************************************
REM * B#() is REDIM'ed to have the same number of columns as A#() *
REM * has rows and to have the same number of rows as A#() has *
REM * columns, and then the rows of A#() are copied to the columns *
REM * of B#(). *
REM ******************************************************************
SUB DMatrixTransPose(A#(), B#())
ARowStart& = LBOUND(A#)
AColStart& = LBOUND(A#, 2)
ARowEnd& = UBOUND(A#)
AColEnd& = UBOUND(A#, 2)
REDIM B#(AColStart& TO AColEnd&, ARowStart& TO ARowEnd&)
FOR P& = AColStart& TO AColEnd&
FOR Q& = ARowStart& TO ARowEnd&
B#(P&, Q&) = A#(Q&, P&)
NEXT Q&
NEXT P&
END SUB ' | DMatrixTransPose
REM ******************************************************************
REM * REDIM's ToThis#() to be the same size as This#() and then *
REM * copies the contents of This#() to ToThis#(). *
REM ******************************************************************
SUB DMatrixCopy(This#(), ToThis#())
RowStart& = LBOUND(This#)
RowFinish& = UBOUND(This#)
ColStart& = LBOUND(This#, 2)
ColFinish& = UBOUND(This#,2)
REDIM ToThis#(RowStart& TO RowFinish&, ColStart& TO ColFinish&)
FOR Column& = ColStart& TO ColFinish&
FOR Row& = RowStart& To RowFinish&
ToThis#(Row&,Column&) = This#(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | DMatrixCopy
REM ******************************************************************
REM * Display the contents of A#() on screen, formatted in columns. *
REM ******************************************************************
SUB DMatrixPrint(A#())
ARowStart& = LBOUND(A#)
ARowEnd& = UBOUND(A#)
AColStart& = LBOUND(A#, 2)
AColEnd& = UBOUND(A#, 2)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT A#(Row&,Column&);" ";
NEXT Column&
PRINT
NEXT Row&
END SUB ' | DMatrixPrint
REM ******************************************************************
REM * Saves the contents of A#() to the file specified by FileNumber *
REM ******************************************************************
SUB DMatrixFilePrint(A#(), FileNumber)
ARowStart& = LBOUND(A#)
PRINT #FileNumber, ARowStart&;" ";
ARowEnd& = UBOUND(A#)
PRINT #FileNumber, ARowEnd&;" ";
AColStart& = LBOUND(A#, 2)
PRINT #FileNumber, AColStart&;" ";
AColEnd& = UBOUND(A#, 2)
PRINT #FileNumber, AColEnd&;" ";
PRINT #FileNumber,
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT #FileNumber, A#(Row&,Column&);" ";
NEXT Column&
PRINT #FileNumber,
NEXT Row&
END SUB ' | DMatrixFilePrint
REM ******************************************************************
REM * This routine is for the sadists and masochists among you in *
REM * that it inputs all the information necessary to create and *
REM * fill a matrix fromthe keyboard. *
REM ******************************************************************
SUB DMatrixInput(A#())
INPUT"Lowest subscript for A#(1):",A
INPUT"Highest subscript for A#(1):",B
INPUT"Lowest subscript for A#(2):",C
INPUT"Lowest subscript for A#(2):",D
REDIM A#(A TO B, C TO D)
PRINT
FOR Row& = A TO B
FOR Column& = C TO D
PRINT "Enter value for position ";Row&;", ";Column&;":";
INPUT A
A#(Row&,Column&) = FIX(A)
NEXT Column&
NEXT Row&
END SUB ' | DMatrixInput
REM ******************************************************************
REM * This routine reads all the information necessary to create and *
REM * fill a matrix ( A#() ) from a file specified by filenum. This *
REM * routine is the complement to IMatrixFilePrint and retrieves *
REM * the information in the same order as that routine writes it. *
REM ******************************************************************
SUB DMatrixFileInput(A#() , FileNum)
INPUT #FileNum, A
INPUT #FileNum, B
INPUT #FileNum, C
INPUT #FileNum, D
A = ABS(FIX(A))
B = ABS(FIX(B))
C = ABS(FIX(C))
D = ABS(FIX(D))
REDIM A#(A TO B, C TO D)
FOR Row& = A TO B
FOR Column& = C TO D
INPUT #FileNum, A#(Row&,Column&)
NEXT Column&
NEXT Row&
END SUB ' | DMatrixFileInput
REM ******************************************************************
REM * Matrix addition e.g. C#() = A#() + B#(). A#() and B#() must *
REM * have identical upper and lower bounds. C#() is REDIM'ed to be *
REM * the same size. Each element of C#() is assigned the result of *
REM * adding the equivalent elements in A#() and B#(). *
REM ******************************************************************
SUB DMatrixAdd(A#(), B#(), C#())
ID$ = "DMatrixAdd"
ARowStart& = LBOUND(A#)
BRowStart& = LBOUND(B#)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical#"
END IF
ARowEnd& = UBOUND(A#)
BRowEnd& = UBOUND(B#)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical#"
END IF
AColStart& = LBOUND(A#, 2)
BColStart& = LBOUND(B#, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical#"
END IF
AColEnd& = UBOUND(A#, 2)
BColEnd& = UBOUND(B#, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical#"
END IF
REDIM C#(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C#(Row&,Column&) = A#(Row&,Column&) + B#(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | DMatrixAdd
REM ******************************************************************
REM * Matrix scalar addition e.g. C#() = A#() + B#. C#() is *
REM * REDIM'ed to be identical in size to A#(). Each element of *
REM * C#() is assigned the result of adding B# to the equivalent *
REM * elements in A#(). *
REM ******************************************************************
SUB DMatrixScalarAdd(A#(), B#, C#())
ARowStart& = LBOUND(A#)
ARowEnd& = UBOUND(A#)
AColStart& = LBOUND(A#, 2)
AColEnd& = UBOUND(A#, 2)
REDIM C#(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C#(Row&,Column&) = A#(Row&,Column&) + B#
NEXT Row&
NEXT Column&
END SUB ' | DMatrixScalarAdd
REM ******************************************************************
REM * Matrix subtraction e.g. C#() = A#() - B#(). A#() and B#() *
REM * must have identical upper and lower bounds. C#() is REDIM'ed *
REM * to be the same size. Each element of C#() is assigned the *
REM * result of subtracting the equivalent element of B#() from the *
REM * equivalent element of A#(). *
REM ******************************************************************
SUB DMatrixSubtract(A#(), B#(), C#())
ID$ = "DMatrixSubtract"
ARowStart& = LBOUND(A#)
BRowStart& = LBOUND(B#)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical#"
END IF
ARowEnd& = UBOUND(A#)
BRowEnd& = UBOUND(B#)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical#"
END IF
AColStart& = LBOUND(A#, 2)
BColStart& = LBOUND(B#, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical#"
END IF
AColEnd& = UBOUND(A#, 2)
BColEnd& = UBOUND(B#, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical#"
END IF
REDIM C#(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C#(Row&,Column&) = A#(Row&,Column&) - B#(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | DMatrixSubtract
REM ******************************************************************
REM * Matrix scalar subtraction e.g. C#() = A#() - B#. C#() is *
REM * REDIM'ed to be the same size as A#(). Each element of C#() is *
REM * assigned the result of subtracting B# from the equivalent of *
REM * A#(). *
REM ******************************************************************
SUB DMatrixScalarSubtract(A#(), B#, C#())
ARowStart& = LBOUND(A#)
ARowEnd& = UBOUND(A#)
AColStart& = LBOUND(A#, 2)
AColEnd& = UBOUND(A#, 2)
REDIM C#(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C#(Row&,Column&) = A#(Row&,Column&) - B#
NEXT Row&
NEXT Column&
END SUB ' | DMatrixScalarSubtract
REM ******************************************************************
REM * Matrix multiplication e.g. C#() = A#() * B#(). As such it is *
REM * easier to direct you to look at the source code for this *
REM * routine rather than to try to explain it, other than to say *
REM * that C#() is REDIM'ed according to the standard matrix formula *
REM ******************************************************************
SUB DMatrixMultiply(A#(), B#(), C#())
ID$ = "DMatrixMultiply"
ARowStart& = LBOUND(A#)
BRowStart& = LBOUND(B#)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical#"
END IF
AColStart& = LBOUND(A#, 2)
BColStart& = LBOUND(B#, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical#"
END IF
BRowEnd& = UBOUND(B#)
AColEnd& = UBOUND(A#, 2)
IF AColEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(2) and B(1) not identical#"
END IF
ARowEnd& = UBOUND(A#)
BColEnd& = UBOUND(B#, 2)
REDIM C#(ARowStart& TO ARowEnd&, BColStart& TO BColEnd&)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = BColStart& To BColEnd&
Sum# = 0.0
FOR Z& = AColStart& TO AColEnd&
Sum# = Sum# + (A#(Row&, Z&) * B#(Z&, Column&))
NEXT Z&
C#(Row&,Column&) = Sum#
NEXT Column&
NEXT Row&
END SUB ' | DMatrixMultiply
REM ******************************************************************
REM * Matrix scalar multiplication e.g. C#() = A#() * B#. C#() is *
REM * REDIM'ed to be the same size as A#(). Each element of C#() is *
REM * assigned the result of multiplying the equivalent element of *
REM * A#() by B#. *
REM ******************************************************************
SUB DMatrixScalarMultiply(A#(), B#, C#())
ARowStart& = LBOUND(A#)
AColStart& = LBOUND(A#, 2)
ARowEnd& = UBOUND(A#)
AColEnd& = UBOUND(A#, 2)
REDIM C#(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C#(Row&,Column&) = A#(Row&,Column&) * B#
NEXT Row&
NEXT Column&
END SUB ' | DMatrixScalarMultiply
REM ******************************************************************
REM * Returns the maximum element contained in A#(). *
REM ******************************************************************
FUNCTION DMatrixMaximum#(A#())
MyMax# = -4.490656458412465E-324
ARowStart& = LBOUND(A#)
ARowEnd& = UBOUND(A#)
AColStart& = LBOUND(A#, 2)
AColEnd& = UBOUND(A#, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMax# < A#(Row&, Column&) THEN
MyMax# = A#(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
DMatrixMaximum# = MyMax#
END FUNCTION ' | DMatrixMaximum#
REM ******************************************************************
REM * Returns the minimum element contained in A#(). *
REM ******************************************************************
FUNCTION DMatrixMinimum#(A#())
MyMin# = 1.797693134862310E+308
ARowStart& = LBOUND(A#)
ARowEnd& = UBOUND(A#)
AColStart& = LBOUND(A#, 2)
AColEnd& = UBOUND(A#, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMin# > A#(Row&, Column&) THEN
MyMin# = A#(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
DMatrixMinimum# = MyMin#
END FUNCTION ' | DMatrixMinimum#
REM ******************************************************************
REM * Returns the Average of all the values contained in A#(). *
REM ******************************************************************
FUNCTION DMatrixMean#(A#())
Sum# = 0.0
ARowStart& = LBOUND(A#)
AColStart& = LBOUND(A#, 2)
ARowEnd& = UBOUND(A#)
AColEnd& = UBOUND(A#, 2)
FOR Column& = AColStart& TO AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
Sum# = Sum# + A#(Row&,Column&)
NEXT Row&
NEXT Column&
MatrixSize# = (1.0 + ARowEnd& - ARowStart&) * (1.0 + AColEnd& - AColStart&)
DMatrixMean# = Sum# / MatrixSize#
END FUNCTION ' | DMatrixMean#
REM ******************************************************************
REM * Returns the variance of all the values contained in A#(). *
REM ******************************************************************
FUNCTION DMatrixVariance#(A#())
SumSquared# = 0.0
MyMean# = DMatrixMean#(A#())
ARowStart& = LBOUND(A#)
AColStart& = LBOUND(A#, 2)
ARowEnd& = UBOUND(A#)
AColEnd& = UBOUND(A#, 2)
FOR Column& = AColStart& TO AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
Temp# = A#(Row&,Column&) - MyMean#
Temp# = Temp# * Temp#
SumSquared# = SumSquared# + Temp#
NEXT Row&
NEXT Column&
MatrixSize# = (1.0 + ARowEnd& - ARowStart&) * (1.0 + AColEnd& - AColStart&)
DMatrixVariance# = SumSquared# / (MatrixSize# - 1.0)
END FUNCTION ' | DMatrixVariance#
And finally _FLOAT in next post
TR
RE: Huge Matrices Library - TarotRedhand - 05-04-2022
The contents of this part are -
Code: (Select All) ' _FLOAT
SUB IdentityFMatrix(A##(), MatrixSize%)
SUB ZeroFMatrix(A##())
SUB ConFMatrix(A##())
SUB FMatrixNegate(A##())
SUB FMatrixTransPose(A##(), B##())
SUB FMatrixCopy(This##(), ToThis##())
SUB FMatrixPrint(A##())
SUB FMatrixFilePrint(A##(), FileNumber)
SUB FMatrixInput(A##())
SUB FMatrixFileInput(A##() , FileNum)
SUB FMatrixAdd(A##(), B##(), C##())
SUB FMatrixScalarAdd(A##(), B##, C##())
SUB FMatrixSubtract(A##(), B##(), C##())
SUB FMatrixScalarSubtract(A##(), B##, C##())
SUB FMatrixMultiply(A##(), B##(), C##())
SUB FMatrixScalarMultiply(A##(), B##, C##())
FUNCTION FMatrixMaximum##(A##())
FUNCTION FMatrixMinimum##(A##())
FUNCTION FMatrixMean##(A##())
FUNCTION FMatrixVariance##(A##())
The code for which is -
Code: (Select All) REM ******************************************************************
REM * This library deals with 2 dimensional arrays that are treated *
REM * as though they were mathematical matrices. I have included *
REM * all the routines that are associated with matrices that make *
REM * sense for the various TYPEs that are used. So for integers *
REM * and longs there no routines for mean, variance, inverse or *
REM * determinant. Also for singles and doubles I have left out *
REM * routines for inverse and determinant as their use is very *
REM * limited and specialised. *
REM ******************************************************************
REM ******************************************************************
REM * Private SUB only intended for use by the routines in this *
REM * library. *
REM ******************************************************************
SUB MatrixError(Where$, Fault$)
PRINT "Error in ";Where$;" - ";Fault$
STOP
END SUB ' | MatrixError
REM ******************************************************************
REM * _FLOAT floating point Matrices *
REM ******************************************************************
REM ******************************************************************
REM * A##() is REDIM'ed to be a square matrix with MatrixSize# rows *
REM * and MatrixSize# columns. All the elements of A##() are set to *
REM * zero except those where the row and the column are equal which *
REM * are set to one e.g. A##(1,1) = 1, A##(1,2) = 0. *
REM ******************************************************************
SUB IdentityFMatrix(A##(), MatrixSize&)
MatrixSize& = ABS(MatrixSize&)
REDIM A##(1 TO MatrixSize&, 1 TO MatrixSize&)
FOR Column& = 1 TO MatrixSize&
FOR Row& = 1 TO MatrixSize&
IF Row& = Column& THEN
A##(Row&,Column&) = 1.0
ELSE
A##(Row&,Column&) = 0.0
END IF
NEXT Row&
NEXT Column&
END SUB ' | IdentityFMatrix
REM ******************************************************************
REM * All the elements of A##() are set to zero. *
REM ******************************************************************
SUB ZeroFMatrix(A##())
ARowStart& = LBOUND(A##)
ARowEnd& = UBOUND(A##)
AColStart& = LBOUND(A##, 2)
AColEnd& = UBOUND(A##, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A##(Row&,Column&) = 0.0
NEXT Row&
NEXT Column&
END SUB ' | ZeroFMatrix
REM ******************************************************************
REM * All the elements of A##() are set to one. *
REM ******************************************************************
SUB ConFMatrix(A##())
ARowStart& = LBOUND(A##)
ARowEnd& = UBOUND(A##)
AColStart& = LBOUND(A##, 2)
AColEnd& = UBOUND(A##, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A##(Row&,Column&) = 1.0
NEXT Row&
NEXT Column&
END SUB ' | ConFMatrix
REM ******************************************************************
REM * LET A##() = -A##() e.g if A##(1,1) = 5 then after this routine *
REM * A##(1,1) = -5. *
REM ******************************************************************
SUB FMatrixNegate(A##())
ARowStart& = LBOUND(A##)
ARowEnd& = UBOUND(A##)
AColStart& = LBOUND(A##, 2)
AColEnd& = UBOUND(A##, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
A##(Row&,Column&) = -A##(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | FMatrixNegate
REM ******************************************************************
REM * B##() is REDIM'ed to have the same number of columns as A##() *
REM * has rows and to have the same number of rows as A##() has *
REM * columns, and then the rows of A##() are copied to the columns *
REM * of B##(). *
REM ******************************************************************
SUB FMatrixTransPose(A##(), B##())
ARowStart& = LBOUND(A##)
AColStart& = LBOUND(A##, 2)
ARowEnd& = UBOUND(A##)
AColEnd& = UBOUND(A##, 2)
REDIM B##(AColStart& TO AColEnd&, ARowStart& TO ARowEnd&)
FOR P& = AColStart& TO AColEnd&
FOR Q& = ARowStart& TO ARowEnd&
B##(P&, Q&) = A##(Q&, P&)
NEXT Q&
NEXT P&
END SUB ' | FMatrixTransPose
REM ******************************************************************
REM * REDIM's ToThis##() to be the same size as This##() and then *
REM * copies the contents of This##() to ToThis##(). *
REM ******************************************************************
SUB FMatrixCopy(This##(), ToThis##())
RowStart& = LBOUND(This##)
RowFinish& = UBOUND(This##)
ColStart& = LBOUND(This##, 2)
ColFinish& = UBOUND(This##,2)
REDIM ToThis##(RowStart& TO RowFinish&, ColStart& TO ColFinish&)
FOR Column& = ColStart& TO ColFinish&
FOR Row& = RowStart& To RowFinish&
ToThis##(Row&,Column&) = This##(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | FMatrixCopy
REM ******************************************************************
REM * Display the contents of A##() on screen, formatted in columns. *
REM ******************************************************************
SUB FMatrixPrint(A##())
ARowStart& = LBOUND(A##)
ARowEnd& = UBOUND(A##)
AColStart& = LBOUND(A##, 2)
AColEnd& = UBOUND(A##, 2)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT A##(Row&,Column&);" ";
NEXT Column&
PRINT
NEXT Row&
END SUB ' | FMatrixPrint
REM ******************************************************************
REM * Saves the contents of A##() to the file specified by FileNumber *
REM ******************************************************************
SUB FMatrixFilePrint(A##(), FileNumber)
ARowStart& = LBOUND(A##)
PRINT #FileNumber, ARowStart&;" ";
ARowEnd& = UBOUND(A##)
PRINT #FileNumber, ARowEnd&;" ";
AColStart& = LBOUND(A##, 2)
PRINT #FileNumber, AColStart&;" ";
AColEnd& = UBOUND(A##, 2)
PRINT #FileNumber, AColEnd&;" ";
PRINT #FileNumber,
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = AColStart& To AColEnd&
PRINT #FileNumber, A##(Row&,Column&);" ";
NEXT Column&
PRINT #FileNumber,
NEXT Row&
END SUB ' | FMatrixFilePrint
REM ******************************************************************
REM * This routine is for the sadists and masochists among you in *
REM * that it inputs all the information necessary to create and *
REM * fill a matrix fromthe keyboard. *
REM ******************************************************************
SUB FMatrixInput(A##())
INPUT"Lowest subscript for A##(1):",A
INPUT"Highest subscript for A##(1):",B
INPUT"Lowest subscript for A##(2):",C
INPUT"Lowest subscript for A##(2):",D
REDIM A##(A TO B, C TO D)
PRINT
FOR Row& = A TO B
FOR Column& = C TO D
PRINT "Enter value for position ";Row&;", ";Column&;":";
INPUT A
A##(Row&,Column&) = FIX(A)
NEXT Column&
NEXT Row&
END SUB ' | FMatrixInput
REM ******************************************************************
REM * This routine reads all the information necessary to create and *
REM * fill a matrix ( A##() ) from a file specified by filenum. This *
REM * routine is the complement to IMatrixFilePrint and retrieves *
REM * the information in the same order as that routine writes it. *
REM ******************************************************************
SUB FMatrixFileInput(A##() , FileNum)
INPUT #FileNum, A
INPUT #FileNum, B
INPUT #FileNum, C
INPUT #FileNum, D
A = ABS(FIX(A))
B = ABS(FIX(B))
C = ABS(FIX(C))
D = ABS(FIX(D))
REDIM A##(A TO B, C TO D)
FOR Row& = A TO B
FOR Column& = C TO D
INPUT #FileNum, A##(Row&,Column&)
NEXT Column&
NEXT Row&
END SUB ' | FMatrixFileInput
REM ******************************************************************
REM * Matrix addition e.g. C##() = A##() + B##(). A##() and B##() must *
REM * have identical upper and lower bounds. C##() is REDIM'ed to be *
REM * the same size. Each element of C##() is assigned the result of *
REM * adding the equivalent elements in A##() and B##(). *
REM ******************************************************************
SUB FMatrixAdd(A##(), B##(), C##())
ID$ = "FMatrixAdd"
ARowStart& = LBOUND(A##)
BRowStart& = LBOUND(B##)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical##"
END IF
ARowEnd& = UBOUND(A##)
BRowEnd& = UBOUND(B##)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical##"
END IF
AColStart& = LBOUND(A##, 2)
BColStart& = LBOUND(B##, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical##"
END IF
AColEnd& = UBOUND(A##, 2)
BColEnd& = UBOUND(B##, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical##"
END IF
REDIM C##(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C##(Row&,Column&) = A##(Row&,Column&) + B##(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | FMatrixAdd
REM ******************************************************************
REM * Matrix scalar addition e.g. C##() = A##() + B##. C##() is *
REM * REDIM'ed to be identical in size to A##(). Each element of *
REM * C##() is assigned the result of adding B# to the equivalent *
REM * elements in A##(). *
REM ******************************************************************
SUB FMatrixScalarAdd(A##(), B##, C##())
ARowStart& = LBOUND(A##)
ARowEnd& = UBOUND(A##)
AColStart& = LBOUND(A##, 2)
AColEnd& = UBOUND(A##, 2)
REDIM C##(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C##(Row&,Column&) = A##(Row&,Column&) + B#
NEXT Row&
NEXT Column&
END SUB ' | FMatrixScalarAdd
REM ******************************************************************
REM * Matrix subtraction e.g. C##() = A##() - B##(). A##() and B##() *
REM * must have identical upper and lower bounds. C##() is REDIM'ed *
REM * to be the same size. Each element of C##() is assigned the *
REM * result of subtracting the equivalent element of B##() from the *
REM * equivalent element of A##(). *
REM ******************************************************************
SUB FMatrixSubtract(A##(), B##(), C##())
ID$ = "FMatrixSubtract"
ARowStart& = LBOUND(A##)
BRowStart& = LBOUND(B##)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical##"
END IF
ARowEnd& = UBOUND(A##)
BRowEnd& = UBOUND(B##)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical##"
END IF
AColStart& = LBOUND(A##, 2)
BColStart& = LBOUND(B##, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical##"
END IF
AColEnd& = UBOUND(A##, 2)
BColEnd& = UBOUND(B##, 2)
IF ARowEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(1) and B(1) not identical##"
END IF
REDIM C##(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C##(Row&,Column&) = A##(Row&,Column&) - B##(Row&,Column&)
NEXT Row&
NEXT Column&
END SUB ' | FMatrixSubtract
REM ******************************************************************
REM * Matrix scalar subtraction e.g. C##() = A##() - B##. C##() is *
REM * REDIM'ed to be the same size as A##(). Each element of C##() is *
REM * assigned the result of subtracting B# from the equivalent of *
REM * A##(). *
REM ******************************************************************
SUB FMatrixScalarSubtract(A##(), B##, C##())
ARowStart& = LBOUND(A##)
ARowEnd& = UBOUND(A##)
AColStart& = LBOUND(A##, 2)
AColEnd& = UBOUND(A##, 2)
REDIM C##(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C##(Row&,Column&) = A##(Row&,Column&) - B#
NEXT Row&
NEXT Column&
END SUB ' | FMatrixScalarSubtract
REM ******************************************************************
REM * Matrix multiplication e.g. C##() = A##() * B##(). As such it is *
REM * easier to direct you to look at the source code for this *
REM * routine rather than to try to explain it, other than to say *
REM * that C##() is REDIM'ed according to the standard matrix formula *
REM ******************************************************************
SUB FMatrixMultiply(A##(), B##(), C##())
ID$ = "FMatrixMultiply"
ARowStart& = LBOUND(A##)
BRowStart& = LBOUND(B##)
IF ARowStart& <> BRowStart& THEN
MatrixError ID$, "Lower bounds of A(1) and B(1) not identical##"
END IF
AColStart& = LBOUND(A##, 2)
BColStart& = LBOUND(B##, 2)
IF AColStart& <> BColStart& THEN
MatrixError ID$, "Lower bounds of A(2) and B(2) not identical##"
END IF
BRowEnd& = UBOUND(B##)
AColEnd& = UBOUND(A##, 2)
IF AColEnd& <> BRowEnd& THEN
MatrixError ID$, "Upper bounds of A(2) and B(1) not identical##"
END IF
ARowEnd& = UBOUND(A##)
BColEnd& = UBOUND(B##, 2)
REDIM C##(ARowStart& TO ARowEnd&, BColStart& TO BColEnd&)
FOR Row& = ARowStart& TO ARowEnd&
FOR Column& = BColStart& To BColEnd&
Sum## = 0.0
FOR Z& = AColStart& TO AColEnd&
Sum## = Sum## + (A##(Row&, Z&) * B##(Z&, Column&))
NEXT Z&
C##(Row&,Column&) = Sum##
NEXT Column&
NEXT Row&
END SUB ' | FMatrixMultiply
REM ******************************************************************
REM * Matrix scalar multiplication e.g. C##() = A##() * B##. C##() is *
REM * REDIM'ed to be the same size as A##(). Each element of C##() is *
REM * assigned the result of multiplying the equivalent element of *
REM * A##() by B##. *
REM ******************************************************************
SUB FMatrixScalarMultiply(A##(), B##, C##())
ARowStart& = LBOUND(A##)
AColStart& = LBOUND(A##, 2)
ARowEnd& = UBOUND(A##)
AColEnd& = UBOUND(A##, 2)
REDIM C##(ARowStart& TO ARowEnd&, AColStart& TO AColEnd&)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
C##(Row&,Column&) = A##(Row&,Column&) * B#
NEXT Row&
NEXT Column&
END SUB ' | FMatrixScalarMultiply
REM ******************************************************************
REM * Returns the maximum element contained in A##(). *
REM ******************************************************************
FUNCTION FMatrixMaximum##(A##())
MyMax## = -1.18E-4932
ARowStart& = LBOUND(A##)
ARowEnd& = UBOUND(A##)
AColStart& = LBOUND(A##, 2)
AColEnd& = UBOUND(A##, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMax## < A##(Row&, Column&) THEN
MyMax## = A##(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
FMatrixMaximum## = MyMax##
END FUNCTION ' | FMatrixMaximum##
REM ******************************************************************
REM * Returns the minimum element contained in A##(). *
REM ******************************************************************
FUNCTION FMatrixMinimum##(A##())
MyMin## = 1.18E+4932
ARowStart& = LBOUND(A##)
ARowEnd& = UBOUND(A##)
AColStart& = LBOUND(A##, 2)
AColEnd& = UBOUND(A##, 2)
FOR Column& = AColStart& To AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
IF MyMin## > A##(Row&, Column&) THEN
MyMin## = A##(Row&,Column&)
END IF
NEXT Row&
NEXT Column&
FMatrixMinimum## = MyMin##
END FUNCTION ' | FMatrixMinimum##
REM ******************************************************************
REM * Returns the Average of all the values contained in A##(). *
REM ******************************************************************
FUNCTION FMatrixMean##(A##())
Sum## = 0.0
ARowStart& = LBOUND(A##)
AColStart& = LBOUND(A##, 2)
ARowEnd& = UBOUND(A##)
AColEnd& = UBOUND(A##, 2)
FOR Column& = AColStart& TO AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
Sum## = Sum## + A##(Row&,Column&)
NEXT Row&
NEXT Column&
MatrixSize## = (1.0 + ARowEnd& - ARowStart&) * (1.0 + AColEnd& - AColStart&)
FMatrixMean## = Sum## / MatrixSize##
END FUNCTION ' | FMatrixMean##
REM ******************************************************************
REM * Returns the variance of all the values contained in A##(). *
REM ******************************************************************
FUNCTION FMatrixVariance##(A##())
SumSquared## = 0.0
MyMean## = FMatrixMean##(A##())
ARowStart& = LBOUND(A##)
AColStart& = LBOUND(A##, 2)
ARowEnd& = UBOUND(A##)
AColEnd& = UBOUND(A##, 2)
FOR Column& = AColStart& TO AColEnd&
FOR Row& = ARowStart& TO ARowEnd&
Temp## = A##(Row&,Column&) - MyMean##
Temp## = Temp## * Temp##
SumSquared## = SumSquared## + Temp##
NEXT Row&
NEXT Column&
MatrixSize## = (1.0 + ARowEnd& - ARowStart&) * (1.0 + AColEnd& - AColStart&)
FMatrixVariance## = SumSquared## / (MatrixSize## - 1.0)
END FUNCTION ' | FMatrixVariance##
And that's it.
TR
RE: Huge Matrices Library - madscijr - 05-10-2022
(05-04-2022, 07:57 AM)TarotRedhand Wrote: ...
This library is all to do with matrices. There are six sections to it. Each section deals with matrix operations for arrays that contain a particular TYPE of data
... thanks
Thanks for sharing. I have two suggestions
1. Maybe put in the description a short list of what these operations are? Maybe even a couple of simple examples that show what this library can be used for. That will make it easier for someone who is curious to quickly decide if this is something they can use, rather than having to go through the work of copying and reading through all those posts of code, to know what it is for.
2. Can you just attach the code in a single 7z or zip file? That would be easier than putting togther 6 code boxes.
That's all I have for now - thanks!
RE: Huge Matrices Library - TarotRedhand - 05-17-2022
BASIC as a programming language was devised in 1964 at Dartmouth College in the USA as a teaching language. This very first version of BASIC had support for matrix operations in the form of the MAT keyword. Subsequent versions dropped that keyword from the language, hence my library. Dropping that keyword and support may have proved short-sighted to an extent as their use in computer graphics has only grown. Your graphics card performs loads of calculations, per second, involving matrices. But you ask, are there any real world problems that they are good for? Examine this from the ancient (in computing terms) book "Illustrating BASIC" (1977) -
Problem -
There are 3 salespersons who sell a range of 4 products. Here are last weeks sales figures -
Code: (Select All) Product
Salesperson Maglets Scropers Gimples Nuckers
Mr. Hogg 5 2 0 10
Ms. Burnbra 3 5 2 5
M. Chauvin 20 0 0 0
Each of those products has a sale price per item and earns the salesperson a set commission on each item sold -
Code: (Select All) Price List
Product Price Commission
Maglets 1.50 0.20
Scropers 2.80 0.40
Gimples 5.00 1.00
Nuckers 2.00 0.50
The question is who made the most money for the company and how much commission was paid to each salesperson?
This can be solved in two different ways. Either a bespoke routine can be written to do it or you can use my matrix library -
Common to both approaches
Code: (Select All) OPTION BASE 1
DIM Sales!(3, 4), Prices!(4, 2), Result!(3, 2)
REM skipping the code for reading in the data
Bespoke
Code: (Select All) FOR Index1% = 1 to 2 'Columns of Prices!()
FOR Index2% = 1 to 3 'Rows of Sales!()
FOR Index3% = 1 to 4 'Columns of Sales!() and Rows of Prices!()
Result!(Index2%, Index1%) = Result!(Index2%, Index1%) + Sales!(Index2%, Index3%) * Prices!(Index3%, Index1%)
NEXT Index3%
NEXT Index2%
NEXT Index1%
Or using my matrices library we just need (using the SINGLE precision library - accurate enough for our needs) -
SMatrixMultiply(Sales!(), Prices!(), Result!())
to achieve the same result. To prove this copy and paste the SINGLE precision version into a new BM file calling it "Mat_Single.BM". Then copy this code into a new BAS file
SALES.BAS
Code: (Select All) '$INCLUDE: 'MATRIX.BI'
Dim Sales!(3, 4), Prices!(4, 2), Result!(3, 2)
For Index1% = 1 To 3
For Index2% = 1 To 4
Read Sales!(Index1%, Index2%)
Next Index2%
Next Index1%
For Index1% = 1 To 4
For Index2% = 1 To 2
Read Prices!(Index1%, Index2%)
Next Index2%
Next Index1%
SMatrixMultiply Sales!(), Prices!(), Result!()
Print "Results"
Print
Print "Seller Sold Earned"
Print "Mr. Hogg "; " "; Result!(1, 1); " "; Result!(1, 2)
Print "Ms. Burnbra"; " "; Result!(2, 1); " "; Result!(2, 2)
Print "M. Chauvin"; " "; Str$(Result!(3, 1)); ".0"; " "; Str$(Result!(3, 2)); ".0";
End
Data 5,2,0,10
Data 3,5,2,5
Data 20,0,0,0
Data 1.50,0.20
Data 2.80,0.40
Data 5.00,1.00
Data 2.00,0.50
'$INCLUDE: 'Mat_Single.BM'
and run it.
TR
|