Skip to content

Commit 309b8b2

Browse files
experiments
1 parent 12ef63c commit 309b8b2

4 files changed

Lines changed: 279 additions & 1 deletion

File tree

src/main/java/com/jdoe/algorithms/BuildRegressionMatrix.java renamed to src/main/java/com/jdoe/algorithms/BuildRegressionMatrixDOE.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import com.jdoe.util.BuildRegressionMatrixUtility;
88

9-
public class BuildRegressionMatrix {
9+
public class BuildRegressionMatrixDOE {
1010

1111
/**
1212
* Builds a regression matrix from an experimental design matrix and a mathematical model string.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.jdoe.algorithms;
2+
3+
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
4+
import org.apache.commons.math3.linear.RealMatrix;
5+
import org.apache.commons.math3.random.RandomDataGenerator;
6+
import org.apache.commons.math3.random.JDKRandomGenerator;
7+
8+
public class CranleyPattersonShiftDOE {
9+
10+
public static RealMatrix cranleyPattersonShift(double[][] points, Integer seed) {
11+
if (points == null || points.length == 0 || points[0].length == 0) {
12+
throw new IllegalArgumentException("Input `points` must be a non-null 2D array with at least one element.");
13+
}
14+
15+
RealMatrix pointsMatrix = new Array2DRowRealMatrix(points);
16+
17+
int nSamples = pointsMatrix.getRowDimension();
18+
int dim = pointsMatrix.getColumnDimension();
19+
20+
// Initialize random generator with seed if provided
21+
RandomDataGenerator rng;
22+
if (seed != null) {
23+
JDKRandomGenerator jdkRng = new JDKRandomGenerator();
24+
jdkRng.setSeed(seed);
25+
rng = new RandomDataGenerator(jdkRng); // Use Apache Commons Math generator
26+
} else {
27+
rng = new RandomDataGenerator();
28+
}
29+
30+
// Generate random shift vector
31+
double[] shiftVector = new double[dim];
32+
for (int i = 0; i < dim; i++) {
33+
shiftVector[i] = rng.nextUniform(0.0, 1.0);
34+
}
35+
36+
// Create a matrix with the shift vector replicated for each sample
37+
double[][] shiftMatrixData = new double[nSamples][dim];
38+
for (int i = 0; i < nSamples; i++) {
39+
for (int j = 0; j < dim; j++) {
40+
shiftMatrixData[i][j] = shiftVector[j];
41+
}
42+
}
43+
44+
RealMatrix shiftMatrix = new Array2DRowRealMatrix(shiftMatrixData);
45+
46+
// Add the shift vector to all points
47+
RealMatrix shiftedPoints = pointsMatrix.add(shiftMatrix);
48+
49+
// Wrap values to [0, 1) using modulo operation
50+
double[][] resultData = shiftedPoints.getData();
51+
for (int i = 0; i < nSamples; i++) {
52+
for (int j = 0; j < dim; j++) {
53+
resultData[i][j] = resultData[i][j] - Math.floor(resultData[i][j]);
54+
}
55+
}
56+
57+
return new Array2DRowRealMatrix(resultData);
58+
}
59+
60+
/**
61+
* Overloaded method without seed parameter
62+
*/
63+
public static RealMatrix cranleyPattersonShift(double[][] points) {
64+
return cranleyPattersonShift(points, null);
65+
}
66+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package com.jdoe.algorithms;
2+
3+
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
4+
import org.apache.commons.math3.linear.RealMatrix;
5+
6+
public class DoeFold {
7+
8+
/**
9+
* Fold a design to reduce confounding effects.
10+
*
11+
* @param H The design matrix to be folded
12+
* @param columns Indices of columns to fold (Default: null). If columns=null is
13+
* used, then all columns will be folded.
14+
* @return The folded design matrix
15+
*/
16+
public static RealMatrix fold(double[][] H, int[] columns) {
17+
if (H.length == 0 || H[0].length == 0 || H.length != H[0].length) {
18+
throw new IllegalArgumentException("Input design matrix must be 2d.");
19+
}
20+
21+
int nCols = H[0].length;
22+
23+
if (columns == null) {
24+
columns = new int[nCols];
25+
for (int i = 0; i < nCols; i++) {
26+
columns[i] = i;
27+
}
28+
}
29+
30+
double[][] Hf = new double[H.length][H[0].length];
31+
32+
// Copy original matrix to Hf
33+
for (int i = 0; i < H.length; i++) {
34+
System.arraycopy(H[i], 0, Hf[i], 0, H[0].length);
35+
}
36+
37+
for (int col : columns) {
38+
// Get unique values in column
39+
double[] vals = getUniqueValues(getColumn(H, col));
40+
41+
if (vals.length != 2) {
42+
throw new IllegalArgumentException("Input design matrix must be 2-level factors only.");
43+
}
44+
45+
for (int i = 0; i < H.length; i++) {
46+
Hf[i][col] = (H[i][col] == vals[1]) ? vals[0] : vals[1];
47+
}
48+
}
49+
50+
// Combine original and folded matrices
51+
double[][] result = new double[H.length * 2][H[0].length];
52+
53+
// Copy original matrix
54+
for (int i = 0; i < H.length; i++) {
55+
System.arraycopy(H[i], 0, result[i], 0, H[0].length);
56+
}
57+
58+
// Copy folded matrix
59+
for (int i = 0; i < Hf.length; i++) {
60+
System.arraycopy(Hf[i], 0, result[H.length + i], 0, Hf[0].length);
61+
}
62+
63+
return new Array2DRowRealMatrix(result);
64+
}
65+
66+
/**
67+
* Overloaded method with default columns (all columns)
68+
*/
69+
public static RealMatrix fold(double[][] H) {
70+
return fold(H, null);
71+
}
72+
73+
/**
74+
* Helper method to extract a column from a 2D array
75+
*/
76+
private static double[] getColumn(double[][] matrix, int colIndex) {
77+
double[] column = new double[matrix.length];
78+
for (int i = 0; i < matrix.length; i++) {
79+
column[i] = matrix[i][colIndex];
80+
}
81+
return column;
82+
}
83+
84+
/**
85+
* Helper method to get unique values from an array
86+
*/
87+
private static double[] getUniqueValues(double[] arr) {
88+
java.util.Set<Double> uniqueSet = new java.util.LinkedHashSet<>();
89+
for (double val : arr) {
90+
uniqueSet.add(val);
91+
}
92+
return uniqueSet.stream().mapToDouble(Double::doubleValue).toArray();
93+
}
94+
}
95+
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package com.jdoe.algorithms;
2+
3+
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
4+
import org.apache.commons.math3.linear.RealMatrix;
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
public class DoehlertDOE {
9+
10+
/**
11+
* Generate a Doehlert design matrix for a given number of factors using a shell approach.
12+
*
13+
* @param numFactors Number of factors (variables)
14+
* @param numCenterPoints Number of center (replicate) points
15+
* @return Design matrix of shape (N, numFactors), where N = k^2 + k + C
16+
*/
17+
public static RealMatrix doehlertShellDesign(int numFactors, int numCenterPoints) {
18+
if (numFactors < 1) {
19+
throw new IllegalArgumentException("Number of factors must be at least 1.");
20+
}
21+
22+
List<double[]> designPoints = new ArrayList<>();
23+
24+
// Add center points
25+
for (int i = 0; i < numCenterPoints; i++) {
26+
double[] centerPoint = new double[numFactors];
27+
for (int j = 0; j < numFactors; j++) {
28+
centerPoint[j] = 0.0;
29+
}
30+
designPoints.add(centerPoint);
31+
}
32+
33+
// Add shells progressively
34+
for (int shellIndex = 1; shellIndex <= numFactors; shellIndex++) {
35+
int numShellPoints = shellIndex + 1;
36+
double radius = Math.sqrt(shellIndex / (double) numFactors);
37+
38+
for (int pointIdx = 0; pointIdx < numShellPoints; pointIdx++) {
39+
double[] point = new double[numFactors];
40+
double angle = (2.0 * Math.PI * pointIdx) / numShellPoints;
41+
42+
if (numFactors > 0) point[0] = radius * Math.cos(angle);
43+
if (numFactors > 1) point[1] = radius * Math.sin(angle);
44+
45+
designPoints.add(point);
46+
}
47+
}
48+
49+
// Convert list of points to matrix
50+
double[][] result = new double[designPoints.size()][numFactors];
51+
for (int i = 0; i < designPoints.size(); i++) {
52+
result[i] = designPoints.get(i);
53+
}
54+
55+
return new Array2DRowRealMatrix(result);
56+
}
57+
58+
/**
59+
* Overloaded method with default center points (1)
60+
*/
61+
public static RealMatrix doehlertShellDesign(int numFactors) {
62+
return doehlertShellDesign(numFactors, 1);
63+
}
64+
65+
/**
66+
* Generate a Doehlert design matrix using a simplex-based approach.
67+
*
68+
* @param numFactors Number of factors included in the design
69+
* @return Design matrix with experiments at different coded levels
70+
*/
71+
public static RealMatrix doehlertSimplexDesign(int numFactors) {
72+
double[][] simplexMatrix = new double[numFactors + 1][numFactors];
73+
74+
for (int i = 1; i <= numFactors; i++) {
75+
for (int j = 1; j <= i; j++) {
76+
if (j == i) {
77+
simplexMatrix[i][j - 1] = Math.sqrt(i + 1) / Math.sqrt(2 * i);
78+
} else {
79+
int denom = 2 * (i - (j - 1)) * (i - j);
80+
simplexMatrix[i][i - j] = 1 / Math.sqrt(denom);
81+
}
82+
}
83+
}
84+
85+
List<double[]> extraPoints = new ArrayList<>();
86+
for (int i = 0; i <= numFactors; i++) {
87+
List<Integer> rangeList = new ArrayList<>();
88+
for (int k = 1; k < i; k++) rangeList.add(k);
89+
for (int k = i + 1; k <= numFactors; k++) rangeList.add(k);
90+
91+
for (int j : rangeList) {
92+
double[] point = new double[numFactors];
93+
for (int k = 0; k < numFactors; k++) {
94+
point[k] = simplexMatrix[i][k] - simplexMatrix[j][k];
95+
}
96+
extraPoints.add(point);
97+
}
98+
}
99+
100+
// Combine matrices
101+
int totalRows = (numFactors + 1) + extraPoints.size();
102+
double[][] fullMatrix = new double[totalRows][numFactors];
103+
104+
// Copy simplex matrix
105+
for (int i = 0; i < simplexMatrix.length; i++) {
106+
fullMatrix[i] = simplexMatrix[i];
107+
}
108+
109+
// Add extra points
110+
for (int i = 0; i < extraPoints.size(); i++) {
111+
fullMatrix[simplexMatrix.length + i] = extraPoints.get(i);
112+
}
113+
114+
return new Array2DRowRealMatrix(fullMatrix);
115+
}
116+
117+
}

0 commit comments

Comments
 (0)