Skip to content

Commit 96ec73d

Browse files
committed
added std & turbo forms of sub_mat(A, rowIdx, colIdx) and rnd_mat(max_num, rowSize, colSize)
1 parent 59b7630 commit 96ec73d

6 files changed

Lines changed: 356 additions & 74 deletions

File tree

‎src/main/java/com/github/gbenroscience/math/matrix/expressParser/Matrix.java‎

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
*/
1616
package com.github.gbenroscience.math.matrix.expressParser;
1717

18-
import com.github.gbenroscience.parser.MathExpression;
1918
import java.util.HashMap;
2019
import java.util.InputMismatchException;
2120
import java.util.List;
2221
import java.util.Random;
2322
import com.github.gbenroscience.parser.Scanner;
2423
import com.github.gbenroscience.parser.Operator;
24+
import java.util.concurrent.ThreadLocalRandom;
2525

2626
/**
2727
*
@@ -1032,6 +1032,50 @@ public Matrix getCofactorMatrix() {
10321032
return null;
10331033
}
10341034

1035+
/**
1036+
* Computes and returns specifically, the bottom-right sub-block from a
1037+
* given coordinate to the end of the matrix), not a Minor submatrix
1038+
*
1039+
* @param A The matrix
1040+
* @param r The row to copy from(zero based)
1041+
* @param c The column to copy from(zero based)
1042+
* @return specifically the bottom-right sub-block from a given coordinate
1043+
* to the end of the matrix
1044+
*/
1045+
public static Matrix getSubmatrix(Matrix A, int r, int c) {
1046+
int aR = A.getRows();
1047+
int aC = A.getCols();
1048+
1049+
// Bounds validation
1050+
if (r < 0 || r >= aR || c < 0 || c >= aC) {
1051+
throw new IndexOutOfBoundsException("Row or column index out of bounds.");
1052+
}
1053+
1054+
// Calculate dimensions of the new sub-block
1055+
int newR = aR - r;
1056+
int newC = aC - c;
1057+
1058+
// Borrow a buffer of the exact required size
1059+
Matrix B = new Matrix(newR, newC);
1060+
1061+
double[] aF = A.getFlatArray();
1062+
double[] bF = B.getFlatArray();
1063+
1064+
// Copy row by row using System.arraycopy
1065+
for (int i = 0; i < newR; i++) {
1066+
// Source index: (Current original row * total columns) + starting column
1067+
int srcOffset = (r + i) * aC + c;
1068+
1069+
// Destination index: (Current new row * new columns)
1070+
int destOffset = i * newC;
1071+
1072+
// Copy the entire continuous width of the new row in one instruction
1073+
System.arraycopy(aF, srcOffset, bF, destOffset, newC);
1074+
}
1075+
1076+
return B;
1077+
}
1078+
10351079
/**
10361080
*
10371081
* @param i the row on which the element whose minor is needed lies.
@@ -1202,7 +1246,7 @@ public double determinant() {
12021246
* Fills the matrix with randomly generated values between 1 and 101.
12031247
*/
12041248
public void randomFill() {
1205-
Random ran = new Random();
1249+
ThreadLocalRandom ran = ThreadLocalRandom.current();
12061250
for (int i = 0; i < array.length; i++) {
12071251
array[i] = 1 + (double) ran.nextInt(101);
12081252
}
@@ -1214,7 +1258,7 @@ public void randomFill() {
12141258
* @param n the maximum possible size of the integer numbers generated.
12151259
*/
12161260
public void randomFill(int n) {
1217-
Random ran = new Random();
1261+
ThreadLocalRandom ran = ThreadLocalRandom.current();
12181262
for (int i = 0; i < array.length; i++) {
12191263
array[i] = 1 + ran.nextInt(n);
12201264
}
@@ -1395,9 +1439,8 @@ public Matrix inverse() {
13951439
}//end if
13961440
return null;
13971441
}
1398-
1399-
1400-
/**
1442+
1443+
/**
14011444
* Row reduction technique used to compute the determinant of this matrix.
14021445
* The other method using recursion is not worth it above n = 10; The memory
14031446
* consumed by the process and the time used to compute it is incomparable

‎src/main/java/com/github/gbenroscience/parser/methods/Declarations.java‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ public class Declarations {
135135
public static final String MATRIX_EIGENVEC = "eigvec";
136136
public static final String MATRIX_EIGENVALUES = "eigvalues";
137137
public static final String MATRIX_EIGENPOLY = "eigpoly";
138+
public static final String SUB_MATRIX = "sub_mat";
139+
public static final String RANDOM_MATRIX = "rnd_mat";
138140
public static final String HELP = "help";
139141

140142

@@ -296,7 +298,7 @@ public static String[] createInBuiltMethods() {
296298
LINEAR_SYSTEM, DETERMINANT, INVERSE_MATRIX, TRIANGULAR_MATRIX,
297299
ECHELON_MATRIX, MATRIX_MULTIPLY, MATRIX_DIVIDE, MATRIX_ADD,
298300
MATRIX_SUBTRACT, MATRIX_POWER, MATRIX_TRANSPOSE, MATRIX_EDIT,
299-
MATRIX_COFACTORS, MATRIX_ADJOINT, MATRIX_EIGENVEC, MATRIX_EIGENVALUES,
301+
MATRIX_COFACTORS, MATRIX_ADJOINT, MATRIX_EIGENVEC, MATRIX_EIGENVALUES,SUB_MATRIX,RANDOM_MATRIX,
300302
MATRIX_EIGENPOLY, HELP, NOW, NANOS, ROTOR
301303
};
302304

@@ -521,6 +523,10 @@ public static String returnTypeDef(String typeName) {
521523
return TYPE.MATRIX.toString();
522524
case MATRIX_EIGENVALUES:
523525
return TYPE.MATRIX.toString();
526+
case SUB_MATRIX:
527+
return TYPE.MATRIX.toString();
528+
case RANDOM_MATRIX:
529+
return TYPE.MATRIX.toString();
524530
case NOW:
525531
return TYPE.NUMBER.toString();
526532
case NANOS:

‎src/main/java/com/github/gbenroscience/parser/methods/Method.java‎

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,13 @@ public Method(String name, String... parameters) {
6666
* Function objects or anonymous Functions.
6767
*/
6868
public static boolean isFunctionOperatingMethod(String methodName) {
69-
return methodName.equals(DIFFERENTIATION) || methodName.equals(INTEGRATION) || methodName.equals(DIFF_EQN) || methodName.equals(QUADRATIC) || methodName.equals(GENERAL_ROOT)
69+
return methodName.equals(DIFFERENTIATION) || methodName.equals(INTEGRATION) || methodName.equals(DIFF_EQN) || methodName.equals(QUADRATIC) || methodName.equals(GENERAL_ROOT)
7070
|| methodName.equals(TARTAGLIA_ROOTS) || methodName.equals(PLOT) || methodName.equals(MATRIX_MULTIPLY)
7171
|| methodName.equals(MATRIX_DIVIDE) || methodName.equals(MATRIX_ADD) || methodName.equals(MATRIX_SUBTRACT)
7272
|| methodName.equals(MATRIX_POWER) || methodName.equals(MATRIX_EDIT) || methodName.equals(MATRIX_TRANSPOSE)
7373
|| methodName.equals(DETERMINANT) || methodName.equals(MATRIX_ADJOINT) || methodName.equals(MATRIX_COFACTORS)
74-
|| methodName.equals(MATRIX_EIGENPOLY) || methodName.equals(MATRIX_EIGENVEC) || methodName.equals(MATRIX_EIGENVALUES) || methodName.equals(PRINT);
74+
|| methodName.equals(MATRIX_EIGENPOLY) || methodName.equals(MATRIX_EIGENVEC) || methodName.equals(MATRIX_EIGENVALUES)|| methodName.equals(SUB_MATRIX)
75+
|| methodName.equals(PRINT);
7576
}
7677

7778
/**
@@ -152,13 +153,13 @@ public static boolean isListReturningStatsMethod(String op) {
152153
return (op.equals(SORT) || op.equals(MODE) || op.equals(RANDOM) || op.equals(QUADRATIC) || op.equals(TARTAGLIA_ROOTS)
153154
|| op.equals(INVERSE_MATRIX) || op.equals(LINEAR_SYSTEM) || op.equals(TRIANGULAR_MATRIX) || op.equals(ECHELON_MATRIX))
154155
|| op.equals(MATRIX_MULTIPLY) || op.equals(MATRIX_DIVIDE) || op.equals(MATRIX_ADD) || op.equals(MATRIX_SUBTRACT) || op.equals(MATRIX_POWER)
155-
|| op.equals(MATRIX_TRANSPOSE) || op.equals(MATRIX_EDIT) || op.equals(MATRIX_EIGENVEC) || op.equals(MATRIX_EIGENVALUES);
156+
|| op.equals(MATRIX_TRANSPOSE) || op.equals(MATRIX_EDIT) || op.equals(MATRIX_EIGENVEC) || op.equals(MATRIX_EIGENVALUES) || op.equals(SUB_MATRIX)|| op.equals(RANDOM_MATRIX);
156157
}
157-
158+
158159
public static boolean isListReturningStatsMethodThatAllowsAlgebraicOps(String op) {
159160
return (op.equals(INVERSE_MATRIX) || op.equals(LINEAR_SYSTEM) || op.equals(TRIANGULAR_MATRIX) || op.equals(ECHELON_MATRIX))
160161
|| op.equals(MATRIX_MULTIPLY) || op.equals(MATRIX_DIVIDE) || op.equals(MATRIX_ADD) || op.equals(MATRIX_SUBTRACT) || op.equals(MATRIX_POWER)
161-
|| op.equals(MATRIX_TRANSPOSE) || op.equals(MATRIX_EIGENVEC) || op.equals(MATRIX_EIGENVALUES);
162+
|| op.equals(MATRIX_TRANSPOSE) || op.equals(MATRIX_EIGENVEC) || op.equals(MATRIX_EIGENVALUES) || op.equals(SUB_MATRIX)|| op.equals(RANDOM_MATRIX);
162163
}
163164

164165
/**
@@ -267,19 +268,21 @@ public boolean isMatrixEigenVec(String op) {
267268
public boolean isMatrixEigenPoly(String op) {
268269
return op.equals(MATRIX_EIGENPOLY);
269270
}
271+
270272

271273
public boolean isPrint(String op) {
272274
return op.equals(PRINT);
273275
}
274276

275-
public static boolean isPureStatsMethod(String name){
276-
for(String s: getStatsMethods()){
277-
if(s.equals(name)){
277+
public static boolean isPureStatsMethod(String name) {
278+
for (String s : getStatsMethods()) {
279+
if (s.equals(name)) {
278280
return true;
279281
}
280282
}
281283
return false;
282284
}
285+
283286
/**
284287
* @param op the String to check
285288
* @return true if the operator is a statistical operator..basically any
@@ -308,7 +311,8 @@ public static boolean isMatrixMethod(String op) {
308311
|| op.equals(TRIANGULAR_MATRIX) || op.equals(ECHELON_MATRIX) || op.equals(MATRIX_MULTIPLY)
309312
|| op.equals(MATRIX_DIVIDE) || op.equals(MATRIX_ADD) || op.equals(MATRIX_SUBTRACT)
310313
|| op.equals(MATRIX_POWER) || op.equals(MATRIX_EDIT) || op.equals(MATRIX_TRANSPOSE)
311-
|| op.equals(MATRIX_COFACTORS) || op.equals(MATRIX_ADJOINT) || op.equals(MATRIX_EIGENPOLY) || op.equals(MATRIX_EIGENVEC) || op.equals(MATRIX_EIGENVALUES);
314+
|| op.equals(MATRIX_COFACTORS) || op.equals(MATRIX_ADJOINT) || op.equals(MATRIX_EIGENPOLY)
315+
|| op.equals(MATRIX_EIGENVEC) || op.equals(MATRIX_EIGENVALUES)|| op.equals(SUB_MATRIX)|| op.equals(RANDOM_MATRIX);
312316
}
313317

314318
/**
@@ -365,6 +369,24 @@ public static boolean isTranspose(String op) {
365369
return op.equals(MATRIX_TRANSPOSE);
366370
}
367371

372+
/**
373+
*
374+
* @param op The method name
375+
* @return true if the method is the submatrix method name
376+
*/
377+
public static boolean isSubMatrix(String op) {
378+
return op.equals(SUB_MATRIX);
379+
}
380+
381+
/**
382+
*
383+
* @param op The method name
384+
* @return true if the method is the submatrix method name
385+
*/
386+
public static boolean isRandomMatrix(String op) {
387+
return op.equals(RANDOM_MATRIX);
388+
}
389+
368390
/**
369391
*
370392
* @param op The method name
@@ -375,7 +397,7 @@ public static boolean isMatrixEdit(String op) {
375397
}
376398

377399
/**
378-
* @param op
400+
* @param op
379401
* @return true if the Function name has been defined by the user in the
380402
* user's workspace.
381403
*/
@@ -721,8 +743,8 @@ else if (name.equals(LOG)) {
721743
return list;
722744
} else if (name.equals(MATRIX_EIGENPOLY)) {
723745
Set set = new Set(list);
724-
String poly = set.eigenPoly();
725-
list.clear();
746+
String poly = set.eigenPoly();
747+
list.clear();
726748
Function fn = Function.storeAnonymousFunction("@(" + Matrix.lambda + ")" + poly);
727749
list.add(fn.getName());
728750
return list;

‎src/main/java/com/github/gbenroscience/parser/methods/MethodRegistry.java‎

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -694,8 +694,8 @@ else if (hasIterations) {
694694
for (double d : data) {
695695
total += d;
696696
}
697-
// System.out.println("IN->"+Arrays.toString(args)+" total: "+total);
698-
697+
// System.out.println("IN->"+Arrays.toString(args)+" total: "+total);
698+
699699
ctx.wrap(total);
700700
return ctx;
701701
});
@@ -938,8 +938,8 @@ else if (hasIterations) {
938938
});
939939

940940
registerMethod(Declarations.SORT, (ctx, arity, args) -> {
941-
942-
// System.out.println("sort -> arity = "+arity+", args = "+Arrays.toString(args));
941+
942+
// System.out.println("sort -> arity = "+arity+", args = "+Arrays.toString(args));
943943
// 1. Handle edge cases
944944
if (args == null || args.length == 0) {
945945
MathExpression.EvalResult res = ctx;
@@ -960,8 +960,8 @@ else if (hasIterations) {
960960
double[] sortedData = bab.getAsDoubleArray();
961961
// 3. Perform the high-speed Dual-Pivot Quicksort
962962
java.util.Arrays.sort(sortedData);
963-
964-
// System.out.println("IN->"+Arrays.toString(sortedData));
963+
964+
// System.out.println("IN->"+Arrays.toString(sortedData));
965965
ctx.wrap(sortedData);
966966
return ctx;
967967
});
@@ -1182,7 +1182,7 @@ nxn nx(n+1)-M ------n^2+n-M=0---- (-1+sqrt(1+4M))/2 AND (-1-sqrt(1+4M))/
11821182
Matrix mB = fB.getMatrix();
11831183
return ctx.wrap(Matrix.multiply(mA, mB.inverse()));
11841184
}
1185-
return MathExpression.EvalResult.ERROR;
1185+
return MathExpression.EvalResult.ERROR;
11861186
});
11871187
registerMethod(Declarations.MATRIX_EDIT, (ctx, arity, args) -> {
11881188
Function f = FunctionManager.lookUp(args[0].textRes);
@@ -1254,6 +1254,35 @@ nxn nx(n+1)-M ------n^2+n-M=0---- (-1+sqrt(1+4M))/2 AND (-1-sqrt(1+4M))/
12541254
return ctx.wrap(m);
12551255
});
12561256

