Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
*.zip
*.tar.gz
*.rar
*.lst

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

# intellij
.idea

target/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# JDOE
# doe
Java Design of Experiments
86 changes: 86 additions & 0 deletions dependency-reduced-pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.doe</groupId>
<artifactId>doe-genereter</artifactId>
<name>doe</name>
<version>1.0-SNAPSHOT</version>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<archive>
<manifest>
<mainClass>com.doe.Testing</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer />
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.20.0</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>byte-buddy</artifactId>
<groupId>net.bytebuddy</groupId>
</exclusion>
<exclusion>
<artifactId>byte-buddy-agent</artifactId>
<groupId>net.bytebuddy</groupId>
</exclusion>
<exclusion>
<artifactId>objenesis</artifactId>
<groupId>org.objenesis</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
19 changes: 16 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.jdoe</groupId>
<groupId>com.doe</groupId>
<artifactId>doe-genereter</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>JDOE</name>
<name>doe</name>
<url>http://maven.apache.org</url>

<properties>
Expand Down Expand Up @@ -54,6 +54,19 @@
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>26.0.2</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.42</version>
<scope>compile</scope>
</dependency>

</dependencies>

Expand All @@ -66,7 +79,7 @@
<configuration>
<archive>
<manifest>
<mainClass>com.jdoe.Testing</mainClass>
<mainClass>com.doe.Testing</mainClass>
</manifest>
</archive>
</configuration>
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/jdoe/Testing.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.jdoe;
package com.doe;

import com.jdoe.algorithms.BoxBehnkenDOE;
import com.jdoe.algorithms.FactorialDOE;
import com.doe.algorithms.BoxBehnkenDOE;
import com.doe.algorithms.FactorialDOE;

