Design of experiments library for Python with comprehensive experimental design capabilities
—
Advanced experimental design algorithms with multiple optimality criteria for creating customized experimental plans. These methods provide maximum statistical efficiency for specific modeling objectives by optimizing mathematical criteria that measure design quality.
Generate optimal experimental designs using various algorithms and optimality criteria.
def optimal_design(
candidates: np.ndarray,
n_points: int,
degree: int,
criterion: Literal["D", "A", "I"] = "D",
method: Literal["sequential", "simple_exchange", "fedorov", "modified_fedorov", "detmax"] = "detmax",
alpha: float = 0.0,
max_iter: int = 200
) -> Tuple[np.ndarray, dict]:
"""
Generate an optimal experimental design using specified algorithm and criterion
Parameters:
- candidates: 2d-array, candidate set (region R) of shape (N0, k)
- n_points: int, requested design size (n >= p recommended)
- degree: int, polynomial degree of the model
- criterion: str, optimality criterion - "D", "A", or "I" (default "D")
- method: str, algorithm - "sequential", "simple_exchange", "fedorov",
"modified_fedorov", or "detmax" (default "detmax")
- alpha: float, augmentation parameter for information matrix (default 0.0)
- max_iter: int, maximum iterations for iterative methods (default 200)
Returns:
- design: 2d-array, selected design points of shape (n_points, k)
- info: dict, design statistics including criterion value and efficiencies
"""Usage Example:
import pyDOE3
import numpy as np
# Generate candidate set for 3 factors
candidates = pyDOE3.doe_optimal.generate_candidate_set(n_factors=3, n_levels=5)
# Create D-optimal design with 15 points for quadratic model
design, info = pyDOE3.doe_optimal.optimal_design(
candidates=candidates,
n_points=15,
degree=2, # quadratic model
criterion="D",
method="detmax"
)
print(f"Design shape: {design.shape}")
print(f"D-efficiency: {info['D_eff']:.3f}")
print(f"Criterion value: {info['score']:.3f}")Create candidate point sets for defining the experimental design space.
def generate_candidate_set(n_factors: int, n_levels: int, bounds: Optional[List[Tuple[float, float]]] = None) -> np.ndarray:
"""
Generate candidate points for design space
Parameters:
- n_factors: int, number of factors
- n_levels: int, number of levels per factor
- bounds: list of tuples, optional, (min, max) bounds for each factor
Returns:
- candidates: 2d-array, candidate points in design space
"""Usage Example:
import pyDOE3
# Generate 5x5x5 grid for 3 factors in [-1, 1] range
candidates = pyDOE3.doe_optimal.generate_candidate_set(n_factors=3, n_levels=5)
# Custom bounds for each factor
bounds = [(-2, 2), (0, 10), (50, 100)]
custom_candidates = pyDOE3.doe_optimal.generate_candidate_set(
n_factors=3, n_levels=7, bounds=bounds
)Modern algorithm for D-optimal designs with excellent convergence properties.
def detmax(candidates: np.ndarray, n_points: int, degree: int, criterion: str = "D", alpha: float = 0.0, max_iter: int = 200) -> np.ndarray:
"""
DETMAX algorithm for optimal experimental design
Parameters:
- candidates: 2d-array, candidate point set
- n_points: int, number of design points to select
- degree: int, polynomial model degree
- criterion: str, optimality criterion
- alpha: float, augmentation parameter
- max_iter: int, maximum iterations
Returns:
- design: 2d-array, optimal design points
"""Classical exchange algorithm for optimal design construction.
def fedorov(candidates: np.ndarray, n_points: int, degree: int, criterion: str = "D", alpha: float = 0.0, max_iter: int = 200) -> np.ndarray:
"""
Fedorov algorithm for optimal experimental design
Parameters:
- candidates: 2d-array, candidate point set
- n_points: int, number of design points to select
- degree: int, polynomial model degree
- criterion: str, optimality criterion
- alpha: float, augmentation parameter
- max_iter: int, maximum iterations
Returns:
- design: 2d-array, optimal design points
"""Enhanced version of Fedorov algorithm with improved performance.
def modified_fedorov(candidates: np.ndarray, n_points: int, degree: int, criterion: str = "D", alpha: float = 0.0, max_iter: int = 200) -> np.ndarray:
"""
Modified Fedorov algorithm for optimal experimental design
Parameters:
- candidates: 2d-array, candidate point set
- n_points: int, number of design points to select
- degree: int, polynomial model degree
- criterion: str, optimality criterion
- alpha: float, augmentation parameter
- max_iter: int, maximum iterations
Returns:
- design: 2d-array, optimal design points
"""Point-exchange algorithm for optimal design improvement.
def simple_exchange_wynn_mitchell(candidates: np.ndarray, n_points: int, degree: int, criterion: str = "D", alpha: float = 0.0, max_iter: int = 200) -> np.ndarray:
"""
Simple Exchange (Wynn-Mitchell) algorithm
Parameters:
- candidates: 2d-array, candidate point set
- n_points: int, number of design points to select
- degree: int, polynomial model degree
- criterion: str, optimality criterion
- alpha: float, augmentation parameter
- max_iter: int, maximum iterations
Returns:
- design: 2d-array, optimal design points
"""Sequential algorithm for optimal design construction.
def sequential_dykstra(candidates: np.ndarray, n_points: int, degree: int, criterion: str = "D", alpha: float = 0.0) -> np.ndarray:
"""
Sequential Dykstra algorithm for optimal design
Parameters:
- candidates: 2d-array, candidate point set
- n_points: int, number of design points to select
- degree: int, polynomial model degree
- criterion: str, optimality criterion
- alpha: float, augmentation parameter
Returns:
- design: 2d-array, optimal design points
"""Maximizes the determinant of the information matrix, minimizing the volume of confidence ellipsoids.
def d_optimality(M: np.ndarray) -> float:
"""
Compute D-optimality criterion value
Parameters:
- M: 2d-array, information matrix
Returns:
- criterion: float, D-optimality value (determinant)
"""Minimizes the trace of the inverse information matrix, minimizing average parameter variance.
def a_optimality(M: np.ndarray) -> float:
"""
Compute A-optimality criterion value
Parameters:
- M: 2d-array, information matrix
Returns:
- criterion: float, A-optimality value (negative trace of inverse)
"""Minimizes the integrated prediction variance over the design region.
def i_optimality(M_X: np.ndarray, moment_matrix: np.ndarray) -> float:
"""
Compute I-optimality criterion value
Parameters:
- M_X: 2d-array, information matrix
- moment_matrix: 2d-array, uniform moment matrix
Returns:
- criterion: float, I-optimality value
"""def c_optimality(M: np.ndarray, c: np.ndarray) -> float:
"""
Compute C-optimality for linear combination of parameters
Parameters:
- M: 2d-array, information matrix
- c: 1d-array, linear combination coefficients
Returns:
- criterion: float, C-optimality value
"""def e_optimality(M: np.ndarray) -> float:
"""
Compute E-optimality (maximum eigenvalue)
Parameters:
- M: 2d-array, information matrix
Returns:
- criterion: float, E-optimality value
"""def g_optimality(M: np.ndarray, candidates: np.ndarray) -> float:
"""
Compute G-optimality (maximum prediction variance)
Parameters:
- M: 2d-array, information matrix
- candidates: 2d-array, candidate points
Returns:
- criterion: float, G-optimality value
"""def build_design_matrix(X: np.ndarray, degree: int) -> np.ndarray:
"""
Build design matrix for polynomial models
Parameters:
- X: 2d-array, design points
- degree: int, polynomial degree
Returns:
- design_matrix: 2d-array, expanded design matrix with polynomial terms
"""def build_uniform_moment_matrix(X: np.ndarray) -> np.ndarray:
"""
Build uniform moment matrix for I-optimality
Parameters:
- X: 2d-array, candidate points
Returns:
- moment_matrix: 2d-array, uniform moment matrix
"""def d_efficiency(X: np.ndarray) -> float:
"""
Compute D-efficiency of experimental design
Parameters:
- X: 2d-array, design matrix
Returns:
- efficiency: float, D-efficiency (0-1 scale)
"""def a_efficiency(X: np.ndarray) -> float:
"""
Compute A-efficiency of experimental design
Parameters:
- X: 2d-array, design matrix
Returns:
- efficiency: float, A-efficiency (0-1 scale)
"""def information_matrix(X: np.ndarray, alpha: float = 0.0) -> np.ndarray:
"""
Compute information matrix from design matrix
Parameters:
- X: 2d-array, design matrix
- alpha: float, augmentation parameter
Returns:
- M: 2d-array, information matrix X^T X + alpha*I
"""def criterion_value(X: np.ndarray, criterion: str, X0: np.ndarray = None, alpha: float = 0.0, M_moment: np.ndarray = None) -> float:
"""
Compute criterion value for design evaluation
Parameters:
- X: 2d-array, design matrix
- criterion: str, optimality criterion name
- X0: 2d-array, optional, candidate set for some criteria
- alpha: float, augmentation parameter
- M_moment: 2d-array, optional, moment matrix for I-optimality
Returns:
- value: float, criterion value
"""| Criterion | Optimizes | Best For | Mathematical Objective |
|---|---|---|---|
| D-optimal | det(X'X) | General parameter estimation | Minimizes confidence region volume |
| A-optimal | tr((X'X)⁻¹) | Parameter precision | Minimizes average parameter variance |
| I-optimal | ∫var(ŷ(x))dx | Prediction accuracy | Minimizes integrated prediction variance |
| C-optimal | c'(X'X)⁻¹c | Specific parameter combinations | Minimizes variance of linear combination |
| E-optimal | λₘᵢₙ(X'X) | Robust estimation | Maximizes minimum eigenvalue |
| G-optimal | max var(ŷ(x)) | Uniform prediction | Minimizes maximum prediction variance |
| Algorithm | Speed | Quality | Best For |
|---|---|---|---|
| DETMAX | Fast | Excellent | D-optimal designs, general use |
| Fedorov | Medium | Good | Classical approach, well-studied |
| Modified Fedorov | Medium | Better | Enhanced Fedorov performance |
| Simple Exchange | Slow | Good | Small problems, educational |
| Sequential | Fast | Fair | Quick approximations |
import pyDOE3
# 1. Generate candidate set
candidates = pyDOE3.doe_optimal.generate_candidate_set(n_factors=4, n_levels=5)
# 2. Create optimal design
design, info = pyDOE3.doe_optimal.optimal_design(
candidates, n_points=20, degree=2, criterion="D", method="detmax"
)
# 3. Evaluate design quality
print(f"D-efficiency: {info['D_eff']:.3f}")
print(f"A-efficiency: {info['A_eff']:.3f}")criteria = ["D", "A", "I"]
results = {}
for crit in criteria:
design, info = pyDOE3.doe_optimal.optimal_design(
candidates, n_points=15, degree=2, criterion=crit
)
results[crit] = {"design": design, "info": info}import numpy as np
from typing import Literal, Tuple, List, Optional
# Algorithm types
OptimalAlgorithm = Literal["sequential", "simple_exchange", "fedorov", "modified_fedorov", "detmax"]
OptimalityCriterion = Literal["D", "A", "I", "C", "E", "G", "V", "S", "T"]
# Design types
DesignMatrix = np.ndarray
CandidateSet = np.ndarray
InformationMatrix = np.ndarray
MomentMatrix = np.ndarray
# Result types
DesignInfo = dict
FactorBounds = List[Tuple[float, float]]Install with Tessl CLI
npx tessl i tessl/pypi-pydoe3