@iyulab/u-doe 0.6.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -106,7 +106,7 @@ println!("Required replicates: {n}");
106
106
  | Design | Function | Use Case |
107
107
  |--------|----------|----------|
108
108
  | Full Factorial | `full_factorial(k)` | k = 2..7, all factor combinations |
109
- | Fractional Factorial | `fractional_factorial(k, p)` | Screening, k=3..7, p=1..3 |
109
+ | Fractional Factorial | `fractional_factorial(k, p)` | Screening, k=4..7, p=1..3 |
110
110
  | Plackett-Burman | `plackett_burman(k)` | Screening, k ≤ 19, N = 8/12/16/20 |
111
111
  | CCD | `ccd(k, alpha, n_center)` | RSM, k = 2..6 |
112
112
  | Box-Behnken | `box_behnken(k, n_center)` | RSM, k = 3/4/5 |
@@ -157,6 +157,21 @@ Generate a 2^k full factorial design (k = 1..7).
157
157
 
158
158
  Generate a 2^(k-p) fractional factorial design (k = 4..7, p = 1..3).
159
159
 
160
+ #### `fractional_factorial_info(k, p) -> FractionalInfo`
161
+
162
+ Metadata for the fraction `fractional_factorial(k, p)` emits: resolution, defining relation, and generator equations. Use it to derive the alias structure of the design you actually received instead of pairing the matrix with an external published table.
163
+
164
+ **Output:**
165
+ ```json
166
+ {
167
+ "k": 7,
168
+ "p": 3,
169
+ "resolution": "IV",
170
+ "defining_relation": "I=ABCE=BCDF=ACDG=ADEF=BDEG=ABFG=CEFG",
171
+ "generators": ["E=ABC", "F=BCD", "G=ACD"]
172
+ }
173
+ ```
174
+
160
175
  #### `plackett_burman(k) -> DesignMatrix`
161
176
 
162
177
  Generate a Plackett-Burman screening design (k = 1..19).
@@ -204,11 +219,14 @@ Estimate main effects and interactions for a 2-level factorial design.
204
219
  { "name": "A", "columns": [0], "estimate": 21.6, "sum_of_squares": 1870.6, "percent_contribution": 45.2 },
205
220
  { "name": "A:C", "columns": [0, 2], "estimate": -18.1, "sum_of_squares": 1314.1, "percent_contribution": 31.7 }
206
221
  ],
207
- "half_normal": [[18.1, 0.57], [21.6, 1.15]] }
222
+ "half_normal": [{ "term_index": 1, "abs_effect": 18.1, "quantile": 0.57 },
223
+ { "term_index": 0, "abs_effect": 21.6, "quantile": 1.15 }] }
208
224
  ```
209
225
 
210
226
  Interaction names join factor names with `":"` (since 0.5.0; previously bare concatenation `"AC"`). `columns` holds the design-matrix column indices of the term's factors — use it for display formatting (e.g. `"A × C"`) instead of parsing `name`.
211
227
 
228
+ Each `half_normal` point carries `term_index` — an index into `effects` — so a point can be labelled directly (e.g. `effects[point.term_index].name`). The points are sorted by `|effect|`, a **different order** from `effects` (model-term order), so pairing them positionally (`effects[i]` ↔ `half_normal[i]`) mislabels every point; always use `term_index`.
229
+
212
230
  #### `fit_rsm(design, responses, factor_names) -> RsmModel`
213
231
 
214
232
  Fit a second-order Response Surface Model via OLS.
@@ -231,13 +249,17 @@ Compute the steepest ascent path from a fitted RSM model.
231
249
 
232
250
  Compute Derringer-Suich desirability for multiple responses.
233
251
 
234
- **Input:** `specs`: `[{ "goal": "Maximize"|"Minimize"|"Target", "lower": 0, "target": 100, "upper": 100, "s1": 1, "s2": 1 }]`, `responses`: `Float64Array`
252
+ **Input:** `specs`: `[{ "goal": "Maximize"|"Minimize"|"Target", "lower": 0, "target": 100, "upper": 100, "s1": 1, "s2": 1, "importance": 1 }]`, `responses`: `Float64Array`
253
+
254
+ `s1`/`s2` are curve-shape exponents (`s = 1` linear, `> 1` convex/stricter, `< 1` concave). `importance` (optional, default `1`) is the Derringer-Suich response weight rᵢ — it is **distinct from** the shape exponents: raise `importance` to make a response count more in the aggregate, not to reshape its curve.
235
255
 
236
256
  **Output:**
237
257
  ```json