1257+
registerMethod(Declarations.SUB_MATRIX, (ctx, arity, args) -> {
1258+
Function f = FunctionManager.lookUp(args[0].textRes);
1259+
Matrix m = null;
1260+
if (f != null && (m = f.getMatrix()) != null) {
1261+
int row = (int) args[1].scalar;
1262+
int col = (int) args[2].scalar;
1263+
1264+
if (row > 0 & col > 0) {
1265+
Matrix sm = Matrix.getSubmatrix(m, row, col);
1266+
return ctx.wrap(sm);
1267+
}else{
1268+
return ctx.wrap(MathExpression.EvalResult.ERROR);
1269+
}
1270+
} else {
1271+
return ctx.wrap(MathExpression.EvalResult.ERROR);
1272+
}
1273+
});
1274+
registerMethod(Declarations.RANDOM_MATRIX, (ctx, arity, args) -> {
1275+
int n = (int) args[0].scalar;
1276+
int rowSz = (int) args[1].scalar;
1277+
int colSz = (int) args[2].scalar;
1278+
if (n > 0 && rowSz > 0 && colSz > 0) {
1279+
Matrix sm = new Matrix(rowSz, colSz);
1280+
sm.randomFill(n);
1281+
return ctx.wrap(sm);
1282+
}
1283+
return ctx.wrap(MathExpression.EvalResult.ERROR);
1284+
});
1285+
12571286
// Users can call MethodRegistry.registerMethod("custom", (ctx, arity, args) -> ...) at runtime!
12581287
}
12591288

0 commit comments

Comments
 (0)