/**
* Hello world!
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/jdoe/algorithms/BoxBehnkenDOE.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.jdoe.algorithms;
package com.doe.algorithms;

import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.RealMatrix;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.jdoe.algorithms;
package com.doe.algorithms;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.jdoe.util.BuildRegressionMatrixUtility;
import com.doe.util.BuildRegressionMatrixUtility;

public class BuildRegressionMatrix {
public class BuildRegressionMatrixDOE {

/**
* Builds a regression matrix from an experimental design matrix and a mathematical model string.
Expand Down
142 changes: 142 additions & 0 deletions src/main/java/com/jdoe/algorithms/CompositeDOE.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package com.doe.algorithms;

import org.apache.commons.math3.linear.Array2DRowFieldMatrix;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.RealMatrix;
import org.jetbrains.annotations.NotNull;

import com.doe.util.GenericDOEUtil;

public class CompositeDOE {

private static final String[] alphaParamLegalExpressions = {"orthogonal", "o", "rotatable", "r"};

private static final String[] faceParamLegalExpressions = {"circumscribed", "ccc", "inscribed", "cci", "faced", "ccf"};

public static RealMatrix centralCompositeDesign(@NotNull int numberOfFactors, @NotNull int[] centerPoints, @NotNull String alpha, @NotNull String face) {
validateCompositeDegisnParameters(numberOfFactors, centerPoints, alpha, face);

RealMatrix factorialDesignMatrix;
RealMatrix starDesignMatrix;
double alphaValue;

// Orthogonal Design
if (alpha.toLowerCase().equals("orthogonal") || alpha.toLowerCase().equals("o")) {
Object[] starResult = StarDOE.star(numberOfFactors, "orthogonal", centerPoints);
starDesignMatrix = new Array2DRowRealMatrix((double[][]) starResult[0]); // Convert array to RealMatrix
alphaValue = (double) starResult[1];
}
// Rotatable Design
else if (alpha.toLowerCase().equals("rotatable") || alpha.toLowerCase().equals("r")) {
Object[] starResult = StarDOE.star(numberOfFactors, "rotatable", new int[]{0, 0});
starDesignMatrix = new Array2DRowRealMatrix((double[][]) starResult[0]); // Convert array to RealMatrix
alphaValue = (double) starResult[1];
} else {
throw new IllegalArgumentException("Invalid alpha parameter: " + alpha);
}

// Inscribed CCD
if (face.toLowerCase().equals("inscribed") || face.toLowerCase().equals("cci")) {
factorialDesignMatrix = FactorialDOE.fullFactorial2Level(numberOfFactors);
factorialDesignMatrix = factorialDesignMatrix.scalarMultiply(1.0 / alphaValue); // Scale down the factorial points
Object[] starResult = StarDOE.star(numberOfFactors, alpha, centerPoints);
starDesignMatrix = new Array2DRowRealMatrix((double[][]) starResult[0]); // Convert array to RealMatrix
alphaValue = (double) starResult[1];
}
// Faced CCD
else if (face.toLowerCase().equals("faced") || face.toLowerCase().equals("ccf")) {
Object[] starResult = StarDOE.star(numberOfFactors, alpha, centerPoints);
starDesignMatrix = new Array2DRowRealMatrix((double[][]) starResult[0]); // Convert array to RealMatrix
alphaValue = 1.0;
// Value of alpha is always 1 in Faced CCD
factorialDesignMatrix = FactorialDOE.fullFactorial2Level(numberOfFactors);
}
// Circumscribed CCD
else if (face.toLowerCase().equals("circumscribed") || face.toLowerCase().equals("ccc")) {
factorialDesignMatrix = FactorialDOE.fullFactorial2Level(numberOfFactors);
} else {
throw new IllegalArgumentException("Invalid face parameter: " + face);
}

RealMatrix centerPointsMatrix1 = RepeatCenterDOE.repeatCenter(numberOfFactors, centerPoints[0]);
RealMatrix centerPointsMatrix2 = RepeatCenterDOE.repeatCenter(numberOfFactors, centerPoints[1]);

factorialDesignMatrix = UnionDOE.matrixUnion(factorialDesignMatrix, centerPointsMatrix1);
starDesignMatrix = UnionDOE.matrixUnion(starDesignMatrix, centerPointsMatrix2);
RealMatrix finalDesignMatrix = UnionDOE.matrixUnion(factorialDesignMatrix, starDesignMatrix);

return finalDesignMatrix;
}

//<-----------------------------Utility Methods---------------------------------->

public static void validateCompositeDegisnParameters(int numberOfFactors, int[] centerPoints, String alpha, String face) {
if (numberOfFactors < 1) {
throw new IllegalArgumentException("number of factors must be greater than 1");
}
if (centerPoints.length != 2) { // Fixed: was == now !=
throw new IllegalArgumentException(String.format("Invalid number of values for \"center\" (expected 2, but got %d)", centerPoints.length));
}
if (validateExpression(alpha, alphaParamLegalExpressions) == Boolean.FALSE) {
throw new IllegalArgumentException(String.format("Invalid value for \"alpha\" (expected one of %s)", java.util.Arrays.toString(alphaParamLegalExpressions)));
}
if (validateExpression(face, faceParamLegalExpressions) == Boolean.FALSE) {
throw new IllegalArgumentException(String.format("Invalid value for \"face\" (expected one of %s)", java.util.Arrays.toString(faceParamLegalExpressions)));
}
}

public static Boolean validateExpression(String expression, String[] legalExpressions) {
Boolean validInput = Boolean.FALSE;
for (String legalExpression : legalExpressions) {
if (legalExpression.equals(expression)) {
validInput = Boolean.TRUE;
break;
}
}
return validInput;
}

}

//<-----------------------------STEPS---------------------------------->

/**
* Detailed Steps to Port Central Composite Design Script to Java
* <p>
* $ 1. Create CompositeDOE Class Structure Create CompositeDOE.java in com.doe.algorithms package Add imports:
* org.apache.commons.math3.linear.* for matrix operations Define method signature: public static RealMatrix centralCompositeDesign(int n,
* int[] center, String alpha, String face) Set default parameters handling for center, alpha, and face
* <p>
* $ 2. Implement Input Validation Logic Add assertion: assert n > 1 : "\"n\" must be an integer greater than 1" Validate alpha parameter
* with: alpha.toLowerCase() and check against allowed values Validate face parameter with: face.toLowerCase() and check against allowed
* values Validate center array length: if (center.length != 2) throw IllegalArgumentException Format error messages to match Python
* implementation
* <p>
* $ 3. Implement Star Point Generation Create StarDOE.java class with star method Calculate alpha based on alpha type: For orthogonal:
* alpha = Math.pow(2 * factorial(n), 0.25) where factorial(n) = n! For rotatable: alpha = Math.pow(2, 0.5) for 2D, Math.pow(3, 0.5) for 3D,
* etc. Generate 2n star points with values [±alpha, 0, ..., 0], [0, ±alpha, ..., 0], etc. Return both star matrix and alpha value as an
* Object array
* <p>
* 4. Enhance FactorialDOE Class Add ff2n method that generates 2-level factorial design Create 2^n × n matrix with values -1 and +1 Use bit
* manipulation: for each row i and column j, set value to ((i >> j) & 1) == 0 ? -1 : 1 Return RealMatrix object
* <p>
* 5. Create UnionDOE Class Implement union method that combines two matrices vertically Use Array2DRowRealMatrix constructor to create new
* matrix with combined rows Copy data from both input matrices to the result matrix Return the concatenated matrix
* <p>
* 6. Create RepeatCenterDOE Class Implement repeatCenter method that generates center points Create repeats × n matrix filled with zeros
* Use new Array2DRowRealMatrix(repeats, n) to initialize matrix Return the center point matrix
* <p>
* 7. Implement Core Algorithm Logic Initialize H1 andH2 matrices based on face type For inscribed (cci): scale factorial points H1 =
* H1.scalarMultiply(1.0/a) For faced (ccf): set alpha to 1.0 For circumscribed (ccc): keep original factorial points Generate center points
* C1 and C2 using repeatCenter Combine matrices: H1 = union(H1, C1), H2 = union(H2, C2), H = union(H1, H2)
* <p>
* 8. Handle Matrix Operations Implement matrix scaling using scalarMultiply() method from Commons Math Ensure all matrix dimensions are
* compatible for union operations Use getSubMatrix() and setSubMatrix() for matrix manipulations Return final RealMatrix object
* <p>
* 9. Create Unit Tests Create CompositeDOETest.java with comprehensive test cases Test all three face types: ccc, cci, ccf Test both alpha
* types: orthogonal, rotatable Validate matrix dimensions: (2^n + 2n + sum(center)) × n Verify center point counts and star point
* distances
* <p>
* 10. Add Documentation and Error Handling Add JavaDoc explaining parameters, return value, and exceptions Implement proper exception
* handling for invalid inputs Include example usage in documentation Follow the same error message format as Python implementation
*/
66 changes: 66 additions & 0 deletions src/main/java/com/jdoe/algorithms/CranleyPattersonShiftDOE.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.doe.algorithms;