238
258
  { "individual": [0.8, 0.6], "overall": 0.69 }
239
259
  ```
240
260
 
261
+ `overall` is the importance-weighted geometric mean D = (∏ dᵢ^rᵢ)^(1/Σrᵢ); with all weights at the default `1` this is the plain geometric mean.
262
+
241
263
  #### `two_level_factorial_power(k, p, n_replicates, effect_size, sigma, alpha) -> f64`
242
264
 
243
265
  Compute statistical power of a 2^(k-p) factorial design. Returns power in [0, 1].
package/node/u_doe.cjs CHANGED
@@ -73,10 +73,13 @@ exports.definitive_screening = definitive_screening;
73
73
  * Compute Derringer-Suich desirability for multiple responses.
74
74
  *
75
75
  * `specs`: native array of response specification objects, each:
76
- * `{ goal: "Maximize"|"Minimize"|"Target", lower, target, upper, s1, s2 }`
76
+ * `{ goal: "Maximize"|"Minimize"|"Target", lower, target, upper, s1, s2, importance? }`
77
+ * where `s1`/`s2` are curve-shape exponents and the optional `importance`
78
+ * (default 1.0) is the Derringer-Suich weight rᵢ for the overall aggregation.
77
79
  * `responses`: flat array of observed response values (one per spec).
78
80
  *
79
- * Returns `{ individual: [f64], overall: f64 }`.
81
+ * Returns `{ individual: [f64], overall: f64 }` where `overall` is the
82
+ * importance-weighted geometric mean (∏ dᵢ^rᵢ)^(1/Σrᵢ).
80
83
  *
81
84
  * # Errors
82
85
  * Returns an error string if `specs` has the wrong shape (native JS values,
@@ -138,7 +141,10 @@ exports.doe_anova = doe_anova;
138
141
  * `max_order`: maximum interaction order (1 = main effects only, 2 = + 2FI, 3 = + 3FI).
139
142
  *
140
143
  * Returns `{ effects: [{ name, columns, estimate, sum_of_squares, percent_contribution }],
141
- * half_normal: [[abs_effect, quantile]] }`.
144
+ * half_normal: [{ term_index, abs_effect, quantile }] }`.
145
+ * Each `half_normal` point carries `term_index` (an index into `effects`) so the
146
+ * point can be labelled directly — the points are sorted by `|effect|`, a
147
+ * different order from `effects`, so positional pairing would mislabel them.
142
148
  *
143
149
  * # Errors
144
150
  * Returns an error string if dimensions do not match or an argument has the
@@ -213,6 +219,33 @@ function fractional_factorial(k, p) {
213
219
  }
214
220
  exports.fractional_factorial = fractional_factorial;
215
221
 
