Skip to content

Commit f9d5bc0

Browse files
author
nofa
committed
ff2n,fracfactorial
1 parent e2c03f4 commit f9d5bc0

2 files changed

Lines changed: 94 additions & 27 deletions

File tree

src/main/java/com/jdoe/Testing.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
*/
99
public class Testing
1010
{
11-
//! this main class is used for testing purposes only
11+
//! for testing purposes only does not require a main entry point
1212
public static void main( String[] args )
1313
{
1414
int[] arrayOfLevels = {2,3,6};
15-
FactorialDOE.FullFactorial(arrayOfLevels);
15+
FactorialDOE.fullFactorial(arrayOfLevels);
16+
FactorialDOE.fullFactorial2Level( arrayOfLevels.length );
1617
}
1718
}

src/main/java/com/jdoe/algorithms/FactorialDOE.java

Lines changed: 91 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,16 @@
2323

2424
public class FactorialDOE {
2525

26-
27-
private static final Logger log = LogManager.getLogger(FactorialDOE.class);
26+
private static final Logger log = LogManager.getLogger( FactorialDOE.class );
2827

2928
/**
3029
* Generates a full factorial design matrix for a set of design factors.
3130
* <p>
32-
* A full factorial design enumerates all possible combinations of discrete levels
33-
* for the provided design factors. Each row in the resulting matrix corresponds
34-
* to one combination of factor levels, and each column corresponds to a design factor.
35-
* This method is useful in design of experiments (DOE) where exhaustive sampling
36-
* of the factor space is required.
31+
* A full factorial design enumerates all possible combinations of discrete levels for the provided design factors. Each row in the
32+
* resulting matrix corresponds to one combination of factor levels, and each column corresponds to a design factor. This method is
33+
* useful in design of experiments (DOE) where exhaustive sampling of the factor space is required.
3734
* <p>
38-
* The input is an integer array where each element represents the number of discrete
39-
* levels for a corresponding design factor.
35+
* The input is an integer array where each element represents the number of discrete levels for a corresponding design factor.
4036
* <p>
4137
* Example:
4238
* <pre>
@@ -58,36 +54,106 @@ public class FactorialDOE {
5854
* {1.0,2.0,5.0}}
5955
* </pre>
6056
* <p>
61-
* Notes:
62-
* - Number of rows = product of all input factor levels.
63-
* - Number of columns = number of design factors.
64-
* - Values are zero-indexed, representing the level number for each factor.
65-
* - This method only generates the combinations; it does not perform optimization.
57+
* Notes: - Number of rows = product of all input factor levels. - Number of columns = number of design factors. - Values are
58+
* zero-indexed, representing the level number for each factor. - This method only generates the combinations; it does not perform
59+
* optimization.
6660
*
67-
* @param designFactorLevelArray an array where each element specifies the number of levels for a design factor
61+
* @param designFactorLevelArray
62+
* an array where each element specifies the number of levels for a design factor
6863
*/
69-
public static RealMatrix FullFactorial(int[] designFactorLevelArray) {
64+
public static RealMatrix fullFactorial( int[] designFactorLevelArray ) {
7065
// calculate matrix size by number of combinations
7166
int length = designFactorLevelArray.length;
7267
int combinationCount = 1;
73-
for (int i = 0; i < length; i++) {
74-
combinationCount *= designFactorLevelArray[i];
68+
for ( int i = 0; i < length; i++ ) {
69+
combinationCount *= designFactorLevelArray[ i ];
7570
}
76-
log.debug("Total Combinations: " + combinationCount);
71+
log.debug( "Total Combinations: " + combinationCount );
7772
// create matrix for storing combinations
7873
Array2DRowRealMatrix matrixFactory = new Array2DRowRealMatrix();
79-
RealMatrix matrix = matrixFactory.createMatrix(combinationCount, length);
74+
RealMatrix matrix = matrixFactory.createMatrix( combinationCount, length );
8075

8176
// populate matrix
82-
for (int rowNum = 0; rowNum < combinationCount; rowNum++) {
77+
for ( int rowNum = 0; rowNum < combinationCount; rowNum++ ) {
8378
int temp = rowNum;
84-
for (int colNum = 0; colNum < designFactorLevelArray.length; colNum++) {
85-
matrix.setEntry(rowNum, colNum, temp % designFactorLevelArray[colNum]);
86-
temp /= designFactorLevelArray[colNum];
79+
for ( int colNum = 0; colNum < designFactorLevelArray.length; colNum++ ) {
80+
matrix.setEntry( rowNum, colNum, temp % designFactorLevelArray[ colNum ] );
81+
temp /= designFactorLevelArray[ colNum ];
8782
}
8883
}
89-
log.debug(matrix.toString());
84+
log.debug( matrix.toString() );
9085
return matrix;
9186
}
9287

88+
/**
89+
* Generates a full factorial design matrix for 2-level design factors.
90+
* <p>
91+
* This method creates a design matrix where each factor has exactly two levels: -1 and +1. It's commonly used in screening experiments
92+
* and fractional factorial designs.
93+
* <p>
94+
* The resulting matrix will have 2^k rows (where k is the number of factors) and k columns. Each row represents a unique combination of
95+
* factor levels.
96+
* <p>
97+
* Example usage:
98+
* <pre>
99+
* {@code
100+
* RealMatrix design = FactorialDOE.fullFactorial2Level(3);
101+
* // Generates an 8x3 matrix with all combinations of -1 and +1
102+
* }
103+
* </pre>
104+
* <p>
105+
* Sample output for 2 factors:
106+
* <pre>
107+
* {{-1.0, -1.0},
108+
* { 1.0, -1.0},
109+
* {-1.0, 1.0},
110+
* { 1.0, 1.0}}
111+
* </pre>
112+
*
113+
* @param designFactorCount
114+
* the number of 2-level design factors
115+
*
116+
* @return a RealMatrix containing all possible combinations of factor levels
117+
*
118+
* @throws IllegalArgumentException
119+
* if designFactorCount is negative
120+
*/
121+
public static RealMatrix fullFactorial2Level( int designFactorCount ) {
122+
// create matrix
123+
Integer combinationCount = ( int ) Math.pow( 2, designFactorCount );
124+
Array2DRowRealMatrix matrixFactory = new Array2DRowRealMatrix();
125+
RealMatrix matrix = matrixFactory.createMatrix( combinationCount, designFactorCount );
126+
log.debug( "Total Combinations: " + combinationCount );
127+
// populate matrix
128+
// Generate all binary numbers from 0 to (2^k - 1)
129+
for ( int i = 0; i < combinationCount; i++ ) {
130+
// For each factor/column
131+
for ( int j = 0; j < designFactorCount; j++ ) {
132+
// Check the (k-j-1)-th bit from right
133+
// If bit is 0 → -1, if bit is 1 → 1
134+
int bitPosition = designFactorCount - j - 1;
135+
int bitValue = ( i >> bitPosition ) & 1;
136+
matrix.setEntry( i, j, bitValue == 0 ? -1 : 1 );
137+
}
138+
}
139+
log.debug( matrix.toString() );
140+
return matrix;
141+
}
142+
143+
public static void fractionalFactorial( String generetor ) {
144+
// validate generetor string
145+
if ( !generetor.matches( "^[A-Za-z +\\-]+$" ) ) {
146+
throw new IllegalArgumentException( "Generator string contains invalid characters. Allowed: letters, space, +, -" );
147+
}
148+
int factorCount = 0;
149+
for ( int i = 0; i < generetor.length() - 1; i++ ) {
150+
if ( generetor.contains( " " ) ) {
151+
factorCount += 1;
152+
}
153+
}
154+
if ( generetor.split( " " ).length != factorCount ) {
155+
throw new IllegalArgumentException( "Generator does not match the number of factors" );
156+
}
157+
}
158+
93159
}

0 commit comments

Comments
 (0)