import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.RealMatrix;
import org.apache.commons.math3.random.RandomDataGenerator;
import org.apache.commons.math3.random.JDKRandomGenerator;

public class CranleyPattersonShiftDOE {

public static RealMatrix cranleyPattersonShift(double[][] points, Integer seed) {
if (points == null || points.length == 0 || points[0].length == 0) {
throw new IllegalArgumentException("Input `points` must be a non-null 2D array with at least one element.");
}

RealMatrix pointsMatrix = new Array2DRowRealMatrix(points);

int nSamples = pointsMatrix.getRowDimension();
int dim = pointsMatrix.getColumnDimension();

// Initialize random generator with seed if provided
RandomDataGenerator rng;
if (seed != null) {
JDKRandomGenerator jdkRng = new JDKRandomGenerator();
jdkRng.setSeed(seed);
rng = new RandomDataGenerator(jdkRng); // Use Apache Commons Math generator
} else {
rng = new RandomDataGenerator();
}

// Generate random shift vector
double[] shiftVector = new double[dim];
for (int i = 0; i < dim; i++) {
shiftVector[i] = rng.nextUniform(0.0, 1.0);
}

// Create a matrix with the shift vector replicated for each sample
double[][] shiftMatrixData = new double[nSamples][dim];
for (int i = 0; i < nSamples; i++) {
for (int j = 0; j < dim; j++) {
shiftMatrixData[i][j] = shiftVector[j];
}
}

RealMatrix shiftMatrix = new Array2DRowRealMatrix(shiftMatrixData);

// Add the shift vector to all points
RealMatrix shiftedPoints = pointsMatrix.add(shiftMatrix);

// Wrap values to [0, 1) using modulo operation
double[][] resultData = shiftedPoints.getData();
for (int i = 0; i < nSamples; i++) {
for (int j = 0; j < dim; j++) {
resultData[i][j] = resultData[i][j] - Math.floor(resultData[i][j]);
}
}

return new Array2DRowRealMatrix(resultData);
}

/**
* Overloaded method without seed parameter
*/
public static RealMatrix cranleyPattersonShift(double[][] points) {
return cranleyPattersonShift(points, null);
}
}
Loading