222
+ /**
223
+ * Metadata for a 2^(k-p) fractional factorial design: resolution, defining
224
+ * relation, and generator equations of the fraction `fractional_factorial(k, p)`
225
+ * actually emits — lets consumers derive the alias structure without pairing
226
+ * the design with an external published table.
227
+ *
228
+ * Returns `{ k: usize, p: usize, resolution: "III"|"IV"|"V",
229
+ * defining_relation: str, generators: [str] }` —
230
+ * e.g. `{ k: 7, p: 3, resolution: "IV",
231
+ * defining_relation: "I=ABCE=BCDF=ACDG=ADEF=BDEG=ABFG=CEFG",
232
+ * generators: ["E=ABC", "F=BCD", "G=ACD"] }`.
233
+ *
234
+ * # Errors
235
+ * Returns an error string if the (k, p) combination is not in the standard table.
236
+ * @param {number} k
237
+ * @param {number} p
238
+ * @returns {any}
239
+ */
240
+ function fractional_factorial_info(k, p) {
241
+ const ret = wasm.fractional_factorial_info(k, p);
242
+ if (ret[2]) {
243
+ throw takeFromExternrefTable0(ret[1]);
244
+ }
245
+ return takeFromExternrefTable0(ret[0]);
246
+ }
247
+ exports.fractional_factorial_info = fractional_factorial_info;
248
+
216
249
  /**
217
250
  * Generate a 2^k full factorial design.
218
251
  *
package/node/u_doe.d.cts CHANGED
@@ -42,10 +42,13 @@ export function definitive_screening(k: number): any;
42
42
  * Compute Derringer-Suich desirability for multiple responses.
43
43
  *
44
44
  * `specs`: native array of response specification objects, each:
45
- * `{ goal: "Maximize"|"Minimize"|"Target", lower, target, upper, s1, s2 }`
45
+ * `{ goal: "Maximize"|"Minimize"|"Target", lower, target, upper, s1, s2, importance? }`
46
+ * where `s1`/`s2` are curve-shape exponents and the optional `importance`
47
+ * (default 1.0) is the Derringer-Suich weight rᵢ for the overall aggregation.
46
48
  * `responses`: flat array of observed response values (one per spec).
47
49
  *
48
- * Returns `{ individual: [f64], overall: f64 }`.
50
+ * Returns `{ individual: [f64], overall: f64 }` where `overall` is the
51
+ * importance-weighted geometric mean (∏ dᵢ^rᵢ)^(1/Σrᵢ).
49
52
  *
50
53
  * # Errors
51
54
  * Returns an error string if `specs` has the wrong shape (native JS values,
@@ -81,7 +84,10 @@ export function doe_anova(design: any, responses: Float64Array, factor_names: an
81
84
  * `max_order`: maximum interaction order (1 = main effects only, 2 = + 2FI, 3 = + 3FI).
82
85
  *
83
86
  * Returns `{ effects: [{ name, columns, estimate, sum_of_squares, percent_contribution }],
84
- * half_normal: [[abs_effect, quantile]] }`.
87
+ * half_normal: [{ term_index, abs_effect, quantile }] }`.
88
+ * Each `half_normal` point carries `term_index` (an index into `effects`) so the
89
+ * point can be labelled directly — the points are sorted by `|effect|`, a
90
+ * different order from `effects`, so positional pairing would mislabel them.
85
91
  *
86
92
  * # Errors
87
93
  * Returns an error string if dimensions do not match or an argument has the
@@ -119,6 +125,23 @@ export function fit_rsm(design: any, responses: Float64Array, factor_names: any)
119
125
  */
120
126
  export function fractional_factorial(k: number, p: number): any;
121
127
 
128
+ /**
129
+ * Metadata for a 2^(k-p) fractional factorial design: resolution, defining
130
+ * relation, and generator equations of the fraction `fractional_factorial(k, p)`
131
+ * actually emits — lets consumers derive the alias structure without pairing
132
+ * the design with an external published table.
133
+ *
134
+ * Returns `{ k: usize, p: usize, resolution: "III"|"IV"|"V",
135
+ * defining_relation: str, generators: [str] }` —
136
+ * e.g. `{ k: 7, p: 3, resolution: "IV",
137
+ * defining_relation: "I=ABCE=BCDF=ACDG=ADEF=BDEG=ABFG=CEFG",
138
+ * generators: ["E=ABC", "F=BCD", "G=ACD"] }`.
139
+ *
140
+ * # Errors
141
+ * Returns an error string if the (k, p) combination is not in the standard table.
142
+ */
143
+ export function fractional_factorial_info(k: number, p: number): any;
144
+
122
145
  /**
123
146
  * Generate a 2^k full factorial design.
124
147
  *
Binary file
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "iyulab"
6
6
  ],
7
7
  "description": "Design of Experiments (DOE) framework: factorial, Plackett-Burman, CCD, Box-Behnken, Taguchi, effects analysis, RSM, and desirability optimization.",
8
- "version": "0.6.2",
8
+ "version": "0.8.0",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
package/u_doe.d.ts CHANGED
@@ -42,10 +42,13 @@ export function definitive_screening(k: number): any;
42
42
  * Compute Derringer-Suich desirability for multiple responses.
43
43
  *
44
44
  * `specs`: native array of response specification objects, each:
45
- * `{ goal: "Maximize"|"Minimize"|"Target", lower, target, upper, s1, s2 }`
45
+ * `{ goal: "Maximize"|"Minimize"|"Target", lower, target, upper, s1, s2, importance? }`
46
+ * where `s1`/`s2` are curve-shape exponents and the optional `importance`
47
+ * (default 1.0) is the Derringer-Suich weight rᵢ for the overall aggregation.
46
48
  * `responses`: flat array of observed response values (one per spec).
47
49
  *
48
- * Returns `{ individual: [f64], overall: f64 }`.
50
+ * Returns `{ individual: [f64], overall: f64 }` where `overall` is the
51
+ * importance-weighted geometric mean (∏ dᵢ^rᵢ)^(1/Σrᵢ).
49
52
  *
50
53
  * # Errors
51
54
  * Returns an error string if `specs` has the wrong shape (native JS values,
@@ -81,7 +84,10 @@ export function doe_anova(design: any, responses: Float64Array, factor_names: an
81
84
  * `max_order`: maximum interaction order (1 = main effects only, 2 = + 2FI, 3 = + 3FI).
82
85
  *
83
86
  * Returns `{ effects: [{ name, columns, estimate, sum_of_squares, percent_contribution }],
84
- * half_normal: [[abs_effect, quantile]] }`.
87
+ * half_normal: [{ term_index, abs_effect, quantile }] }`.
88
+ * Each `half_normal` point carries `term_index` (an index into `effects`) so the
89
+ * point can be labelled directly — the points are sorted by `|effect|`, a
90
+ * different order from `effects`, so positional pairing would mislabel them.
85
91
  *
86
92
  * # Errors
87
93
  * Returns an error string if dimensions do not match or an argument has the
@@ -119,6 +125,23 @@ export function fit_rsm(design: any, responses: Float64Array, factor_names: any)
119
125
  */
120
126
  export function fractional_factorial(k: number, p: number): any;
121
127
 
128
+ /**
129
+ * Metadata for a 2^(k-p) fractional factorial design: resolution, defining
130
+ * relation, and generator equations of the fraction `fractional_factorial(k, p)`
131
+ * actually emits — lets consumers derive the alias structure without pairing
132
+ * the design with an external published table.
133
+ *
134
+ * Returns `{ k: usize, p: usize, resolution: "III"|"IV"|"V",
135
+ * defining_relation: str, generators: [str] }` —
136
+ * e.g. `{ k: 7, p: 3, resolution: "IV",
137
+ * defining_relation: "I=ABCE=BCDF=ACDG=ADEF=BDEG=ABFG=CEFG",
138
+ * generators: ["E=ABC", "F=BCD", "G=ACD"] }`.
139
+ *
140
+ * # Errors
141
+ * Returns an error string if the (k, p) combination is not in the standard table.
142
+ */
143
+ export function fractional_factorial_info(k: number, p: number): any;
144
+
122
145
  /**
123
146
  * Generate a 2^k full factorial design.
124
147
  *
package/u_doe.js CHANGED
@@ -5,5 +5,5 @@ import { __wbg_set_wasm } from "./u_doe_bg.js";
5
5
  __wbg_set_wasm(wasm);
6
6
  wasm.__wbindgen_start();
7
7
  export {
8
- box_behnken, ccd, definitive_screening, desirability, doe_anova, estimate_effects, fit_rsm, fractional_factorial, full_factorial, plackett_burman, signal_to_noise, simplex_centroid, simplex_lattice, steepest_ascent, taguchi_array, two_level_factorial_power
8
+ box_behnken, ccd, definitive_screening, desirability, doe_anova, estimate_effects, fit_rsm, fractional_factorial, fractional_factorial_info, full_factorial, plackett_burman, signal_to_noise, simplex_centroid, simplex_lattice, steepest_ascent, taguchi_array, two_level_factorial_power
9
9
  } from "./u_doe_bg.js";
package/u_doe_bg.js CHANGED
@@ -68,10 +68,13 @@ export function definitive_screening(k) {
68
68
  * Compute Derringer-Suich desirability for multiple responses.
69
69
  *
70
70
  * `specs`: native array of response specification objects, each:
71
- * `{ goal: "Maximize"|"Minimize"|"Target", lower, target, upper, s1, s2 }`
71
+ * `{ goal: "Maximize"|"Minimize"|"Target", lower, target, upper, s1, s2, importance? }`
72
+ * where `s1`/`s2` are curve-shape exponents and the optional `importance`
73
+ * (default 1.0) is the Derringer-Suich weight rᵢ for the overall aggregation.
72
74
  * `responses`: flat array of observed response values (one per spec).
73
75
  *
74
- * Returns `{ individual: [f64], overall: f64 }`.
76
+ * Returns `{ individual: [f64], overall: f64 }` where `overall` is the
77
+ * importance-weighted geometric mean (∏ dᵢ^rᵢ)^(1/Σrᵢ).
75
78
  *
76
79
  * # Errors
77
80
  * Returns an error string if `specs` has the wrong shape (native JS values,
@@ -131,7 +134,10 @@ export function doe_anova(design, responses, factor_names, effect_names) {
131
134
  * `max_order`: maximum interaction order (1 = main effects only, 2 = + 2FI, 3 = + 3FI).
132
135
  *
133
136
  * Returns `{ effects: [{ name, columns, estimate, sum_of_squares, percent_contribution }],
134
- * half_normal: [[abs_effect, quantile]] }`.
137
+ * half_normal: [{ term_index, abs_effect, quantile }] }`.
138
+ * Each `half_normal` point carries `term_index` (an index into `effects`) so the
139
+ * point can be labelled directly — the points are sorted by `|effect|`, a
140
+ * different order from `effects`, so positional pairing would mislabel them.
135
141
  *
136
142
  * # Errors
137
143
  * Returns an error string if dimensions do not match or an argument has the
@@ -203,6 +209,32 @@ export function fractional_factorial(k, p) {
203
209
  return takeFromExternrefTable0(ret[0]);
204
210
  }
205
211
 
212
+ /**
213
+ * Metadata for a 2^(k-p) fractional factorial design: resolution, defining
214
+ * relation, and generator equations of the fraction `fractional_factorial(k, p)`
215
+ * actually emits — lets consumers derive the alias structure without pairing
216
+ * the design with an external published table.
217
+ *
218
+ * Returns `{ k: usize, p: usize, resolution: "III"|"IV"|"V",
219
+ * defining_relation: str, generators: [str] }` —
220
+ * e.g. `{ k: 7, p: 3, resolution: "IV",
221
+ * defining_relation: "I=ABCE=BCDF=ACDG=ADEF=BDEG=ABFG=CEFG",
222
+ * generators: ["E=ABC", "F=BCD", "G=ACD"] }`.
223
+ *
224
+ * # Errors
225
+ * Returns an error string if the (k, p) combination is not in the standard table.
226
+ * @param {number} k
227
+ * @param {number} p
228
+ * @returns {any}
229
+ */
230
+ export function fractional_factorial_info(k, p) {
231
+ const ret = wasm.fractional_factorial_info(k, p);
232
+ if (ret[2]) {
233
+ throw takeFromExternrefTable0(ret[1]);
234
+ }
235
+ return takeFromExternrefTable0(ret[0]);
236
+ }
237
+
206
238
  /**
207
239
  * Generate a 2^k full factorial design.
208
240
  *
package/u_doe_bg.wasm CHANGED
Binary file