diff --git a/.github/workflows/README.yml.disabled b/.github/workflows/README.yml similarity index 100% rename from .github/workflows/README.yml.disabled rename to .github/workflows/README.yml diff --git a/.github/workflows/cli-tests.yml.disabled b/.github/workflows/cli-tests.yml similarity index 100% rename from .github/workflows/cli-tests.yml.disabled rename to .github/workflows/cli-tests.yml diff --git a/.github/workflows/docs.yml.disabled b/.github/workflows/docs.yml similarity index 100% rename from .github/workflows/docs.yml.disabled rename to .github/workflows/docs.yml diff --git a/.github/workflows/examples.yml.disabled b/.github/workflows/examples.yml similarity index 100% rename from .github/workflows/examples.yml.disabled rename to .github/workflows/examples.yml diff --git a/.github/workflows/ssh-localhost.yml.disabled b/.github/workflows/ssh-localhost.yml similarity index 100% rename from .github/workflows/ssh-localhost.yml.disabled rename to .github/workflows/ssh-localhost.yml diff --git a/.gitignore b/.gitignore index 0d30d51..4a0c49b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ .claude claude -*fz.egg-info +*.egg-info venv build .vscode @@ -21,4 +21,4 @@ build *.sh .coverage results*/ -output/ \ No newline at end of file +output/ diff --git a/CLAUDE.md b/CLAUDE.md index 243f3a7..dbb1f25 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -12,11 +12,12 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co - Reading and parsing output results - Smart caching and retry mechanisms -The four core functions are: +The five core functions are: 1. **`fzi`** - Parse input files to identify variables 2. **`fzc`** - Compile input files by substituting variables 3. **`fzo`** - Parse output files from calculations 4. **`fzr`** - Run complete parametric calculations end-to-end +5. **`fzd`** - Run iterative design of experiments with adaptive algorithms ## Development Setup @@ -63,13 +64,14 @@ python -m pytest tests/test_cli_commands.py::test_fzi_parse_variables -v ## Architecture -The codebase is organized into functional modules (~5700 lines total): +The codebase is organized into functional modules (~7300 lines total): ### Core Modules -- **`fz/core.py`** (913 lines) - Public API functions (`fzi`, `fzc`, `fzo`, `fzr`) +- **`fz/core.py`** (1277 lines) - Public API functions (`fzi`, `fzc`, `fzo`, `fzr`, `fzd`) - Entry points for all parametric computing operations - Orchestrates input compilation, calculation execution, and result parsing + - Implements iterative design of experiments (`fzd`) with algorithm integration - Handles signal interruption and graceful shutdown - **`fz/interpreter.py`** (387 lines) - Variable parsing and formula evaluation @@ -108,15 +110,34 @@ The codebase is organized into functional modules (~5700 lines total): - Structured logging with levels (DEBUG, INFO, WARNING, ERROR) - UTF-8 encoding handling for Windows -- **`fz/cli.py`** (395 lines) - Command-line interface - - Entry points: `fz`, `fzi`, `fzc`, `fzo`, `fzr` +- **`fz/cli.py`** (509 lines) - Command-line interface + - Entry points: `fz`, `fzi`, `fzc`, `fzo`, `fzr`, `fzd` - Argument parsing for all commands - Output formatting (JSON, table, CSV, markdown, HTML) +- **`fz/algorithms.py`** (513 lines) - Algorithm framework for design of experiments + - Base interface for iterative algorithms used by `fzd` + - Algorithm loading from Python files with dynamic import + - Support for initial design, adaptive sampling, and result analysis + - Automatic dependency checking (e.g., numpy, scipy) + - Content detection for analysis results (HTML, JSON, Markdown, key-value) + +- **`fz/shell.py`** (505 lines) - Shell utilities and binary path resolution + - Cross-platform shell command execution with Windows bash detection + - Binary path resolution with `FZ_SHELL_PATH` support + - Caching of binary locations for performance + - Windows .exe extension handling + - Short path conversion for Windows paths with spaces + ### Supporting Modules - **`fz/spinner.py`** (225 lines) - Progress indication for long-running operations -- **`fz/installer.py`** (354 lines) - Model installation from GitHub/URL/zip +- **`fz/installer.py`** (598 lines) - Model and algorithm installation from GitHub/URL/zip + - Install models: `fz install model ` or `fz.install_model(model)` + - Install algorithms: `fz install algorithm ` or `fz.install_algorithm(algorithm)` + - Supports GitHub repositories (`fz-` convention), full URLs, and local zip files + - Project-level (`.fz/models/`, `.fz/algorithms/`) and global (`~/.fz/models/`, `~/.fz/algorithms/`) installation + - Priority system: project-level overrides global ## Key Design Patterns @@ -159,6 +180,18 @@ The codebase is organized into functional modules (~5700 lines total): - Prevents redundant computation when resuming interrupted runs - Glob patterns supported: `cache://archive/*/results` +### 6. Algorithm-Based Design of Experiments (fzd) +- **Iterative adaptive sampling**: Algorithms decide what points to evaluate next based on previous results +- **Algorithm interface**: Each algorithm class implements: + - `get_initial_design()`: Returns initial design points + - `get_next_design()`: Returns next points to evaluate (empty list when done) + - `get_analysis()`: Returns final analysis results + - `get_analysis_tmp()`: [Optional] Returns intermediate progress at each iteration +- **Flexible analysis output**: Algorithms can return text, HTML, JSON, Markdown, or key-value pairs +- **Content detection**: Automatically processes analysis results based on content type +- **Examples**: Monte Carlo sampling, BFGS optimization, Brent's method, random sampling +- **Requires pandas**: fzd returns results as pandas DataFrames + ## Windows-Specific Considerations ### Bash Availability @@ -178,7 +211,7 @@ The codebase is organized into functional modules (~5700 lines total): - All tests in `tests/` directory following pytest conventions - Test files prefixed with `test_` (e.g., `test_cli_commands.py`) - Use pytest fixtures in `conftest.py` for common setup -- Examples: `test_parallel.py`, `test_interrupt_handling.py`, `test_examples_*.py` +- Examples: `test_parallel.py`, `test_interrupt_handling.py`, `test_fzd.py`, `test_examples_*.py` ### Test Patterns 1. Create temporary directory with `tempfile.TemporaryDirectory()` @@ -221,6 +254,16 @@ Each case creates a directory with: - `err.txt` - Standard error - `.fz_hash` - Input file MD5 hashes (for cache matching) +### Example Algorithms +- Location: `examples/algorithms/` directory +- Available algorithms: + - **`montecarlo_uniform.py`** - Uniform random sampling for Monte Carlo integration + - **`randomsampling.py`** - Simple random sampling with configurable iterations + - **`bfgs.py`** - BFGS optimization algorithm (requires scipy) + - **`brent.py`** - Brent's method for 1D optimization (requires scipy) +- Each algorithm demonstrates the standard interface and can serve as a template +- Algorithms can be referenced by file path: `algorithm="examples/algorithms/montecarlo_uniform.py"` + ## Environment Variables ```bash @@ -329,8 +372,41 @@ All public functions and methods must have docstrings with: - Host key validation with interactive fingerprint checking - Timeout and keepalive configurable via environment +### Algorithm Loading and Execution (fzd) +- **Dynamic import**: Algorithms loaded from Python files using `importlib.machinery` +- **Dependency checking**: `__require__` list checked at load time; warns if missing +- **Fixed vs variable inputs**: Separates fixed values from ranges for optimization + - Fixed: `{"x": "5.0"}` → always x=5.0 + - Variable: `{"y": "[0;10]"}` → y varies between 0 and 10 + - Algorithm only controls variable inputs; fixed values merged automatically +- **Analysis content processing**: Detects and processes multiple content types: + - HTML: Saved to `analysis.html` and `iteration_N.html` + - JSON: Parsed and made available as structured data + - Markdown: Saved to `analysis.md` files + - Key-value pairs: Parsed into dictionaries +- **Progress tracking**: Progress bar shows iteration count, evaluations, and ETA +- **Result structure**: Returns dict with: + - `XY`: pandas DataFrame with all input and output values + - `analysis`: Processed analysis results (HTML, plots, metrics, etc.) - excludes internal `_raw` data + - `algorithm`: Algorithm path + - `iterations`: Number of iterations completed + - `total_evaluations`: Total number of function evaluations + - `summary`: Human-readable summary text + ## Common Development Tasks +### Adding a New Algorithm for fzd +1. Create a new Python file in `examples/algorithms/` or any directory +2. Implement a class with required methods: + - `__init__(self, **options)` - Accept algorithm-specific options + - `get_initial_design(self, input_vars, output_vars)` - Return initial design points + - `get_next_design(self, previous_input_vars, previous_output_values)` - Return next points (or empty list when done) + - `get_analysis(self, input_vars, output_values)` - Return final analysis results + - `get_analysis_tmp(self, input_vars, output_values)` [Optional] - Return intermediate results +3. Add optional `__require__` list for dependencies (e.g., `["numpy", "scipy"]`) +4. Test with `fzd()` function +5. See `examples/algorithms/` for reference implementations + ### Adding a New Calculator Type 1. Add runner function to `runners.py` following `_run_*_calculator()` pattern 2. Register in calculator resolution logic diff --git a/README.md b/README.md index 1c1d6c0..5f1b060 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ A powerful Python package for parametric simulations and computational experimen - [Calculator Types](#calculator-types) - [Advanced Features](#advanced-features) - [Complete Examples](#complete-examples) +- [Writing Custom Algorithms for fzd](#writing-custom-algorithms-for-fzd) - [Configuration](#configuration) - [Interrupt Handling](#interrupt-handling) - [Development](#development) @@ -28,22 +29,24 @@ A powerful Python package for parametric simulations and computational experimen ### Core Capabilities -- **🔄 Parametric Studies**: Automatically generate and run all combinations of parameter values (Cartesian product) +- **🔄 Parametric Studies**: Factorial designs (dict with Cartesian product) or non-factorial designs (DataFrame with specific cases) - **⚡ Parallel Execution**: Run multiple cases concurrently across multiple calculators with automatic load balancing - **💾 Smart Caching**: Reuse previous calculation results based on input file hashes to avoid redundant computations - **🔁 Retry Mechanism**: Automatically retry failed calculations with alternative calculators - **🌐 Remote Execution**: Execute calculations on remote servers via SSH with automatic file transfer -- **📊 DataFrame Output**: Results returned as pandas DataFrames with automatic type casting and variable extraction +- **📊 DataFrame I/O**: Input and output using pandas DataFrames with automatic type casting and variable extraction - **🛑 Interrupt Handling**: Gracefully stop long-running calculations with Ctrl+C while preserving partial results - **🔍 Formula Evaluation**: Support for calculated parameters using Python or R expressions - **📁 Directory Management**: Automatic organization of inputs, outputs, and logs for each case +- **🎯 Adaptive Algorithms**: Iterative design of experiments with intelligent sampling strategies (fzd) -### Four Core Functions +### Five Core Functions 1. **`fzi`** - Parse **I**nput files to identify variables 2. **`fzc`** - **C**ompile input files by substituting variable values 3. **`fzo`** - Parse **O**utput files from calculations 4. **`fzr`** - **R**un complete parametric calculations end-to-end +5. **`fzd`** - Run iterative **D**esign of experiments with adaptive algorithms ## Installation @@ -83,7 +86,10 @@ pip install -e git+https://github.com/Funz/fz.git # for SSH support pip install paramiko -# for DataFrame support +# for DataFrame support (recommended) +pip install pandas + +# for fzd (design of experiments) - REQUIRED pip install pandas # for R interpreter support @@ -91,6 +97,9 @@ pip install funz-fz[r] # OR pip install rpy2 # Note: Requires R installed with system libraries - see examples/r_interpreter_example.md + +# for optimization algorithms (scipy-based algorithms in examples/) +pip install scipy numpy ``` ## Quick Start @@ -214,6 +223,7 @@ Available commands: - `fzc` - Compile input files - `fzo` - Read output files - `fzr` - Run parametric calculations +- `fzd` - Run design of experiments with adaptive algorithms ### fzi - Parse Input Variables @@ -599,6 +609,47 @@ fzr input.txt \ # Only runs the remaining cases ``` +### fzd - Run Design of Experiments + +Run iterative design of experiments with adaptive algorithms: + +```bash +# Basic usage with Monte Carlo algorithm +fzd input.txt \ + --model perfectgas \ + --variables '{"T_celsius": "[10;50]", "V_L": "[1;10]", "n_mol": 1}' \ + --calculator "sh://bash PerfectGazPressure.sh" \ + --output-expression "pressure" \ + --algorithm examples/algorithms/montecarlo_uniform.py \ + --algorithm-options '{"batch_sample_size": 20, "max_iterations": 10}' \ + --analysis-dir fzd_results/ + +# With optimization algorithm (BFGS) +fzd input.txt \ + --model perfectgas \ + --variables '{"T_celsius": "[10;50]", "V_L": "[1;10]", "n_mol": 1}' \ + --calculator "sh://bash calc.sh" \ + --output-expression "pressure" \ + --algorithm examples/algorithms/bfgs.py \ + --algorithm-options '{"minimize": true, "max_iterations": 50}' \ + --analysis-dir optimization_results/ + +# Fixed and variable inputs +fzd input.txt \ + --model perfectgas \ + --variables '{"T_celsius": "[10;50]", "V_L": "5.0", "n_mol": 1}' \ + --calculator "sh://bash calc.sh" \ + --output-expression "pressure" \ + --algorithm examples/algorithms/brent.py \ + --analysis-dir brent_results/ +``` + +**Key Differences from fzr**: +- Variables use `"[min;max]"` for ranges (algorithm decides values) or `"value"` for fixed +- Requires `--algorithm` parameter with path to algorithm file +- Optionally accepts `--algorithm-options` as JSON dict +- Returns DataFrame with all sampled points and analysis results + ### Environment Variables for CLI ```bash @@ -618,6 +669,10 @@ fzr input.txt --model perfectgas ... export FZ_SSH_AUTO_ACCEPT_HOSTKEYS=1 # Use with caution export FZ_SSH_KEEPALIVE=300 fzr input.txt --calculator "ssh://user@host/bash calc.sh" ... + +# Shell path for binary resolution (Windows) +export FZ_SHELL_PATH="C:\msys64\usr\bin;C:\msys64\mingw64\bin" +fzr input.txt --model perfectgas ... ``` ## Core Functions @@ -767,13 +822,150 @@ print(results) **Parameters**: - `input_path`: Input file or directory path -- `input_variables`: Variable values (creates Cartesian product of lists) +- `input_variables`: Variable values - dict (factorial) or DataFrame (non-factorial) - `model`: Model definition (dict or alias) - `calculators`: Calculator URI(s) - string or list - `results_dir`: Results directory path **Returns**: pandas DataFrame with all results +### fzd - Run Design of Experiments + +Execute iterative design of experiments with adaptive algorithms: + +```python +import fz + +model = { + "varprefix": "$", + "output": { + "result": "grep 'Result:' output.txt | awk '{print $2}'" + } +} + +# Run Monte Carlo sampling +results = fz.fzd( + input_path="input.txt", + input_variables={ + "x": "[0;10]", # Range: algorithm decides values + "y": "[-5;5]", # Range: algorithm decides values + "z": "2.5" # Fixed value + }, + model=model, + output_expression="result", + algorithm="examples/algorithms/montecarlo_uniform.py", + calculators=["sh://bash calculate.sh"], + algorithm_options={"batch_sample_size": 10, "max_iterations": 20}, + analysis_dir="results_fzd" +) + +# Results include: +# - results['XY']: DataFrame with all input/output values +# - results['analysis']: Processed analysis (HTML, plots, metrics, etc.) +# - results['iterations']: Number of iterations completed +# - results['total_evaluations']: Total function evaluations +# - results['summary']: Summary text +print(results['XY']) # All sampled points and outputs +print(results['summary']) # Algorithm completion summary +``` + +**Algorithm Examples**: +- `examples/algorithms/montecarlo_uniform.py` - Uniform random sampling +- `examples/algorithms/randomsampling.py` - Simple random sampling +- `examples/algorithms/bfgs.py` - BFGS optimization (requires scipy) +- `examples/algorithms/brent.py` - Brent's 1D optimization (requires scipy) + +**Parameters**: +- `input_file`: Input file or directory path +- `input_variables`: Dict with `"[min;max]"` for ranges or `"value"` for fixed +- `model`: Model definition (dict or alias) +- `output_expression`: Expression to evaluate from outputs (e.g., `"pressure"` or `"out1 + out2 * 2"`) +- `algorithm`: Path to algorithm Python file +- `calculators`: Calculator URI(s) - string or list +- `algorithm_options`: Dict of algorithm-specific options +- `analysis_dir`: Analysis results directory + +**Returns**: Dict with: +- `XY`: pandas DataFrame with all input and output values +- `analysis`: Processed analysis results (HTML files, plots, metrics) +- `algorithm`: Algorithm path +- `iterations`: Number of iterations completed +- `total_evaluations`: Total number of function evaluations +- `summary`: Human-readable summary text + +### Input Variables: Factorial vs Non-Factorial Designs + +FZ supports two types of parametric study designs through different `input_variables` formats: + +#### Factorial Design (Dict) + +Use a **dict** to create a full factorial design (Cartesian product of all variable values): + +```python +# Dict with lists creates ALL combinations (factorial) +input_variables = { + "temp": [100, 200, 300], # 3 values + "pressure": [1.0, 2.0] # 2 values +} +# Creates 6 cases: 3 × 2 = 6 +# (100,1.0), (100,2.0), (200,1.0), (200,2.0), (300,1.0), (300,2.0) + +results = fz.fzr(input_file, input_variables, model, calculators) +``` + +**Use factorial design when:** +- You want to explore all possible combinations +- Variables are independent +- You need a complete design space exploration + +#### Non-Factorial Design (DataFrame) + +Use a **pandas DataFrame** to specify exactly which cases to run (non-factorial): + +```python +import pandas as pd + +# DataFrame: each row is ONE case (non-factorial) +input_variables = pd.DataFrame({ + "temp": [100, 200, 100, 300], + "pressure": [1.0, 1.0, 2.0, 1.5] +}) +# Creates 4 cases ONLY: +# (100,1.0), (200,1.0), (100,2.0), (300,1.5) +# Note: (100,2.0) is included but (200,2.0) is not + +results = fz.fzr(input_file, input_variables, model, calculators) +``` + +**Use non-factorial design when:** +- You have specific combinations to test +- Variables are coupled or have constraints +- You want to import a design from another tool +- You need an irregular or optimized sampling pattern + +**Examples of non-factorial patterns:** +```python +# Latin Hypercube Sampling +import pandas as pd +from scipy.stats import qmc + +sampler = qmc.LatinHypercube(d=2) +sample = sampler.random(n=10) +input_variables = pd.DataFrame({ + "x": sample[:, 0] * 100, # Scale to [0, 100] + "y": sample[:, 1] * 10 # Scale to [0, 10] +}) + +# Constraint-based design (only valid combinations) +input_variables = pd.DataFrame({ + "rpm": [1000, 1500, 2000, 2500], + "load": [10, 20, 40, 50] # load increases with rpm +}) + +# Imported from design of experiments tool +input_variables = pd.read_csv("doe_design.csv") +``` + ## Model Definition A model defines how to parse inputs and extract outputs: @@ -1389,6 +1581,351 @@ results = fz.fzr( print(results[['param', 'calculator', 'status']].head(10)) ``` +### Example 4: Design of Experiments with Adaptive Sampling + +```python +import fz +import matplotlib.pyplot as plt + +# Input template with perfect gas law +# (same as Example 1, but using fzd for adaptive design) + +model = { + "varprefix": "$", + "formulaprefix": "@", + "delim": "{}", + "commentline": "#", + "output": { + "pressure": "grep 'pressure = ' output.txt | awk '{print $3}'" + } +} + +# Run Monte Carlo sampling to explore pressure distribution +results = fz.fzd( + input_path="input.txt", + input_variables={ + "T_celsius": "[10;50]", # Range: 10 to 50°C + "V_L": "[1;10]", # Range: 1 to 10 L + "n_mol": "1.0" # Fixed: 1 mole + }, + model=model, + output_expression="pressure", + algorithm="examples/algorithms/montecarlo_uniform.py", + calculators=["sh://bash PerfectGazPressure.sh"], + algorithm_options={ + "batch_sample_size": 20, # 20 samples per iteration + "max_iterations": 10 # 10 iterations + }, + analysis_dir="monte_carlo_results" +) + +# Results DataFrame has all sampled points +print(f"Total evaluations: {results['total_evaluations']}") +print(f"Iterations: {results['iterations']}") +print(results['summary']) + +# Access the data +df = results['XY'] +print(df.head()) + +# Plot the sampled points +fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) + +# Scatter plot: Temperature vs Volume colored by Pressure +scatter = ax1.scatter(df['T_celsius'], df['V_L'], c=df['pressure'], + cmap='viridis', s=50, alpha=0.6) +ax1.set_xlabel('Temperature (°C)') +ax1.set_ylabel('Volume (L)') +ax1.set_title('Sampled Design Space') +plt.colorbar(scatter, ax=ax1, label='Pressure (Pa)') + +# Histogram of pressure values +ax2.hist(df['pressure'], bins=20, edgecolor='black') +ax2.set_xlabel('Pressure (Pa)') +ax2.set_ylabel('Frequency') +ax2.set_title('Pressure Distribution') + +plt.tight_layout() +plt.savefig('monte_carlo_analysis.png') +print("Analysis plot saved to monte_carlo_analysis.png") +``` + +### Example 5: Optimization with BFGS + +```python +import fz + +# Find temperature and volume that minimize pressure + +model = { + "varprefix": "$", + "formulaprefix": "@", + "delim": "{}", + "commentline": "#", + "output": { + "pressure": "grep 'pressure = ' output.txt | awk '{print $3}'" + } +} + +results = fz.fzd( + input_path="input.txt", + input_variables={ + "T_celsius": "[10;50]", # Search range + "V_L": "[1;10]", # Search range + "n_mol": "1.0" # Fixed + }, + model=model, + output_expression="pressure", + algorithm="examples/algorithms/bfgs.py", + calculators=["sh://bash PerfectGazPressure.sh"], + algorithm_options={ + "minimize": True, # Minimize pressure + "max_iterations": 50 + }, + analysis_dir="optimization_results" +) + +# Get optimal point +df = results['XY'] +optimal_idx = df['pressure'].idxmin() +optimal = df.loc[optimal_idx] + +print(f"Optimal temperature: {optimal['T_celsius']:.2f}°C") +print(f"Optimal volume: {optimal['V_L']:.2f} L") +print(f"Minimum pressure: {optimal['pressure']:.2f} Pa") +print(f"Total evaluations: {results['total_evaluations']}") + +# Plot optimization path +import matplotlib.pyplot as plt +plt.figure(figsize=(10, 6)) +plt.scatter(df['T_celsius'], df['V_L'], c=df['pressure'], + cmap='coolwarm', s=100, edgecolor='black') +plt.plot(df['T_celsius'], df['V_L'], 'k--', alpha=0.3, label='Optimization path') +plt.scatter(optimal['T_celsius'], optimal['V_L'], + color='red', s=300, marker='*', + edgecolor='black', label='Optimum') +plt.xlabel('Temperature (°C)') +plt.ylabel('Volume (L)') +plt.title('BFGS Optimization Path') +plt.colorbar(label='Pressure (Pa)') +plt.legend() +plt.savefig('optimization_path.png') +print("Optimization path saved to optimization_path.png") +``` + +## Writing Custom Algorithms for fzd + +FZ provides an extensible framework for implementing adaptive algorithms. Each algorithm is a Python class with specific methods. + +### Algorithm Interface + +Create a Python file with a class implementing these methods: + +```python +class MyAlgorithm: + """Custom algorithm for design of experiments""" + + def __init__(self, **options): + """ + Initialize algorithm with options passed from algorithm_options. + + Args: + **options: Algorithm-specific parameters (e.g., batch_size, max_iter) + """ + self.batch_size = options.get('batch_size', 10) + self.max_iterations = options.get('max_iterations', 100) + self.iteration = 0 + + def get_initial_design(self, input_vars, output_vars): + """ + Return initial design points to evaluate. + + Args: + input_vars: Dict[str, tuple] - {var_name: (min, max)} + e.g., {"x": (0.0, 10.0), "y": (-5.0, 5.0)} + output_vars: List[str] - Output variable names + + Returns: + List[Dict[str, float]] - Initial points to evaluate + e.g., [{"x": 0.5, "y": 0.0}, {"x": 7.5, "y": 2.3}] + """ + # Generate initial sample points + import random + points = [] + for _ in range(self.batch_size): + point = { + var: random.uniform(bounds[0], bounds[1]) + for var, bounds in input_vars.items() + } + points.append(point) + return points + + def get_next_design(self, previous_input_vars, previous_output_values): + """ + Return next design points based on previous results. + + Args: + previous_input_vars: List[Dict[str, float]] - All previous input combinations + previous_output_values: List[float] - Corresponding outputs (may contain None) + + Returns: + List[Dict[str, float]] - Next points to evaluate + Empty list [] signals algorithm is finished + """ + self.iteration += 1 + + # Stop if max iterations reached + if self.iteration >= self.max_iterations: + return [] # Empty list = finished + + # Generate next batch based on results + # ... your adaptive logic here ... + + return next_points + + def get_analysis(self, input_vars, output_values): + """ + Return final analysis results. + + Args: + input_vars: List[Dict[str, float]] - All evaluated inputs + output_values: List[float] - All outputs (may contain None) + + Returns: + Dict with analysis information (can include 'text', 'data', etc.) + """ + # Filter out failed evaluations (None values) + valid_results = [(x, y) for x, y in zip(input_vars, output_values) if y is not None] + + return { + 'text': f"Algorithm completed: {len(valid_results)} successful evaluations", + 'data': {'mean': sum(y for _, y in valid_results) / len(valid_results)} + } + + def get_analysis_tmp(self, input_vars, output_values): + """ + [OPTIONAL] Return intermediate results at each iteration. + + Args: + input_vars: List[Dict[str, float]] - All inputs so far + output_values: List[float] - All outputs so far + + Returns: + Dict with intermediate analysis information + """ + valid_count = sum(1 for y in output_values if y is not None) + return { + 'text': f"Iteration {self.iteration}: {valid_count} valid samples" + } +``` + +### Algorithm Examples + +#### 1. Monte Carlo Sampling + +See `examples/algorithms/montecarlo_uniform.py`: + +```python +import fz + +results = fz.fzd( + input_path="input.txt", + input_variables={"x": "[0;10]", "y": "[0;5]"}, + model="mymodel", + output_expression="result", + algorithm="examples/algorithms/montecarlo_uniform.py", + calculators=["sh://bash calc.sh"], + algorithm_options={"batch_sample_size": 20, "max_iterations": 10} +) +``` + +#### 2. BFGS Optimization + +See `examples/algorithms/bfgs.py` (requires scipy): + +```python +results = fz.fzd( + input_path="input.txt", + input_variables={"x": "[0;10]", "y": "[0;5]"}, + model="mymodel", + output_expression="energy", + algorithm="examples/algorithms/bfgs.py", + calculators=["sh://bash calc.sh"], + algorithm_options={"minimize": True, "max_iterations": 50} +) +``` + +#### 3. Brent's Method (1D Optimization) + +See `examples/algorithms/brent.py` (requires scipy): + +```python +results = fz.fzd( + input_path="input.txt", + input_variables={"temperature": "[0;100]"}, # Single variable + model="mymodel", + output_expression="efficiency", + algorithm="examples/algorithms/brent.py", + calculators=["sh://bash calc.sh"], + algorithm_options={"minimize": False} # Maximize efficiency +) +``` + +### Algorithm Features + +#### Content Format Detection + +Algorithms can return analysis results in multiple formats: + +```python +def get_analysis(self, input_vars, output_values): + # Return HTML + return { + 'text': '

Results

Mean: 42.5

', + 'data': {'mean': 42.5} + } + # Saved to: analysis_.html + + # Return JSON + return { + 'text': '{"mean": 42.5, "std": 3.2}', + 'data': {} + } + # Saved to: analysis_.json + + # Return Markdown + return { + 'text': '# Results\n\n**Mean**: 42.5\n**Std**: 3.2', + 'data': {} + } + # Saved to: analysis_.md + + # Return key-value format + return { + 'text': 'mean=42.5\nstd=3.2\nsamples=100', + 'data': {} + } + # Saved to: analysis_.txt +``` + +See `docs/FZD_CONTENT_FORMATS.md` for detailed format documentation. + +#### Dependency Management + +Specify required packages using `__require__`: + +```python +__require__ = ["numpy", "scipy", "matplotlib"] + +class MyAlgorithm: + def __init__(self, **options): + import numpy as np + import scipy.optimize + # ... +``` + +FZ will check dependencies at load time and warn if packages are missing. + ## Configuration ### Environment Variables @@ -1411,6 +1948,11 @@ export FZ_SSH_AUTO_ACCEPT_HOSTKEYS=0 # Default formula interpreter (python or R) export FZ_INTERPRETER=python + +# Custom shell binary search path (for Windows, overrides system PATH) +# Use semicolon separator on Windows, colon on Unix/Linux +export FZ_SHELL_PATH="C:\msys64\usr\bin;C:\msys64\mingw64\bin" # Windows +export FZ_SHELL_PATH="/opt/custom/bin:/usr/local/bin" # Unix/Linux ``` ### Python Configuration @@ -1442,6 +1984,9 @@ your_project/ │ │ └── mymodel.json │ ├── calculators/ # Calculator aliases │ │ └── mycluster.json +│ ├── algorithms/ # Algorithm plugins +│ │ ├── myalgo.py +│ │ └── myalgo.R │ └── tmp/ # Temporary files (auto-created) │ └── fz_temp_*/ # Per-run temp directories └── results/ # Results directory @@ -1456,6 +2001,209 @@ your_project/ └── ... ``` +## Installing Plugins + +FZ supports installing models and algorithms as plugins from GitHub repositories, local zip files, or URLs. + +### Installing Algorithm Plugins + +Algorithm plugins enable design of experiments and optimization workflows. Install algorithms from GitHub repositories in the `fz-` format: + +#### From GitHub Repository Name + +```bash +# Install from Funz organization (convention: fz-) +fz install algorithm montecarlo + +# This installs from: https://github.com/Funz/fz-montecarlo +``` + +```python +# Python API +import fz + +# Install locally (.fz/algorithms/) +fz.install_algorithm("montecarlo") + +# Install globally (~/.fz/algorithms/) +fz.install_algorithm("montecarlo", global_install=True) +``` + +#### From GitHub URL + +```bash +# Install from full URL +fz install algorithm https://github.com/YourOrg/fz-custom-algo +``` + +```python +fz.install_algorithm("https://github.com/YourOrg/fz-custom-algo") +``` + +#### From Local Zip File + +```bash +# Install from downloaded zip +fz install algorithm ./fz-myalgo.zip +``` + +```python +fz.install_algorithm("./fz-myalgo.zip") +``` + +#### Using Installed Algorithms + +Once installed, algorithms can be referenced by name: + +```python +import fz + +# Use installed algorithm plugin +results = fz.fzd( + input_path="input.txt", + input_variables={"x": "[0;10]", "y": "[-5;5]"}, + model="mymodel", + output_expression="result", + algorithm="montecarlo", # Plugin name (no path or extension) + calculators=["sh://bash calc.sh"], + algorithm_options={"batch_sample_size": 20} +) +``` + +### Installing Model Plugins + +Model plugins define input parsing and output extraction patterns. Install models from GitHub: + +#### From GitHub Repository Name + +```bash +# Install from Funz organization (convention: fz-) +fz install model moret + +# This installs from: https://github.com/Funz/fz-moret +``` + +```python +# Python API +import fz + +# Install locally (.fz/models/) +fz.install("moret") + +# Install globally (~/.fz/models/) +fz.install("moret", global_install=True) +``` + +#### From GitHub URL or Local Zip + +```bash +fz install model https://github.com/Funz/fz-moret +fz install model ./fz-moret.zip +``` + +### Listing Installed Plugins + +```bash +# List installed algorithms +fz list algorithms + +# List only global algorithms +fz list algorithms --global + +# List installed models +fz list models + +# List only global models +fz list models --global +``` + +```python +# Python API +import fz + +# List algorithms +algorithms = fz.list_algorithms() +for name, info in algorithms.items(): + print(f"{name} ({info['type']}) - {info['file']}") + +# List models +models = fz.list_models() +for name, model in models.items(): + print(f"{name}: {model.get('id', 'N/A')}") +``` + +### Uninstalling Plugins + +```bash +# Uninstall algorithm +fz uninstall algorithm montecarlo + +# Uninstall from global location +fz uninstall algorithm montecarlo --global + +# Uninstall model +fz uninstall model moret +``` + +```python +# Python API +import fz + +# Uninstall algorithm +fz.uninstall_algorithm("montecarlo") + +# Uninstall model +fz.uninstall("moret") +``` + +### Plugin Priority + +When the same plugin exists in multiple locations, FZ uses the following priority: + +1. **Project-level** (`.fz/algorithms/` or `.fz/models/`) - Highest priority +2. **Global** (`~/.fz/algorithms/` or `~/.fz/models/`) - Fallback + +This allows project-specific customization while maintaining a personal library of reusable plugins. + +### Creating Algorithm Plugins + +To create your own algorithm plugin repository (for sharing or distribution): + +1. **Create repository** named `fz-` (e.g., `fz-montecarlo`) + +2. **Add algorithm file** as `.py` or `.R` in repository root or `.fz/algorithms/`: + +```python +# montecarlo.py +class MonteCarlo: + def __init__(self, **options): + self.n_samples = options.get("n_samples", 100) + + def get_initial_design(self, input_vars, output_vars): + import random + samples = [] + for _ in range(self.n_samples): + sample = {} + for var, (min_val, max_val) in input_vars.items(): + sample[var] = random.uniform(min_val, max_val) + samples.append(sample) + return samples + + def get_next_design(self, X, Y): + return [] # One-shot sampling + + def get_analysis(self, X, Y): + valid_Y = [y for y in Y if y is not None] + mean = sum(valid_Y) / len(valid_Y) if valid_Y else 0 + return {"text": f"Mean: {mean:.2f}", "data": {"mean": mean}} +``` + +3. **Push to GitHub** and share repository URL + +4. **Install** using `fz install algorithm ` or `fz install algorithm ` + +See `examples/algorithms/PLUGIN_SYSTEM.md` for complete documentation on the algorithm plugin system. + ## Interrupt Handling FZ supports graceful interrupt handling for long-running calculations: @@ -1609,18 +2357,30 @@ python example_interrupt.py # Interactive interrupt demo fz/ ├── fz/ # Main package │ ├── __init__.py # Public API exports -│ ├── core.py # Core functions (fzi, fzc, fzo, fzr) -│ ├── interpreter.py # Variable parsing, formula evaluation -│ ├── runners.py # Calculation execution (sh, ssh) +│ ├── core.py # Core functions (fzi, fzc, fzo, fzr, fzd) +│ ├── interpreter.py # Variable parsing, formula evaluation +│ ├── runners.py # Calculation execution (sh, ssh, cache) │ ├── helpers.py # Parallel execution, retry logic │ ├── io.py # File I/O, caching, hashing +│ ├── algorithms.py # Algorithm framework for fzd +│ ├── shell.py # Shell utilities, binary path resolution │ ├── logging.py # Logging configuration +│ ├── cli.py # Command-line interface │ └── config.py # Configuration management +├── examples/ # Example files +│ └── algorithms/ # Example algorithms for fzd +│ ├── montecarlo_uniform.py # Monte Carlo sampling +│ ├── randomsampling.py # Simple random sampling +│ ├── bfgs.py # BFGS optimization +│ └── brent.py # Brent's 1D optimization ├── tests/ # Test suite │ ├── test_parallel.py # Parallel execution tests │ ├── test_interrupt_handling.py # Interrupt handling tests +│ ├── test_fzd.py # Design of experiments tests │ ├── test_examples_*.py # Example-based tests │ └── ... +├── docs/ # Documentation +│ └── FZD_CONTENT_FORMATS.md # fzd content format documentation ├── README.md # This file └── setup.py # Package configuration ``` diff --git a/SHELL_PATH_IMPLEMENTATION.md b/SHELL_PATH_IMPLEMENTATION.md deleted file mode 100644 index 35d568c..0000000 --- a/SHELL_PATH_IMPLEMENTATION.md +++ /dev/null @@ -1,224 +0,0 @@ -# FZ_SHELL_PATH Implementation Summary - -## Overview - -Implemented a comprehensive shell path configuration system for FZ that allows users to override the system `PATH` environment variable for binary resolution. This is particularly useful on Windows where Unix-like tools (grep, awk, sed, etc.) need to be found in custom locations like MSYS2, Git Bash, or user-defined paths. - -## Key Features - -### 1. Configuration Management -- **New environment variable**: `FZ_SHELL_PATH` - allows users to specify custom binary search paths -- **Path format**: Semicolon-separated on Windows (`;`), colon-separated on Unix/Linux (`:`) -- **Fallback**: If not set, uses system `PATH` environment variable -- **Integration**: Fully integrated into `fz/config.py` with proper configuration loading - -### 2. Binary Resolution System -- **New module**: `fz/shell_path.py` - Implements `ShellPathResolver` class -- **Features**: - - Resolves command names to absolute paths - - Caches resolved paths for performance - - Windows .exe extension handling (automatically tries both `cmd` and `cmd.exe`) - - Lists available binaries in configured paths - - Replaces command names in shell command strings with absolute paths - -### 3. Integration Points - -#### Model Output Expressions (fzo function) -- **File**: `fz/core.py` -- **Integration**: Output commands in model definitions are automatically resolved -- **Example**: - ```python - model = {"output": {"value": "grep 'pattern' output.txt | awk '{print $2}'"}} - # With FZ_SHELL_PATH=/msys64/usr/bin, executes: - # /msys64/usr/bin/grep.exe 'pattern' output.txt | /msys64/usr/bin/awk.exe '{print $2}' - ``` - -#### Shell Calculator Commands (sh://) -- **File**: `fz/runners.py` -- **Integration**: Commands in `sh://` calculator URIs are resolved -- **Example**: - ```python - calculators=["sh://grep 'result' data.txt | awk '{print $2}'"] - # Commands are resolved using FZ_SHELL_PATH - ``` - -### 4. Testing -- **Test file**: `tests/test_shell_path.py` -- **Coverage**: - - ShellPathResolver initialization and caching - - Path resolution on Windows and Unix - - Windows .exe extension handling - - Command string replacement - - Configuration integration - - Global resolver instance management -- **Test count**: 20 passed, 1 skipped -- **All core tests pass**: Verified with `test_cli_commands.py` and `test_examples_advanced.py` - -### 5. Documentation -- **CLAUDE.md**: Updated with comprehensive FZ_SHELL_PATH documentation - - Usage examples for MSYS2, Git Bash, and Unix/Linux - - How the system works - - Implementation details - - Performance considerations -- **Examples**: New `examples/shell_path_example.md` with practical use cases - -## Files Modified - -1. **fz/config.py** - - Added `shell_path` attribute to Config class - - Load `FZ_SHELL_PATH` from environment - - Include in config summary display - -2. **fz/shell_path.py** (NEW) - - `ShellPathResolver` class with full functionality - - Global resolver instance management - - Binary discovery and caching - -3. **fz/core.py** - - Import shell path resolution module - - Apply command resolution in fzo() function (both with and without subdirectories) - - Two locations: subdirectory case (line 556) and single directory case (line 592) - -4. **fz/runners.py** - - Import shell path resolution module - - Apply command resolution in run_local_calculation() function (line 665) - -5. **CLAUDE.md** - - New "Shell Path Configuration" section (lines 234-285) - - Usage examples and implementation details - - Windows-specific guidance - -6. **tests/test_shell_path.py** (NEW) - - Comprehensive test suite for shell path functionality - - Tests for Windows and Unix platforms - - Configuration integration tests - -7. **examples/shell_path_example.md** (NEW) - - Practical usage examples - - Troubleshooting guide - - Common use cases - -## Implementation Details - -### ShellPathResolver Class - -```python -class ShellPathResolver: - def __init__(self, custom_shell_path: Optional[str]): - # Initialize with custom path or None - - def get_search_paths(self) -> List[str]: - # Returns list of directories to search - - def resolve_command(self, command: str) -> Optional[str]: - # Resolves command name to absolute path with caching - - def list_available_binaries(self) -> List[str]: - # Lists all available binaries in search paths - - def replace_commands_in_string(self, command_string: str) -> str: - # Replaces command names with absolute paths in shell commands -``` - -### Global Functions - -- `get_resolver()` - Get global resolver instance -- `resolve_command(command)` - Resolve single command -- `replace_commands_in_string(command_string)` - Replace commands in string -- `reinitialize_resolver()` - Reset resolver after config reload - -### Platform Support - -- **Windows**: - - Semicolon-separated paths - - Automatic .exe extension handling - - Short path (8.3) format support for paths with spaces - -- **Unix/Linux**: - - Colon-separated paths - - Standard executable permission checking - -## Usage - -### Setting FZ_SHELL_PATH - -**Windows Command Prompt:** -```cmd -SET FZ_SHELL_PATH=C:\msys64\usr\bin;C:\msys64\mingw64\bin -fz input.txt -m mymodel -``` - -**Windows PowerShell:** -```powershell -$env:FZ_SHELL_PATH = "C:\msys64\usr\bin;C:\msys64\mingw64\bin" -fz input.txt -m mymodel -``` - -**Unix/Linux Bash:** -```bash -export FZ_SHELL_PATH=/opt/tools/bin:/usr/local/bin -fz input.txt -m mymodel -``` - -### Programmatic Usage - -```python -from fz import fzr -from fz.config import Config -from fz.shell_path import reinitialize_resolver - -# Set custom shell path -import os -os.environ['FZ_SHELL_PATH'] = '/opt/custom/bin' - -# Reinitialize resolver to pick up new path -reinitialize_resolver() - -# Now use fz functions with custom paths -results = fzr("input.txt", variables, model, calculators) -``` - -## Benefits - -1. **Consistency**: Ensure all team members use the same tool versions -2. **Portability**: Don't rely on system PATH which varies across machines -3. **Windows Compatibility**: Seamlessly handle multiple bash environments on Windows -4. **Performance**: Binary paths are cached after first lookup -5. **Flexibility**: Can prioritize custom tool installations over system tools -6. **Backward Compatible**: Works alongside existing code without breaking changes - -## Testing Results - -``` -tests/test_shell_path.py::TestShellPathResolver - 12 tests PASSED -tests/test_shell_path.py::TestGlobalResolver - 3 tests PASSED -tests/test_shell_path.py::TestConfigIntegration - 3 tests PASSED -tests/test_shell_path.py::TestWindowsPathResolution - 2 tests PASSED -tests/test_cli_commands.py - 46 tests PASSED, 3 SKIPPED -tests/test_examples_advanced.py - All tests PASSED -``` - -## Future Enhancements (Optional) - -1. Add Windows registry scanning for tool installations -2. Support for tool version detection and selection -3. Per-calculator shell path configuration -4. Binary aliasing (e.g., gawk → awk) -5. Shell path validation utility command - -## Backward Compatibility - -✅ **Fully backward compatible** -- Existing code works unchanged -- `FZ_SHELL_PATH` is optional -- Falls back to system `PATH` if not set -- No changes to public APIs beyond new functions in `shell_path` module - -## Documentation Status - -✅ Complete -- Code comments and docstrings throughout -- CLAUDE.md documentation with examples -- Example file with use cases -- Inline comments for complex logic -- Type hints on all functions diff --git a/docs/FZD_CONTENT_FORMATS.md b/docs/FZD_CONTENT_FORMATS.md new file mode 100644 index 0000000..82d61ca --- /dev/null +++ b/docs/FZD_CONTENT_FORMATS.md @@ -0,0 +1,300 @@ +# FZD Content Format Handling + +## Overview + +`fzd` (Design of Experiments) intelligently detects and processes different content formats returned by algorithm's `get_analysis()` and `get_analysis_tmp()` methods. Content is automatically saved to appropriate files and parsed into structured Python objects. + +## Supported Formats + +### 1. HTML Content +**Detection**: Presence of HTML tags (``, `
`, `

`, `

`, etc.) + +**Processing**: +- Saved to: `analysis_.html` +- Return structure: `{'html_file': 'analysis_.html'}` + +**Algorithm Example**: +```python +def get_analysis(self, X, Y): + return { + 'text': '

Results

Mean: 42.5

', + 'data': {'mean': 42.5} + } +``` + +**Result**: +- File created: `results_fzd/analysis_1.html` +- Python return: `result['analysis']['html_file'] == 'analysis_1.html'` +- Raw content NOT included in return (replaced with file reference) + +### 2. JSON Content +**Detection**: Text starts with `{` or `[` and is valid JSON + +**Processing**: +- Parsed to Python object +- Saved to: `analysis_.json` +- Return structure: + - `{'json_data': {...}}` - Parsed Python object + - `{'json_file': 'analysis_.json'}` - File reference + +**Algorithm Example**: +```python +def get_analysis(self, X, Y): + return { + 'text': '{"mean": 42.5, "std": 3.2, "samples": 100}', + 'data': {} + } +``` + +**Result**: +- File created: `results_fzd/analysis_1.json` +- Python return: + ```python + result['analysis']['json_data'] == {'mean': 42.5, 'std': 3.2, 'samples': 100} + result['analysis']['json_file'] == 'analysis_1.json' + ``` + +### 3. Key=Value Format +**Detection**: Multiple lines with `=` signs (at least 2) + +**Processing**: +- Parsed to Python dict +- Saved to: `analysis_.txt` +- Return structure: + - `{'keyvalue_data': {...}}` - Parsed dict + - `{'txt_file': 'analysis_.txt'}` - File reference + +**Algorithm Example**: +```python +def get_analysis(self, X, Y): + return { + 'text': '''mean=42.5 +std=3.2 +samples=100 +confidence_interval=[40.1, 44.9]''', + 'data': {} + } +``` + +**Result**: +- File created: `results_fzd/analysis_1.txt` +- Python return: + ```python + result['analysis']['keyvalue_data'] == { + 'mean': '42.5', + 'std': '3.2', + 'samples': '100', + 'confidence_interval': '[40.1, 44.9]' + } + result['analysis']['txt_file'] == 'analysis_1.txt' + ``` + +### 4. Markdown Content +**Detection**: Presence of markdown syntax (`#`, `##`, `*`, `-`, ` ``` `, etc.) + +**Processing**: +- Saved to: `analysis_.md` +- Return structure: `{'md_file': 'analysis_.md'}` + +**Algorithm Example**: +```python +def get_analysis(self, X, Y): + return { + 'text': '''# Analysis Results + +## Statistics +- Mean: 42.5 +- Standard Deviation: 3.2 + +```python +# Algorithm configuration +samples = 100 +``` +''', + 'data': {'mean': 42.5, 'std': 3.2} + } +``` + +**Result**: +- File created: `results_fzd/analysis_1.md` +- Python return: `result['analysis']['md_file'] == 'analysis_1.md'` +- Raw markdown NOT included in return (replaced with file reference) + +### 5. Plain Text +**Detection**: None of the above formats detected + +**Processing**: +- Kept as-is in the return dict +- Return structure: `{'text': 'plain text content...'}` + +**Algorithm Example**: +```python +def get_analysis(self, X, Y): + return { + 'text': 'Mean: 42.5, Std: 3.2, Samples: 100', + 'data': {'mean': 42.5, 'std': 3.2} + } +``` + +**Result**: +- No file created +- Python return: `result['analysis']['text'] == 'Mean: 42.5, Std: 3.2, Samples: 100'` + +## Multiple Content Types + +Algorithms can return both 'text' and 'html' fields separately: + +```python +def get_analysis(self, X, Y): + return { + 'text': 'Summary: Mean is 42.5 with 100 samples', + 'html': '
', + 'data': {'mean': 42.5, 'samples': 100} + } +``` + +**Result**: +- File created: `results_fzd/analysis_1.html` (from 'html' field) +- Python return: + ```python + result['analysis']['text'] == 'Summary: Mean is 42.5 with 100 samples' + result['analysis']['html_file'] == 'analysis_1.html' + result['analysis']['data'] == {'mean': 42.5, 'samples': 100} + ``` + +## FZD Return Structure + +The complete structure returned by `fzd()`: + +```python +result = { + 'XY': pd.DataFrame, # All input variables and output values + + 'analysis': { # Processed analysis from get_analysis() + 'data': {...}, # Numeric/structured data from algorithm + + # Content-specific fields (depending on format detected): + 'html_file': 'analysis_N.html', # If HTML detected + 'json_data': {...}, # If JSON detected (parsed) + 'json_file': 'analysis_N.json', # JSON file reference + 'keyvalue_data': {...}, # If key=value detected (parsed) + 'txt_file': 'analysis_N.txt', # Key=value file reference + 'md_file': 'analysis_N.md', # If markdown detected + 'text': '...', # Plain text (no format detected) + }, + + 'algorithm': 'path/to/algorithm.py', + 'iterations': 5, + 'total_evaluations': 100, + 'summary': 'algorithm completed: 5 iterations, 100 evaluations (95 valid)' +} +``` + +## Accessing Results + +### Access parsed data: +```python +# For JSON format +mean = result['analysis']['json_data']['mean'] + +# For key=value format +mean = float(result['analysis']['keyvalue_data']['mean']) + +# For data dict (always available) +mean = result['analysis']['data']['mean'] +``` + +### Access file paths: +```python +from pathlib import Path + +# HTML file +html_file = Path('results_fzd') / result['analysis']['html_file'] +with open(html_file) as f: + html_content = f.read() + +# JSON file +json_file = Path('results_fzd') / result['analysis']['json_file'] +with open(json_file) as f: + data = json.load(f) +``` + + +## Iteration Files + +For each iteration, `fzd` creates: + +1. **Input data**: `X_.csv` - All input variable values +2. **Output data**: `Y_.csv` - All output values +3. **HTML summary**: `results_.html` - Iteration overview with embedded analysis +4. **Analysis files**: `analysis_.[html|json|txt|md]` - Processed algorithm output + +## Implementation Details + +### Content Detection (fz/io.py) +```python +def detect_content_type(text: str) -> str: + """Returns: 'html', 'json', 'keyvalue', 'markdown', or 'plain'""" +``` + +### Content Processing (fz/io.py) +```python +def process_analysis_content( + analysis_dict: Dict[str, Any], + iteration: int, + results_dir: Path +) -> Dict[str, Any]: + """Process get_analysis() output, detect formats, and save files""" +``` + +### Integration (fz/core.py) +- `_get_and_process_analysis()` - Calls process_analysis_content for each iteration +- Called for both `get_analysis()` (final) and `get_analysis_tmp()` (intermediate) + +## Testing + +Run content detection tests: +```bash +python -m pytest tests/test_fzd.py::TestContentDetection -v +``` + +Run demo: +```bash +python demo_fzd_content_formats.py +``` + +## Best Practices for Algorithm Developers + +1. **Use the 'data' field for structured numeric data** + ```python + return {'data': {'mean': 42.5, 'std': 3.2}, 'text': 'Summary...'} + ``` + +2. **Return JSON for complex structured data** + ```python + import json + return {'text': json.dumps({'results': [...], 'stats': {...}})} + ``` + +3. **Use markdown for formatted text with structure** + ```python + return {'text': '# Results\n\n## Statistics\n- Mean: 42.5\n- Std: 3.2'} + ``` + +4. **Use HTML for rich visualizations** + ```python + return {'html': '
', 'text': 'See plot'} + ``` + +5. **Use key=value for simple parameter lists** + ```python + return {'text': 'mean=42.5\nstd=3.2\nsamples=100'} + ``` + +## Notes + +- Raw HTML, markdown, and large content are saved to files and replaced with file references +- Parsed data (JSON, key=value) is available as Python objects in the analysis dict +- Plain text content remains in `analysis['text']` if no format is detected +- Algorithm text output is logged to console before being processed +- All file references are relative to the analysis_dir diff --git a/examples/algorithms/bfgs.py b/examples/algorithms/bfgs.py new file mode 100644 index 0000000..d6b8fae --- /dev/null +++ b/examples/algorithms/bfgs.py @@ -0,0 +1,87 @@ +#title: BFGS Optimization Algorithm +#author: Test +#type: optimization +#options: max_iter=100;tol=0.000001 + +class Bfgs: + """Simplified BFGS for multi-dimensional optimization""" + + def __init__(self, **options): + self.max_iter = int(options.get('max_iter', 100)) + self.tol = float(options.get('tol', 1e-6)) + self._iteration = 0 + self._var_names = [] + self._finished = False + + def get_initial_design(self, input_vars, output_vars): + self._var_names = list(input_vars.keys()) + # Start at center of search space + center = {var: (bounds[0] + bounds[1]) / 2 + for var, bounds in input_vars.items()} + return [center] + + def get_next_design(self, previous_input_vars, previous_output_values): + if self._finished: + return [] + + self._iteration += 1 + if self._iteration >= self.max_iter: + self._finished = True + return [] + + # Simple: sample around best point + valid_results = [(inp, out) for inp, out in + zip(previous_input_vars, previous_output_values) + if out is not None] + + if not valid_results: + self._finished = True + return [] + + best_input, best_output = min(valid_results, key=lambda x: x[1]) + + # Check if we're done (very simple convergence) + if len(valid_results) > 5: + recent_outputs = [out for _, out in valid_results[-5:]] + if max(recent_outputs) - min(recent_outputs) < self.tol: + self._finished = True + return [] + + # Generate point near best (simple random walk) + import random + next_point = {} + for var in self._var_names: + next_point[var] = best_input[var] + random.uniform(-0.1, 0.1) + + return [next_point] + + def get_analysis(self, input_vars, output_values): + valid_results = [(inp, out) for inp, out in zip(input_vars, output_values) + if out is not None] + + if not valid_results: + return { + 'text': 'No valid results', + 'data': {'iterations': self._iteration, 'evaluations': len(input_vars)} + } + + best_input, best_output = min(valid_results, key=lambda x: x[1]) + + result_text = f"""BFGS Optimization Results: + Iterations: {self._iteration} + Function evaluations: {len(valid_results)} + Optimal output: {best_output:.6g} + Optimal input: {best_input} + Convergence: {'Yes' if self._finished else 'No (max iterations)'} +""" + + return { + 'text': result_text, + 'data': { + 'iterations': self._iteration, + 'evaluations': len(valid_results), + 'optimal_output': best_output, + 'optimal_input': best_input, + 'converged': self._finished, + } + } diff --git a/examples/algorithms/brent.py b/examples/algorithms/brent.py new file mode 100644 index 0000000..50dcd84 --- /dev/null +++ b/examples/algorithms/brent.py @@ -0,0 +1,120 @@ +#title: Brent's Method for 1D Optimization +#author: Test +#type: optimization +#options: max_iter=50;tol=0.00001;initial_points=3 + +import math + +class Brent: + """Brent's method for 1D optimization""" + + def __init__(self, **options): + self.max_iter = int(options.get('max_iter', 50)) + self.tol = float(options.get('tol', 1e-5)) + self.initial_points = int(options.get('initial_points', 3)) + self.golden_ratio = (3.0 - math.sqrt(5.0)) / 2.0 + self._iteration = 0 + self._input_var_name = None + self._var_bounds = None + self._evaluated_points = [] + self._finished = False + + def get_initial_design(self, input_vars, output_vars): + if len(input_vars) != 1: + raise ValueError( + f"Brent's method only works for 1D optimization. " + f"Got {len(input_vars)} variables: {list(input_vars.keys())}" + ) + + self._input_var_name = list(input_vars.keys())[0] + self._var_bounds = input_vars[self._input_var_name] + min_val, max_val = self._var_bounds + + points = [] + for i in range(self.initial_points): + x = min_val + (max_val - min_val) * i / (self.initial_points - 1) + points.append({self._input_var_name: x}) + return points + + def get_next_design(self, previous_input_vars, previous_output_values): + if self._finished: + return [] + + # Add new results + for inp, out in zip(previous_input_vars, previous_output_values): + if out is not None: + x = inp[self._input_var_name] + self._evaluated_points.append((x, out)) + + if len(self._evaluated_points) < self.initial_points: + return [] + + self._evaluated_points.sort(key=lambda p: p[0]) + + self._iteration += 1 + if self._iteration >= self.max_iter: + self._finished = True + return [] + + # Find best three consecutive points + best_idx = min(range(len(self._evaluated_points)), + key=lambda i: self._evaluated_points[i][1]) + + # Simple convergence check + if best_idx > 0 and best_idx < len(self._evaluated_points) - 1: + a_x = self._evaluated_points[best_idx - 1][0] + c_x = self._evaluated_points[best_idx + 1][0] + if abs(c_x - a_x) < self.tol: + self._finished = True + return [] + + # Golden section search + min_val, max_val = self._var_bounds + x_vals = [x for x, f in self._evaluated_points] + + # Find largest gap + all_x = sorted([min_val] + x_vals + [max_val]) + max_gap = 0 + max_gap_mid = None + for i in range(len(all_x) - 1): + gap = all_x[i + 1] - all_x[i] + if gap > max_gap: + max_gap = gap + max_gap_mid = (all_x[i] + all_x[i + 1]) / 2.0 + + if max_gap < self.tol or max_gap_mid is None: + self._finished = True + return [] + + return [{self._input_var_name: max_gap_mid}] + + def get_analysis(self, input_vars, output_values): + valid_results = [(inp, out) for inp, out in zip(input_vars, output_values) + if out is not None] + + if not valid_results: + return { + 'text': 'No valid results', + 'data': {'iterations': self._iteration, 'evaluations': len(input_vars)} + } + + best_input, best_output = min(valid_results, key=lambda x: x[1]) + + result_text = f"""Brent Optimization Results: + Iterations: {self._iteration} + Function evaluations: {len(valid_results)} + Optimal output: {best_output:.6g} + Optimal input: {best_input} + Convergence: {'Yes' if self._finished else 'No (max iterations)'} +""" + + return { + 'text': result_text, + 'data': { + 'iterations': self._iteration, + 'evaluations': len(valid_results), + 'optimal_output': best_output, + 'optimal_input': best_input, + 'converged': self._finished, + } + } diff --git a/examples/algorithms/demo_plugin_system.py b/examples/algorithms/demo_plugin_system.py new file mode 100644 index 0000000..581369d --- /dev/null +++ b/examples/algorithms/demo_plugin_system.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python3 +""" +Demonstration of the algorithm plugin system + +This script demonstrates: +1. Creating an algorithm plugin in .fz/algorithms/ +2. Loading the algorithm by name (not path) +3. Using the plugin with fzd +""" + +import sys +from pathlib import Path +import tempfile +import shutil + +# Add parent directory to path for imports +sys.path.insert(0, str(Path(__file__).parent.parent.parent)) + +def demo_plugin_system(): + """Demonstrate the algorithm plugin system""" + + print("=" * 70) + print("Algorithm Plugin System Demo") + print("=" * 70) + + # Create temporary directory for demo + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + print(f"\nWorking in: {tmpdir}\n") + + # Step 1: Create .fz/algorithms/ directory + print("Step 1: Creating .fz/algorithms/ directory") + algo_dir = tmpdir / ".fz" / "algorithms" + algo_dir.mkdir(parents=True) + print(f" ✓ Created: {algo_dir}\n") + + # Step 2: Create a simple algorithm plugin + print("Step 2: Creating algorithm plugin 'quicksampler.py'") + plugin_file = algo_dir / "quicksampler.py" + plugin_file.write_text(""" +class QuickSampler: + '''Simple random sampler with fixed number of samples''' + + def __init__(self, **options): + self.n_samples = options.get("n_samples", 5) + self.iteration = 0 + + def get_initial_design(self, input_vars, output_vars): + import random + random.seed(42) + + samples = [] + for _ in range(self.n_samples): + sample = {} + for var, (min_val, max_val) in input_vars.items(): + sample[var] = random.uniform(min_val, max_val) + samples.append(sample) + + return samples + + def get_next_design(self, X, Y): + # One-shot sampling - return empty list (finished) + return [] + + def get_analysis(self, X, Y): + valid_Y = [y for y in Y if y is not None] + if not valid_Y: + return {"text": "No valid results", "data": {}} + + mean_val = sum(valid_Y) / len(valid_Y) + min_val = min(valid_Y) + max_val = max(valid_Y) + + return { + "text": f"Sampled {len(valid_Y)} points\\nMean: {mean_val:.2f}\\nRange: [{min_val:.2f}, {max_val:.2f}]", + "data": { + "mean": mean_val, + "min": min_val, + "max": max_val, + "n_samples": len(valid_Y) + } + } +""") + print(f" ✓ Created: {plugin_file.name}\n") + + # Step 3: Load algorithm by name (plugin mode) + print("Step 3: Loading algorithm by name 'quicksampler'") + print(" Note: No .py extension, no path - just the name!") + + import os + os.chdir(tmpdir) # Change to tmpdir so .fz/algorithms/ is found + + from fz.algorithms import load_algorithm + + algo = load_algorithm("quicksampler", n_samples=3) + print(f" ✓ Loaded algorithm: {type(algo).__name__}\n") + + # Step 4: Test the algorithm + print("Step 4: Testing the algorithm") + input_vars = {"x": (0.0, 10.0), "y": (-5.0, 5.0)} + output_vars = ["result"] + + design = algo.get_initial_design(input_vars, output_vars) + print(f" ✓ Generated {len(design)} samples:") + for i, point in enumerate(design): + print(f" Sample {i+1}: x={point['x']:.2f}, y={point['y']:.2f}") + + # Simulate outputs + outputs = [point['x']**2 + point['y']**2 for point in design] + print(f"\n ✓ Simulated outputs (x² + y²):") + for i, val in enumerate(outputs): + print(f" Output {i+1}: {val:.2f}") + + # Get analysis + analysis = algo.get_analysis(design, outputs) + print(f"\n ✓ Analysis:") + for line in analysis['text'].split('\n'): + print(f" {line}") + + print("\n" + "=" * 70) + print("✓ Plugin System Demo Complete!") + print("=" * 70) + + print("\nKey Takeaways:") + print(" • Algorithms stored in .fz/algorithms/") + print(" • Load by name: load_algorithm('quicksampler')") + print(" • Project-level: .fz/algorithms/ (current directory)") + print(" • Global: ~/.fz/algorithms/ (user home)") + print(" • Priority: Project-level overrides global") + print(" • Works with both .py and .R files") + print() + + +def demo_comparison(): + """Show side-by-side comparison of plugin vs direct path""" + + print("\n" + "=" * 70) + print("Plugin vs Direct Path Comparison") + print("=" * 70) + + print("\n📁 Plugin Mode (Recommended):") + print(" • Place file: .fz/algorithms/myalgo.py") + print(" • Load: load_algorithm('myalgo')") + print(" • Benefits: Organized, shareable, clean code") + print() + + print("📄 Direct Path Mode (Still works):") + print(" • Place file: anywhere/myalgo.py") + print(" • Load: load_algorithm('anywhere/myalgo.py')") + print(" • Benefits: Backward compatible, explicit") + print() + + print("🎯 Use plugin mode for:") + print(" • Team projects (commit .fz/algorithms/ to git)") + print(" • Personal library (~/.fz/algorithms/)") + print(" • Clean, maintainable code") + print() + + print("🎯 Use direct path for:") + print(" • Quick experiments") + print(" • External algorithms") + print(" • Legacy code") + print() + + +if __name__ == "__main__": + demo_plugin_system() + demo_comparison() diff --git a/examples/algorithms/montecarlo_uniform.R b/examples/algorithms/montecarlo_uniform.R new file mode 100644 index 0000000..289310b --- /dev/null +++ b/examples/algorithms/montecarlo_uniform.R @@ -0,0 +1,280 @@ + +#title: Estimate mean with given confidence interval range using Monte Carlo +#author: Yann Richet +#type: sampling +#options: batch_sample_size=10;max_iterations=100;confidence=0.9;target_confidence_range=1.0;seed=42 +#require: base64enc + +# Constructor for MonteCarlo_Uniform S3 class +MonteCarlo_Uniform <- function(...) { + # Get options from ... arguments + opts <- list(...) + + # Create object with initial state + # Use an environment for mutable state (idiomatic S3 pattern) + state <- new.env(parent = emptyenv()) + state$n_samples <- 0 + state$variables <- list() + + obj <- list( + options = list( + batch_sample_size = as.integer( + ifelse(is.null(opts$batch_sample_size), 10, opts$batch_sample_size) + ), + max_iterations = as.integer( + ifelse(is.null(opts$max_iterations), 100, opts$max_iterations) + ), + confidence = as.numeric( + ifelse(is.null(opts$confidence), 0.9, opts$confidence) + ), + target_confidence_range = as.numeric( + ifelse(is.null(opts$target_confidence_range), 1.0, opts$target_confidence_range) + ) + ), + state = state # Environment for mutable state + ) + + # Set random seed + seed <- ifelse(is.null(opts$seed), 42, opts$seed) + set.seed(as.integer(seed)) + + # Set S3 class + class(obj) <- "MonteCarlo_Uniform" + + return(obj) +} + +# Generic function definitions (if not already defined) +if (!exists("get_initial_design")) { + get_initial_design <- function(obj, ...) UseMethod("get_initial_design") +} + +if (!exists("get_next_design")) { + get_next_design <- function(obj, ...) UseMethod("get_next_design") +} + +if (!exists("get_analysis")) { + get_analysis <- function(obj, ...) UseMethod("get_analysis") +} + +if (!exists("get_analysis_tmp")) { + get_analysis_tmp <- function(obj, ...) UseMethod("get_analysis_tmp") +} + +# Method: get_initial_design +get_initial_design.MonteCarlo_Uniform <- function(obj, input_variables, output_variables) { + # Store variable bounds in mutable state + # input_variables is a named list: list(var1 = c(min, max), var2 = c(min, max)) + for (v in names(input_variables)) { + bounds <- input_variables[[v]] + if (!is.numeric(bounds) || length(bounds) != 2) { + stop(paste("Input variable", v, "must have c(min, max) bounds for MonteCarlo_Uniform sampling")) + } + obj$state$variables[[v]] <- bounds + } + + return(generate_samples(obj, obj$options$batch_sample_size)) +} + +# Method: get_next_design +get_next_design.MonteCarlo_Uniform <- function(obj, X, Y) { + # Check max iterations + if (obj$state$n_samples >= obj$options$max_iterations * obj$options$batch_sample_size) { + return(list()) # Empty list signals finished + } + + # Filter out NULL/NA values + Y_valid <- Y[!sapply(Y, is.null) & !is.na(Y)] + Y_valid <- unlist(Y_valid) + + if (length(Y_valid) < 2) { + return(generate_samples(obj, obj$options$batch_sample_size)) + } + + # Calculate confidence interval + mean_y <- mean(Y_valid) + n <- length(Y_valid) + se <- sd(Y_valid) / sqrt(n) + + # t-distribution confidence interval + alpha <- 1 - obj$options$confidence + t_critical <- qt(1 - alpha/2, df = n - 1) + conf_int_lower <- mean_y - t_critical * se + conf_int_upper <- mean_y + t_critical * se + conf_range <- conf_int_upper - conf_int_lower + + # Stop if confidence interval is narrow enough + if (conf_range <= obj$options$target_confidence_range) { + return(list()) # Finished + } + + # Generate more samples + return(generate_samples(obj, obj$options$batch_sample_size)) +} + +# Method: get_analysis +get_analysis.MonteCarlo_Uniform <- function(obj, X, Y) { + analysis_dict <- list(text = "", data = list()) + + # Filter out NULL/NA values + Y_valid <- Y[!sapply(Y, is.null) & !is.na(Y)] + Y_valid <- unlist(Y_valid) + + if (length(Y_valid) < 2) { + analysis_dict$text <- "Not enough valid results to analyze statistics" + analysis_dict$data <- list(valid_samples = length(Y_valid)) + return(analysis_dict) + } + + # Calculate statistics + mean_y <- mean(Y_valid) + std_y <- sd(Y_valid) + n <- length(Y_valid) + se <- std_y / sqrt(n) + + # t-distribution confidence interval + alpha <- 1 - obj$options$confidence + t_critical <- qt(1 - alpha/2, df = n - 1) + conf_int_lower <- mean_y - t_critical * se + conf_int_upper <- mean_y + t_critical * se + + # Store data + analysis_dict$data <- list( + mean = mean_y, + std = std_y, + confidence_interval = c(conf_int_lower, conf_int_upper), + n_samples = length(Y_valid), + min = min(Y_valid), + max = max(Y_valid) + ) + + # Create text summary + analysis_dict$text <- sprintf( +"Monte Carlo Sampling Results: + Valid samples: %d + Mean: %.6f + Std: %.6f + %.0f%% confidence interval: [%.6f, %.6f] + Range: [%.6f, %.6f] +", + length(Y_valid), + mean_y, + std_y, + obj$options$confidence * 100, + conf_int_lower, + conf_int_upper, + min(Y_valid), + max(Y_valid) + ) + + # Try to create HTML with histogram + tryCatch({ + # Create histogram plot + png_file <- tempfile(fileext = ".png") + png(png_file, width = 800, height = 600) + + hist(Y_valid, breaks = 20, freq = FALSE, + col = rgb(0, 1, 0, 0.6), + border = "black", + main = "Output Distribution", + xlab = "Output Value", + ylab = "Density") + grid(col = rgb(0, 0, 0, 0.3)) + + # Add mean line + abline(v = mean_y, col = "red", lwd = 2, lty = 2) + legend("topright", + legend = sprintf("Mean: %.3f", mean_y), + col = "red", lty = 2, lwd = 2) + + dev.off() + + # Convert to base64 + if (requireNamespace("base64enc", quietly = TRUE)) { + img_base64 <- base64enc::base64encode(png_file) + + html_output <- sprintf( +'
+

Estimated mean: %.6f

+

%.0f%% confidence interval: [%.6f, %.6f]

+ Histogram +
', + mean_y, + obj$options$confidence * 100, + conf_int_lower, + conf_int_upper, + img_base64 + ) + analysis_dict$html <- html_output + } + + # Clean up temp file + unlink(png_file) + }, error = function(e) { + # If plotting fails, just skip it + }) + + return(analysis_dict) +} + +# Method: get_analysis_tmp +get_analysis_tmp.MonteCarlo_Uniform <- function(obj, X, Y) { + # Filter out NULL/NA values + Y_valid <- Y[!sapply(Y, is.null) & !is.na(Y)] + Y_valid <- unlist(Y_valid) + + if (length(Y_valid) < 2) { + return(list( + text = sprintf(" Progress: %d valid sample(s) collected", length(Y_valid)), + data = list(valid_samples = length(Y_valid)) + )) + } + + # Calculate statistics + mean_y <- mean(Y_valid) + std_y <- sd(Y_valid) + n <- length(Y_valid) + se <- std_y / sqrt(n) + + # t-distribution confidence interval + alpha <- 1 - obj$options$confidence + t_critical <- qt(1 - alpha/2, df = n - 1) + conf_int_lower <- mean_y - t_critical * se + conf_int_upper <- mean_y + t_critical * se + conf_range <- conf_int_upper - conf_int_lower + + return(list( + text = sprintf( + " Progress: %d samples, mean=%.6f, %.0f%% CI range=%.6f", + length(Y_valid), + mean_y, + obj$options$confidence * 100, + conf_range + ), + data = list( + n_samples = length(Y_valid), + mean = mean_y, + std = std_y, + confidence_range = conf_range + ) + )) +} + +# Helper function: generate_samples (not a method, internal use only) +generate_samples <- function(obj, n) { + samples <- list() + + for (i in 1:n) { + sample <- list() + for (v in names(obj$state$variables)) { + bounds <- obj$state$variables[[v]] + sample[[v]] <- runif(1, min = bounds[1], max = bounds[2]) + } + samples[[i]] <- sample + } + + # Update n_samples in state environment (mutable) + obj$state$n_samples <- obj$state$n_samples + n + + return(samples) +} diff --git a/examples/algorithms/montecarlo_uniform.py b/examples/algorithms/montecarlo_uniform.py new file mode 100644 index 0000000..8ff8a90 --- /dev/null +++ b/examples/algorithms/montecarlo_uniform.py @@ -0,0 +1,229 @@ + +#title: Estimate mean with given confidence interval range using Monte Carlo +#author: Yann Richet +#type: sampling +#options: batch_sample_size=10;max_iterations=100;confidence=0.9;target_confidence_range=1.0;seed=42 +#require: numpy;scipy;matplotlib + +class MonteCarlo_Uniform: + """Monte Carlo sampling algorithm with adaptive stopping based on confidence interval""" + + def __init__(self, **options): + """Initialize with algorithm options""" + self.options = {} + self.options["batch_sample_size"] = int(options.get("batch_sample_size", 10)) + self.options["max_iterations"] = int(options.get("max_iterations", 100)) + self.options["confidence"] = float(options.get("confidence", 0.9)) + self.options["target_confidence_range"] = float(options.get("target_confidence_range", 1.0)) + + self.n_samples = 0 + self.variables = {} + + import numpy as np + np.random.seed(int(options.get("seed", 42))) + + def get_initial_design(self, input_variables, output_variables): + """ + Generate initial design + + Args: + input_variables: Dict[str, Tuple[float, float]] - {var: (min, max)} + output_variables: List[str] - output variable names + """ + for v, bounds in input_variables.items(): + # Bounds are already parsed as tuples (min, max) + if isinstance(bounds, tuple) and len(bounds) == 2: + self.variables[v] = bounds + else: + raise ValueError( + f"Input variable {v} must have (min, max) tuple bounds for MonteCarlo_Uniform sampling" + ) + return self._generate_samples(self.options["batch_sample_size"]) + + def get_next_design(self, X, Y): + """ + Generate next design based on convergence criteria + + Args: + X: List[Dict[str, float]] - previous inputs + Y: List[float] - previous outputs (may contain None) + + Returns: + List[Dict[str, float]] - next points, or [] if finished + """ + # Check max iterations + if self.n_samples >= self.options["max_iterations"] * self.options["batch_sample_size"]: + return [] + + # Filter out None values + import numpy as np + from scipy import stats + Y_valid = [y for y in Y if y is not None] + + if len(Y_valid) < 2: + return self._generate_samples(self.options["batch_sample_size"]) + + Y_array = np.array(Y_valid) + mean = np.mean(Y_array) + conf_int = stats.t.interval( + self.options["confidence"], + len(Y_array) - 1, + loc=mean, + scale=stats.sem(Y_array) + ) + conf_range = conf_int[1] - conf_int[0] + + # Stop if confidence interval is narrow enough + if conf_range <= self.options["target_confidence_range"]: + return [] + + # Generate more samples + return self._generate_samples(self.options["batch_sample_size"]) + + def _generate_samples(self, n): + import numpy as np + samples = [] + for _ in range(n): + sample = {} + for v,(min_val,max_val) in self.variables.items(): + sample[v] = np.random.uniform(min_val, max_val) + samples.append(sample) + self.n_samples += n + return samples + + def get_analysis(self, X, Y): + """ + Display results with statistics and histogram + + Args: + X: List[Dict[str, float]] - all evaluated inputs + Y: List[float] - all outputs (may contain None) + + Returns: + Dict with 'text', 'data', and optionally 'html' keys + """ + import numpy as np + from scipy import stats + + analysis_dict = {"text": "", "data": {}} + + # Filter out None values + Y_valid = [y for y in Y if y is not None] + + if len(Y_valid) < 2: + analysis_dict["text"] = "Not enough valid results to analysis statistics" + analysis_dict["data"] = {"valid_samples": len(Y_valid)} + return analysis_dict + + Y_array = np.array(Y_valid) + mean = np.mean(Y_array) + std = np.std(Y_array) + conf_int = stats.t.interval( + self.options["confidence"], + len(Y_array) - 1, + loc=mean, + scale=stats.sem(Y_array) + ) + + # Store data + analysis_dict["data"] = { + "mean": float(mean), + "std": float(std), + "confidence_interval": [float(conf_int[0]), float(conf_int[1])], + "n_samples": len(Y_valid), + "min": float(np.min(Y_array)), + "max": float(np.max(Y_array)) + } + + # Create text summary + analysis_dict["text"] = f"""Monte Carlo Sampling Results: + Valid samples: {len(Y_valid)} + Mean: {mean:.6f} + Std: {std:.6f} + {self.options['confidence']*100:.0f}% confidence interval: [{conf_int[0]:.6f}, {conf_int[1]:.6f}] + Range: [{np.min(Y_array):.6f}, {np.max(Y_array):.6f}] +""" + + # Try to create HTML with histogram + try: + import matplotlib + matplotlib.use('Agg') # Non-interactive backend + import matplotlib.pyplot as plt + import base64 + from io import BytesIO + + plt.figure(figsize=(8, 6)) + plt.hist(Y_array, bins=20, density=True, alpha=0.6, color='g', edgecolor='black') + plt.title("Output Distribution") + plt.xlabel("Output Value") + plt.ylabel("Density") + plt.grid(alpha=0.3) + + # Add mean line + plt.axvline(mean, color='r', linestyle='--', linewidth=2, label=f'Mean: {mean:.3f}') + plt.legend() + + # Convert to base64 + buffered = BytesIO() + plt.savefig(buffered, format="png", dpi=100, bbox_inches='tight') + plt.close() + img_str = base64.b64encode(buffered.getvalue()).decode() + + html_output = f"""
+

Estimated mean: {mean:.6f}

+

{self.options['confidence']*100:.0f}% confidence interval: [{conf_int[0]:.6f}, {conf_int[1]:.6f}]

+ Histogram +
""" + analysis_dict["html"] = html_output + except Exception as e: + # If plotting fails, just skip it + pass + + return analysis_dict + + def get_analysis_tmp(self, X, Y): + """ + Display intermediate results at each iteration + + Args: + X: List[Dict[str, float]] - all evaluated inputs so far + Y: List[float] - all outputs so far (may contain None) + + Returns: + Dict with 'text' and 'data' keys + """ + import numpy as np + from scipy import stats + + # Filter out None values + Y_valid = [y for y in Y if y is not None] + + if len(Y_valid) < 2: + return { + 'text': f" Progress: {len(Y_valid)} valid sample(s) collected", + 'data': {'valid_samples': len(Y_valid)} + } + + Y_array = np.array(Y_valid) + mean = np.mean(Y_array) + std = np.std(Y_array) + conf_int = stats.t.interval( + self.options["confidence"], + len(Y_array) - 1, + loc=mean, + scale=stats.sem(Y_array) + ) + conf_range = conf_int[1] - conf_int[0] + + return { + 'text': f" Progress: {len(Y_valid)} samples, " + f"mean={mean:.6f}, " + f"{self.options['confidence']*100:.0f}% CI range={conf_range:.6f}", + 'data': { + 'n_samples': len(Y_valid), + 'mean': float(mean), + 'std': float(std), + 'confidence_range': float(conf_range) + } + } + diff --git a/examples/algorithms/randomsampling.py b/examples/algorithms/randomsampling.py new file mode 100644 index 0000000..0271b7a --- /dev/null +++ b/examples/algorithms/randomsampling.py @@ -0,0 +1,60 @@ +#title: Random Sampling Algorithm +#author: Test +#type: sampling +#options: nvalues=10;seed=42 + +import random + +class Randomsampling: + """Random sampling algorithm for design of experiments""" + + def __init__(self, **options): + self.nvalues = int(options.get('nvalues', 10)) + seed = options.get('seed', None) + if seed is not None: + random.seed(int(seed)) + + def get_initial_design(self, input_vars, output_vars): + samples = [] + for i in range(self.nvalues): + sample = {} + for var_name, (min_val, max_val) in input_vars.items(): + sample[var_name] = random.uniform(min_val, max_val) + samples.append(sample) + return samples + + def get_next_design(self, previous_input_vars, previous_output_values): + return [] # One-shot algorithm + + def get_analysis(self, input_vars, output_values): + valid_results = [(inp, out) for inp, out in zip(input_vars, output_values) + if out is not None] + + if not valid_results: + return {'text': 'No valid results', 'data': {'samples': len(input_vars), 'valid_samples': 0}} + + best_input, best_output = min(valid_results, key=lambda x: x[1]) + worst_input, worst_output = max(valid_results, key=lambda x: x[1]) + valid_outputs = [out for out in output_values if out is not None] + mean_output = sum(valid_outputs) / len(valid_outputs) + + result_text = f"""Random Sampling Results: + Total samples: {len(input_vars)} + Valid samples: {len(valid_results)} + Best output: {best_output:.6g} + Best input: {best_input} + Worst output: {worst_output:.6g} + Mean output: {mean_output:.6g} +""" + + return { + 'text': result_text, + 'data': { + 'samples': len(input_vars), + 'valid_samples': len(valid_results), + 'best_output': best_output, + 'best_input': best_input, + 'worst_output': worst_output, + 'mean_output': mean_output, + } + } diff --git a/examples/dataframe_input.md b/examples/dataframe_input.md new file mode 100644 index 0000000..d4af658 --- /dev/null +++ b/examples/dataframe_input.md @@ -0,0 +1,402 @@ +# DataFrame Input for Non-Factorial Designs + +This document explains how to use pandas DataFrames as input to FZ for non-factorial parametric studies. + +## Overview + +FZ supports two types of parametric study designs: + +1. **Factorial Design (Dict)**: Creates all possible combinations (Cartesian product) +2. **Non-Factorial Design (DataFrame)**: Runs only specified combinations + +## When to Use DataFrames + +Use DataFrame input when: +- Variables have constraints or dependencies +- You need specific combinations, not all combinations +- You're importing a design from another tool (DOE software, optimization) +- You want specialized sampling (Latin Hypercube, Sobol sequences, etc.) +- You have an irregular or optimized design space + +## Basic Example + +### Factorial (Dict) - ALL Combinations + +```python +from fz import fzr + +# Dict creates Cartesian product (factorial design) +input_variables = { + "temp": [100, 200], + "pressure": [1.0, 2.0] +} +# Creates 4 cases: 2 × 2 = 4 +# (100, 1.0), (100, 2.0), (200, 1.0), (200, 2.0) + +results = fzr(input_file, input_variables, model, calculators) +``` + +### Non-Factorial (DataFrame) - SPECIFIC Combinations + +```python +import pandas as pd +from fz import fzr + +# DataFrame: each row is one case +input_variables = pd.DataFrame({ + "temp": [100, 200, 100], + "pressure": [1.0, 1.0, 2.0] +}) +# Creates 3 cases ONLY: +# (100, 1.0), (200, 1.0), (100, 2.0) +# Note: (200, 2.0) is NOT included + +results = fzr(input_file, input_variables, model, calculators) +``` + +## Practical Examples + +### 1. Constraint-Based Design + +When variables have physical or logical constraints: + +```python +import pandas as pd +from fz import fzr + +# Engine RPM and Load have constraints: +# - Low RPM → Low Load (avoid stalling) +# - High RPM → Higher Load possible +input_variables = pd.DataFrame({ + "rpm": [1000, 1500, 2000, 2500, 3000], + "load": [10, 20, 30, 40, 50] # Load increases with RPM +}) + +# This pattern CANNOT be created with a dict +# Dict would create all 25 combinations (5×5), including invalid ones like: +# (1000 RPM, 50 Load) - would stall the engine + +results = fzr("engine_input.txt", input_variables, model, calculators) +``` + +### 2. Latin Hypercube Sampling (LHS) + +For efficient design space exploration with fewer samples: + +```python +import pandas as pd +from scipy.stats import qmc +from fz import fzr + +# Create Latin Hypercube sample in 3 dimensions +sampler = qmc.LatinHypercube(d=3, seed=42) +sample = sampler.random(n=20) # 20 samples instead of full factorial + +# Scale to actual variable ranges +input_variables = pd.DataFrame({ + "temperature": 100 + sample[:, 0] * 200, # [100, 300] + "pressure": 1.0 + sample[:, 1] * 4.0, # [1.0, 5.0] + "flow_rate": 10 + sample[:, 2] * 40 # [10, 50] +}) + +# Compare: Full factorial with [100,150,200,250,300] × [1,2,3,4,5] × [10,20,30,40,50] +# would be 5×5×5 = 125 cases +# LHS: Only 20 cases, but covers the design space well + +results = fzr("simulation.txt", input_variables, model, calculators) +``` + +### 3. Sobol Sequence Sampling + +For low-discrepancy quasi-random sampling: + +```python +import pandas as pd +from scipy.stats import qmc +from fz import fzr + +# Generate Sobol sequence +sampler = qmc.Sobol(d=2, scramble=True, seed=42) +sample = sampler.random(n=32) # Power of 2 recommended for Sobol + +input_variables = pd.DataFrame({ + "x": sample[:, 0] * 100, # [0, 100] + "y": sample[:, 1] * 50 # [0, 50] +}) + +results = fzr("input.txt", input_variables, model, calculators) +``` + +### 4. Imported Design from DOE Software + +Import designs from external tools: + +```python +import pandas as pd +from fz import fzr + +# Design created in R (DoE.base), MODDE, JMP, etc. +input_variables = pd.read_csv("central_composite_design.csv") + +# Or Excel file +input_variables = pd.read_excel("doe_design.xlsx", sheet_name="Design") + +# Or from a previous FZ run +previous_results = pd.read_csv("results.csv") +# Re-run with different settings +input_variables = previous_results[["temp", "pressure", "flow"]] + +results = fzr("input.txt", input_variables, model, calculators) +``` + +### 5. Sensitivity Analysis (One-at-a-Time) + +Test effect of each variable independently: + +```python +import pandas as pd +from fz import fzr + +# Baseline case +baseline = {"temp": 150, "pressure": 2.5, "flow": 30} + +# One-at-a-time variations +oat_cases = [] + +# Vary temperature +for temp in [100, 125, 150, 175, 200]: + oat_cases.append({"temp": temp, "pressure": baseline["pressure"], "flow": baseline["flow"]}) + +# Vary pressure +for pressure in [1.0, 1.5, 2.0, 2.5, 3.0]: + oat_cases.append({"temp": baseline["temp"], "pressure": pressure, "flow": baseline["flow"]}) + +# Vary flow +for flow in [10, 20, 30, 40, 50]: + oat_cases.append({"temp": baseline["temp"], "pressure": baseline["pressure"], "flow": flow}) + +input_variables = pd.DataFrame(oat_cases) +# Creates 13 cases instead of full factorial (5×5×5 = 125) + +results = fzr("input.txt", input_variables, model, calculators) +``` + +### 6. Custom Optimization Samples + +Run calculations at specific points from an optimization algorithm: + +```python +import pandas as pd +import numpy as np +from fz import fzr + +# Points suggested by optimization algorithm (e.g., Bayesian Optimization) +optimization_points = np.array([ + [120, 1.5], + [180, 2.3], + [150, 1.8], + [200, 2.7], + [110, 1.2] +]) + +input_variables = pd.DataFrame( + optimization_points, + columns=["temp", "pressure"] +) + +results = fzr("input.txt", input_variables, model, calculators) + +# Use results to inform next iteration of optimization +best_case = results.loc[results["efficiency"].idxmax()] +``` + +### 7. Time Series / Sequential Cases + +When cases represent sequential states: + +```python +import pandas as pd +import numpy as np +from fz import fzr + +# Simulate a ramping process +time = np.linspace(0, 100, 50) +input_variables = pd.DataFrame({ + "time": time, + "temperature": 100 + 2 * time, # Linear ramp + "pressure": 1.0 + 0.5 * np.sin(time/10) # Oscillating pressure +}) + +results = fzr("input.txt", input_variables, model, calculators) +``` + +## DataFrame vs Dict Comparison + +| Aspect | Dict (Factorial) | DataFrame (Non-Factorial) | +|--------|------------------|---------------------------| +| **Number of cases** | All combinations (product) | Exactly as many rows in DataFrame | +| **Design type** | Full factorial | Custom / irregular | +| **Use case** | Complete exploration | Specific combinations | +| **Example** | `{"x": [1,2], "y": [3,4]}` → 4 cases | `pd.DataFrame({"x":[1,2], "y":[3,4]})` → 2 cases | +| **Constraints** | Cannot handle constraints | Can handle constraints | +| **Sampling** | Grid-based | Any sampling method | + +## Tips and Best Practices + +### 1. Verify Your Design + +Always check your DataFrame before running: + +```python +# Check number of cases +print(f"Number of cases: {len(input_variables)}") + +# Check for duplicates +duplicates = input_variables.duplicated() +if duplicates.any(): + print(f"Warning: {duplicates.sum()} duplicate cases found") + input_variables = input_variables.drop_duplicates() + +# Preview cases +print(input_variables.head()) +``` + +### 2. Combine with Results + +DataFrames make it easy to analyze results: + +```python +import pandas as pd +from fz import fzr + +input_variables = pd.DataFrame({ + "x": [1, 2, 3, 4, 5], + "y": [10, 20, 15, 25, 30] +}) + +results = fzr("input.txt", input_variables, model, calculators) + +# Results include all input variables +print(results[["x", "y", "output"]]) + +# Easy plotting +import matplotlib.pyplot as plt +plt.scatter(results["x"], results["output"], c=results["y"]) +plt.xlabel("X") +plt.ylabel("Output") +plt.colorbar(label="Y") +plt.show() +``` + +### 3. Save and Load Designs + +```python +import pandas as pd + +# Save design for later +input_variables.to_csv("my_design.csv", index=False) + +# Load and reuse +input_variables = pd.read_csv("my_design.csv") +results = fzr("input.txt", input_variables, model, calculators) +``` + +### 4. Append or Filter Cases + +```python +import pandas as pd + +# Start with a base design +base_design = pd.DataFrame({ + "temp": [100, 200, 300], + "pressure": [1.0, 2.0, 3.0] +}) + +# Add edge cases +edge_cases = pd.DataFrame({ + "temp": [50, 350], + "pressure": [0.5, 4.0] +}) + +input_variables = pd.concat([base_design, edge_cases], ignore_index=True) + +# Or filter to specific range +input_variables = input_variables[ + (input_variables["temp"] >= 100) & + (input_variables["temp"] <= 300) +] +``` + +## Common Patterns + +### Design of Experiments (DOE) + +```python +import pandas as pd +from itertools import product + +# 2^k factorial design (k=3 factors, 2 levels) +factors = { + "temp": [100, 200], + "pressure": [1.0, 2.0], + "flow": [10, 20] +} + +# Create all combinations (this is what dict does automatically) +combinations = list(product(*factors.values())) +full_factorial = pd.DataFrame(combinations, columns=factors.keys()) + +# Add center points +center_point = pd.DataFrame({ + "temp": [150], + "pressure": [1.5], + "flow": [15] +}) + +# Central Composite Design = factorial + center + star points +star_points = pd.DataFrame({ + "temp": [50, 250, 150, 150, 150, 150], + "pressure": [1.5, 1.5, 0.5, 2.5, 1.5, 1.5], + "flow": [15, 15, 15, 15, 5, 25] +}) + +ccd_design = pd.concat([full_factorial, center_point, star_points], ignore_index=True) +``` + +### Sparse Grid / Adaptive Sampling + +```python +import pandas as pd +import numpy as np + +# Start with coarse grid +coarse_grid = pd.DataFrame({ + "x": [0, 50, 100], + "y": [0, 50, 100] +}) + +results_coarse = fzr("input.txt", coarse_grid, model, calculators) + +# Identify region of interest (e.g., high output) +threshold = results_coarse["output"].quantile(0.75) +interesting_cases = results_coarse[results_coarse["output"] > threshold] + +# Refine around interesting region +refined_grid = pd.DataFrame({ + "x": np.linspace(40, 60, 10), + "y": np.linspace(40, 60, 10) +}) + +results_refined = fzr("input.txt", refined_grid, model, calculators) +``` + +## Summary + +DataFrames provide maximum flexibility for parametric studies: +- ✅ Support non-factorial designs +- ✅ Handle variable constraints +- ✅ Enable advanced sampling methods +- ✅ Easy integration with DOE tools +- ✅ Seamless result analysis + +Use dicts for simple factorial designs, use DataFrames for everything else! diff --git a/examples/examples.md b/examples/examples.md index 6ff9579..50cb41e 100644 --- a/examples/examples.md +++ b/examples/examples.md @@ -559,3 +559,182 @@ fz.fzi("input_r.txt", }) ``` +# dataframe input variable example + +```python +import pandas as pd +df=pd.DataFrame({ + "T_celsius": [20,25,30], + "V_L": [1,1.5,2], + "n_mol": [1,1,1] +}) +fz.fzr("input.txt", +df,{ + "varprefix": "$", + "formulaprefix": "@", + "delim": "{}", + "commentline": "#", + "output": {"pressure": "grep 'pressure = ' output.txt | awk '{print $3}'"} +}, calculators=["sh://bash ./PerfectGazPressure.sh"]*3, results_dir="results") +``` + +# fzd example + +create design of experiments basic algorithm to estimate a mean with given standard deviation and confidence interval. + +montecarlo_uniform.py: +```bash +echo ' +#title: Estimate mean with given confidence interval range using Monte Carlo +#author: Yann Richet +#type: sampling +#options: batch_sample_size=10;max_iterations=100;confidence=0.9;target_confidence_range=1.0;seed=42 +#require: numpy;scipy;matplotlib;base64 +class MonteCarlo_Uniform: + + options = {} + samples = [] + n_samples = 0 + variables = {} + + def __init__(self, options): + # parse (numeric) options + self.options["batch_sample_size"] = int(options.get("batch_sample_size",10)) + self.options["max_iterations"] = int(options.get("max_iterations",100)) + self.options["confidence"] = float(options.get("confidence",0.9)) + self.options["target_confidence_range"] = float(options.get("target_confidence_range",1.0)) + + import numpy as np + from scipy import stats + np.random.seed(int(options.get("seed",42))) + + def get_initial_design(self, input_variables, output_variables): + for v,bounds in input_variables.items(): + # parse bounds string : [min;max] + bounds = bounds.strip("[]").split(";") + if len(bounds)!=2: + raise Exception(f"Input variable {v} must be defined with min and max values for MonteCarlo_Uniform sampling") + min_val=float(bounds[0]) + max_val=float(bounds[1]) + self.variables[v] = (min_val, max_val) + return self._generate_samples(self.options["batch_sample_size"]) + + def get_next_design(self, X, Y): + # check max iterations + if self.n_samples >= self.options["max_iterations"] * self.options["batch_sample_size"]: + return None + # check confidence interval: compute empirical confidence interval (using kernel density) on Y, compare with target_confidence_range + import numpy as np + from scipy import stats + Y_array = np.array(Y) + kde = stats.gaussian_kde(Y_array) + mean = np.mean(Y_array) + conf_int = stats.t.interval(self.options["confidence"], len(Y_array)-1, loc=mean, scale=stats.sem(Y_array)) + conf_range = conf_int[1] - conf_int[0] + if conf_range <= self.options["target_confidence_range"]: + return None + # else generate new samples + return self._generate_samples(self.options["batch_sample_size"]) + + def _generate_samples(self, n): + import numpy as np + samples = [] + for _ in range(n): + sample = {} + for v,(min_val,max_val) in self.variables.items(): + sample[v] = np.random.uniform(min_val, max_val) + samples.append(sample) + self.n_samples += n + return samples + + def get_analysis(self, X, Y): + html_output = "" + import numpy as np + from scipy import stats + Y_array = np.array(Y) + mean = np.mean(Y_array) + conf_int = stats.t.interval(self.options["confidence"], len(Y_array)-1, loc=mean, scale=stats.sem(Y_array)) + html_output += f"

Estimated mean: {mean}

" + html_output += f"

{self.options['confidence']*100}% confidence interval: [{conf_int[0]}, {conf_int[1]}]

" + # plot histogram + import matplotlib.pyplot as plt + plt.hist(Y_array, bins=20, density=True, alpha=0.6, color='bg') + plt.title("Output Y histogram") + plt.xlabel("Y") + plt.ylabel("Density") + plt.grid() + # base64 in html + import base64 + from io import BytesIO + buffered = BytesIO() + plt.savefig(buffered, format="png") + img_str = base64.b64encode(buffered.getvalue()).decode() + html_output += f"\"Histogram\"/" + return html_output +' > ./examples/algorithms/montecarlo_uniform.py +``` + +```python +analysis = fz.fzd( + input_path='input.txt', + input_variables={ + "n_mol": "[0;10]", + "T_celsius": "[0;100]", + "V_L": "[1;5]" + }, + model={ + "varprefix": "$", + "formulaprefix": "@", + "delim": "{}", + "commentline": "#", + "output": {"pressure": "grep 'pressure = ' output.txt | awk '{print $3}'"} + }, + calculators=["sh://bash ./PerfectGazPressure.sh"]*10, + output_expression="pressure+1", + algorithm="./examples/algorithms/montecarlo_uniform.py", + algorithm_options={ + "batch_sample_size": 20, + "max_iterations": 50, + "confidence": 0.90, + "target_confidence_range": 1000000, + "seed": 123 + }, + analysis_dir="fzd_analysis" +) + +from IPython.core.display import display, HTML +display(HTML(analysis)) +``` + +with R algorithm: +```python +analysis = fz.fzd( + input_path='input.txt', + input_variables={ + "n_mol": "[0;10]", + "T_celsius": "[0;100]", + "V_L": "[1;5]" + }, + model={ + "varprefix": "$", + "formulaprefix": "@", + "delim": "{}", + "commentline": "#", + "output": {"pressure": "grep 'pressure = ' output.txt | awk '{print $3}'"} + }, + calculators=["sh://bash ./PerfectGazPressure.sh"]*10, + output_expression="pressure+1", + algorithm="./examples/algorithms/montecarlo_uniform.R", + algorithm_options={ + "batch_sample_size": 20, + "max_iterations": 50, + "confidence": 0.90, + "target_confidence_range": 1000000, + "seed": 123 + }, + analysis_dir="fzd_analysis" +) + +from IPython.core.display import display, HTML +display(HTML(analysis)) +``` diff --git a/examples/fz_modelica_projectile.ipynb b/examples/fz_modelica_projectile.ipynb new file mode 100644 index 0000000..ec6d247 --- /dev/null +++ b/examples/fz_modelica_projectile.ipynb @@ -0,0 +1,1697 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# FZ Framework with Modelica - Projectile Motion Demo\n", + "\n", + "This notebook demonstrates the **FZ** parametric scientific computing framework integrated with **OpenModelica** for rigorous differential equation solving.\n", + "\n", + "## What We'll Cover\n", + "\n", + "1. **Installation** - Set up FZ and verify OpenModelica\n", + "2. **Modelica Model** - Use differential equations for projectile motion\n", + "3. **Basic Calculations** - Run parametric simulations with OpenModelica\n", + "4. **Design of Experiments** - Systematic parameter space exploration\n", + "5. **Optimization** - Find optimal launch parameters using Gradient Descent\n", + "6. **Root Finding** - Find angle for specific target range using Brent's method\n", + "\n", + "## About This Notebook\n", + "\n", + "This notebook demonstrates FZ's integration with **OpenModelica**, using true differential equations for physics simulation:\n", + "\n", + "- **Physics**: Differential equations solved by OpenModelica\n", + "- **Solver**: Professional ODE solvers (DASSL, Radau, etc.)\n", + "- **Setup**: Requires OpenModelica installation\n", + "- **Speed**: ~1-2s per simulation (includes Modelica compilation)\n", + "- **Best for**: Rigorous modeling, complex multi-physics systems\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Installation and Setup\n", + "\n", + "This cell will set up everything you need:\n", + "- Python dependencies (FZ framework, pandas, numpy, scipy, matplotlib, plotly)\n", + "- fz-modelica plugin (model configuration and calculator)\n", + "- ProjectileMotion.mo template (downloaded from fz-modelica repository and enhanced)\n", + "\n", + "### Requirements\n", + "\n", + "**System requirements:**\n", + "- **OpenModelica** - Must be installed on your system\n", + " - Ubuntu/Debian: `sudo apt-get install openmodelica`\n", + " - macOS: `brew install openmodelica`\n", + " - Windows: Download from https://openmodelica.org/download/\n", + "- **Python 3.7+**\n", + "\n", + "**This cell will install automatically:**\n", + "- FZ framework from GitHub\n", + "- fz-modelica plugin (model config and calculator) from https://github.com/Funz/fz-modelica\n", + "- Python packages: pandas, numpy, scipy, matplotlib, plotly\n", + "\n", + "**The next cells will:**\n", + "- Download base ProjectileMotion.mo model from fz-modelica repository\n", + "- Enhance it with air resistance for realistic physics\n", + "- Compute physics outputs (max_height, range, etc.) from trajectory data\n", + "\n", + "Let's set up everything..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Install OpenModelica (Google Colab)\n", + "\n", + "**Run this cell if you're on Google Colab** to install OpenModelica system package.\n", + "\n", + "On other platforms, install OpenModelica manually:\n", + "- Ubuntu/Debian: `sudo apt-get install openmodelica`\n", + "- macOS: `brew install openmodelica`\n", + "- Windows: Download from https://openmodelica.org/download/" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import subprocess\n", + "import shutil\n", + "\n", + "# Detect if running on Google Colab\n", + "try:\n", + " import google.colab\n", + " IN_COLAB = True\n", + "except ImportError:\n", + " IN_COLAB = False\n", + "\n", + "if IN_COLAB:\n", + " print(\"=\" * 60)\n", + " print(\"INSTALLING OPENMODELICA ON GOOGLE COLAB\")\n", + " print(\"=\" * 60)\n", + " print(\"\\nThis will install OpenModelica system package...\")\n", + " print(\"(This may take 2-5 minutes)\\n\")\n", + " \n", + " # Update package list\n", + " print(\"Step 1/3: Updating package list...\")\n", + " subprocess.run([\"apt-get\", \"update\", \"-qq\"], check=True)\n", + " print(\"✓ Package list updated\\n\")\n", + " \n", + " # Install OpenModelica\n", + " print(\"Step 2/3: Installing OpenModelica...\")\n", + " subprocess.run([\"apt-get\", \"install\", \"-y\", \"-qq\", \"openmodelica\"], \n", + " check=True, stdout=subprocess.DEVNULL)\n", + " print(\"✓ OpenModelica installed\\n\")\n", + " \n", + " # Verify installation\n", + " print(\"Step 3/3: Verifying installation...\")\n", + " omc_path = shutil.which(\"omc\")\n", + " if omc_path:\n", + " result = subprocess.run([\"omc\", \"--version\"], \n", + " capture_output=True, text=True, timeout=5)\n", + " version = result.stdout.strip()\n", + " print(f\"✓ OpenModelica found: {omc_path}\")\n", + " print(f\"✓ Version: {version}\")\n", + " else:\n", + " print(\"⚠ OpenModelica installation may have failed\")\n", + " \n", + " print(\"\\n\" + \"=\" * 60)\n", + " print(\"OPENMODELICA INSTALLATION COMPLETE\")\n", + " print(\"=\" * 60)\n", + "else:\n", + " print(\"Not running on Google Colab - skipping automatic installation\")\n", + " print(\"Please install OpenModelica manually if not already installed:\")\n", + " print(\" - Ubuntu/Debian: sudo apt-get install openmodelica\")\n", + " print(\" - macOS: brew install openmodelica\")\n", + " print(\" - Windows: https://openmodelica.org/download/\")" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "============================================================\n", + "FZ MODELICA SETUP\n", + "============================================================\n", + "✓ Created directory structure in: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp\n", + "\n", + "Changed working directory to: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp\n", + "\n", + "Step 1/2: Installing FZ framework and dependencies...\n", + " (This may take 1-2 minutes)\n", + "\n", + "✓ FZ and Python dependencies installed\n", + "\n", + "Step 2/2: Installing fz-modelica plugin from GitHub...\n", + " ✓ Installed model: Modelica\n", + " ✓ Model path: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/.fz/models/Modelica.json\n", + " ✓ Installed 1 calculator(s)\n", + " - localhost.json\n", + "\n", + "Step 3/3: Checking OpenModelica installation...\n", + " ✓ OpenModelica found: /usr/bin/omc\n", + " ✓ Version: OpenModelica 1.25.4\n", + "\n", + "============================================================\n", + "SETUP COMPLETE\n", + "============================================================\n", + "Working directory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp\n", + "fz-modelica model: installed in .fz/models/\n", + "fz-modelica calculator: installed in .fz/calculators/\n", + "OpenModelica: ✓ Available\n", + "============================================================\n", + "\n", + "✓ All resources installed and ready to use!\n" + ] + } + ], + "source": [ + "#!/usr/bin/env python3\n", + "\"\"\"\n", + "Complete setup: Creates tmp/ directory and installs fz plugins\n", + "\"\"\"\n", + "import os\n", + "import sys\n", + "import subprocess\n", + "import shutil\n", + "\n", + "# Create tmp directory structure\n", + "tmp_dir = os.path.abspath('tmp')\n", + "\n", + "print(\"=\" * 60)\n", + "print(\"FZ MODELICA SETUP\")\n", + "print(\"=\" * 60)\n", + "\n", + "# Clean and create tmp directory\n", + "if os.path.exists(tmp_dir):\n", + " print(f\"Cleaning existing tmp directory: {tmp_dir}\")\n", + " shutil.rmtree(tmp_dir)\n", + "\n", + "os.makedirs(tmp_dir, exist_ok=True)\n", + "print(f\"✓ Created directory structure in: {tmp_dir}\\n\")\n", + "\n", + "os.chdir(tmp_dir)\n", + "print(f\"Changed working directory to: {tmp_dir}\\n\")\n", + "\n", + "# Step 1: Install FZ and dependencies\n", + "print(\"Step 1/2: Installing FZ framework and dependencies...\")\n", + "print(\" (This may take 1-2 minutes)\\n\")\n", + "\n", + "# Install FZ from GitHub (quietly)\n", + "subprocess.run([sys.executable, '-m', 'pip', 'install', '-q',\n", + " 'git+https://github.com/Funz/fz.git'],\n", + " check=True)\n", + "\n", + "# Install dependencies (quietly)\n", + "subprocess.run([sys.executable, '-m', 'pip', 'install', '-q',\n", + " 'pandas', 'numpy', 'scipy', 'matplotlib', 'plotly'],\n", + " check=True)\n", + "\n", + "print(\"✓ FZ and Python dependencies installed\\n\")\n", + "\n", + "# Step 2: Install fz-modelica plugin\n", + "print(\"Step 2/2: Installing fz-modelica plugin from GitHub...\")\n", + "\n", + "import fz\n", + "\n", + "try:\n", + " # Install fz-modelica model and calculator\n", + " result = fz.install_model('modelica', global_install=False)\n", + " print(f\" ✓ Installed model: {result['model_name']}\")\n", + " print(f\" ✓ Model path: {result['install_path']}\")\n", + " if result.get('calculators'):\n", + " print(f\" ✓ Installed {len(result['calculators'])} calculator(s)\")\n", + " for calc in result['calculators']:\n", + " print(f\" - {os.path.basename(calc)}\")\n", + "except Exception as e:\n", + " print(f\" ⚠ Error installing fz-modelica: {e}\")\n", + " print(f\" Will try to use model name 'modelica' directly\")\n", + "\n", + "print()\n", + "\n", + "# Step 3: Verify OpenModelica installation\n", + "print(\"Step 3/3: Checking OpenModelica installation...\")\n", + "omc_path = shutil.which(\"omc\")\n", + "\n", + "if omc_path:\n", + " try:\n", + " result = subprocess.run([\"omc\", \"--version\"], \n", + " capture_output=True, text=True, timeout=5)\n", + " version = result.stdout.strip()\n", + " print(f\" ✓ OpenModelica found: {omc_path}\")\n", + " print(f\" ✓ Version: {version}\")\n", + " openmodelica_available = True\n", + " except Exception as e:\n", + " print(f\" ⚠ OpenModelica found but error checking version: {e}\")\n", + " openmodelica_available = False\n", + "else:\n", + " print(\" ❌ OpenModelica (omc) not found in PATH\")\n", + " print(\"\\n This notebook requires OpenModelica. Install it:\")\n", + " print(\" Ubuntu/Debian: sudo apt-get install openmodelica\")\n", + " print(\" macOS: brew install openmodelica\")\n", + " print(\" Windows: https://openmodelica.org/download/\")\n", + " openmodelica_available = False\n", + "\n", + "print()\n", + "print(\"=\" * 60)\n", + "print(\"SETUP COMPLETE\")\n", + "print(\"=\" * 60)\n", + "print(f\"Working directory: {tmp_dir}\")\n", + "print(f\"fz-modelica model: installed in .fz/models/\")\n", + "print(f\"fz-modelica calculator: installed in .fz/calculators/\")\n", + "print(f\"OpenModelica: {'✓ Available' if openmodelica_available else '✗ Not available'}\")\n", + "print(\"=\" * 60)\n", + "\n", + "print(\"\\n✓ All resources installed and ready to use!\")" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "FZ version: 0.9.0\n", + "Working directory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp\n", + "OpenModelica: ✓ Available\n", + "\n", + "✓ Using fz-modelica plugin (model name: 'Modelica')\n", + "✓ All resources ready\n" + ] + } + ], + "source": [ + "# Import FZ and other libraries\n", + "import fz\n", + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from IPython.display import HTML, display\n", + "\n", + "print(f\"FZ version: {fz.__version__}\")\n", + "print(f\"Working directory: {tmp_dir}\")\n", + "print(f\"OpenModelica: {'✓ Available' if openmodelica_available else '✗ Not available'}\")\n", + "\n", + "# Model is installed and will be used by name\n", + "print(f\"\\n✓ Using fz-modelica plugin (model name: 'Modelica')\")\n", + "print(f\"✓ All resources ready\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## 2. Modelica Projectile Motion Model\n", + "\n", + "We'll use a **Modelica model** that solves differential equations for projectile motion with air resistance.\n", + "\n", + "### Creating the Enhanced FZ Template\n", + "\n", + "The next cell will:\n", + "1. Download the base `ProjectileMotion.mo` from the **fz-modelica** GitHub repository\n", + "2. Enhance it by adding air resistance parameters (`k` and `m`)\n", + "3. Add **dynamic termination** (stops when projectile lands)\n", + "4. Replace parameter values with `${var}` placeholders for FZ\n", + "5. Save the enhanced template to `tmp/ProjectileMotion.mo`\n", + "\n", + "This creates a template that FZ can compile with different parameter values.\n", + "\n", + "### Model Description\n", + "\n", + "The enhanced Modelica model implements:\n", + "\n", + "**State Variables:**\n", + "- `x, y` - Position coordinates [m]\n", + "- `vx, vy` - Velocity components [m/s]\n", + "\n", + "**Differential Equations:**\n", + "```modelica\n", + "der(x) = vx\n", + "der(y) = vy\n", + "m * der(vx) = -k * vx * v\n", + "m * der(vy) = -k * vy * v - m * g\n", + "```\n", + "\n", + "Where drag force is: `F_drag = -k * v * |v|` (quadratic air resistance)\n", + "\n", + "**Dynamic Termination:**\n", + "```modelica\n", + "when y <= 0.0 and pre(launched) then\n", + " terminate(\"Projectile has landed\");\n", + "end when;\n", + "```\n", + "\n", + "The simulation automatically stops when the projectile lands, avoiding wasted computation!\n", + "\n", + "**Parameters (FZ variables):**\n", + "- `v0` - Initial velocity [m/s] → `${v0}`\n", + "- `angle` - Launch angle [degrees] → `${angle}`\n", + "- `k` - Air resistance coefficient [1/m] → `${k}` (added)\n", + "- `m` - Projectile mass [kg] → `${m}` (added)\n", + "\n", + "**Outputs** (computed by post-processing):\n", + "- Maximum height, range, flight time\n", + "- Final velocity, impact angle\n", + "- Energy loss to air resistance\n", + "\n", + "**Note:** The base model from fz-modelica has no air resistance and uses fixed stopTime. We enhance it with realistic physics and dynamic termination." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "✓ Created enhanced FZ template at: ProjectileMotion.mo\n", + "✓ Enhanced base model with:\n", + " - Air resistance (k parameter)\n", + " - Mass parameter (m)\n", + " - Quadratic drag forces\n", + " - Dynamic termination (stops when projectile lands)\n", + "\n", + "Template preview (first 700 chars):\n", + "============================================================\n", + "model ProjectileMotion \"Projectile motion with air resistance\"\n", + "\n", + " // Parameters (can be set from FZ)\n", + " parameter Real v0 = ${v0} \"Initial velocity [m/s]\";\n", + " parameter Real angle_deg = ${angle} \"Launch angle [degrees]\";\n", + " parameter Real k = ${k} \"Air resistance coefficient [1/m]\";\n", + " parameter Real m = ${m} \"Projectile mass [kg]\";\n", + " parameter Real g = 9.81 \"Gravitational acceleration [m/s^2]\";\n", + "\n", + " // Convert angle to radians\n", + " parameter Real angle = angle_deg * 3.14159265359 / 180.0 \"Launch angle [rad]\";\n", + "\n", + " // Initial velocity components\n", + " parameter Real vx0 = v0 * cos(angle) \"Initial horizontal velocity [m/s]\";\n", + " parameter Real vy0 = v0 * sin(angle) \"Initial vertical velocity [m/s]\";\n", + "\n", + " // Sta\n", + "...\n", + "\n", + "✓ Parameters with FZ variables:\n", + " - v0 = ${v0}\n", + " - angle_deg = ${angle}\n", + " - k = ${k}\n", + " - m = ${m}\n", + "\n", + "✓ Dynamic termination condition:\n", + " - Stops automatically when y <= 0 after launch\n", + " - No more wasted computation with fixed stopTime!\n" + ] + } + ], + "source": [ + "# Enhance the model with air resistance and dynamic termination\n", + "# The base model has no air resistance - we'll add it\n", + "# Also add dynamic termination when projectile lands (y <= 0 after launch)\n", + "enhanced_model = '''model ProjectileMotion \"Projectile motion with air resistance\"\n", + "\n", + " // Parameters (can be set from FZ)\n", + " parameter Real v0 = ${v0} \"Initial velocity [m/s]\";\n", + " parameter Real angle_deg = ${angle} \"Launch angle [degrees]\";\n", + " parameter Real k = ${k} \"Air resistance coefficient [1/m]\";\n", + " parameter Real m = ${m} \"Projectile mass [kg]\";\n", + " parameter Real g = 9.81 \"Gravitational acceleration [m/s^2]\";\n", + "\n", + " // Convert angle to radians\n", + " parameter Real angle = angle_deg * 3.14159265359 / 180.0 \"Launch angle [rad]\";\n", + "\n", + " // Initial velocity components\n", + " parameter Real vx0 = v0 * cos(angle) \"Initial horizontal velocity [m/s]\";\n", + " parameter Real vy0 = v0 * sin(angle) \"Initial vertical velocity [m/s]\";\n", + "\n", + " // State variables\n", + " Real x(start=0, fixed=true) \"Horizontal position [m]\";\n", + " Real y(start=0, fixed=true) \"Vertical position [m]\";\n", + " Real vx(start=vx0, fixed=true) \"Horizontal velocity [m/s]\";\n", + " Real vy(start=vy0, fixed=true) \"Vertical velocity [m/s]\";\n", + "\n", + " // Auxiliary variables\n", + " Real v \"Total velocity magnitude [m/s]\";\n", + " Real drag_x \"Horizontal drag force [N]\";\n", + " Real drag_y \"Vertical drag force [N]\";\n", + " \n", + " // Flag to detect when projectile has launched (y > 0.1m)\n", + " Boolean launched(start=false, fixed=true);\n", + "\n", + "equation\n", + " // Velocity magnitude\n", + " v = sqrt(vx^2 + vy^2);\n", + "\n", + " // Drag forces (proportional to velocity squared)\n", + " drag_x = -k * vx * v;\n", + " drag_y = -k * vy * v;\n", + "\n", + " // Differential equations (Newton's second law: F = ma)\n", + " der(x) = vx;\n", + " der(y) = vy;\n", + " m * der(vx) = drag_x;\n", + " m * der(vy) = drag_y - m * g;\n", + " \n", + " // Track if projectile has launched\n", + " launched = y > 0.1;\n", + "\n", + "algorithm\n", + " // Terminate when projectile lands (y <= 0) after launch\n", + " when y <= 0.0 and pre(launched) then\n", + " terminate(\"Projectile has landed\");\n", + " end when;\n", + "\n", + " annotation(\n", + " experiment(StartTime=0, StopTime=100, Tolerance=1e-6, Interval=0.01),\n", + " Documentation(info=\"\n", + "

Projectile Motion with Air Resistance

\n", + "

Enhanced from base fz-modelica model with air resistance and dynamic termination.

\n", + "

The drag force is proportional to velocity squared: F_drag = -k * v * |v|

\n", + "

The simulation automatically terminates when the projectile lands (y <= 0 after launch).

\n", + "
Parameters:
\n", + "
    \n", + "
  • v0: Initial velocity [m/s]
  • \n", + "
  • angle_deg: Launch angle [degrees]
  • \n", + "
  • k: Air resistance coefficient [1/m]
  • \n", + "
  • m: Projectile mass [kg]
  • \n", + "
\n", + "
State Variables:
\n", + "
    \n", + "
  • x, y: Position coordinates [m]
  • \n", + "
  • vx, vy: Velocity components [m/s]
  • \n", + "
\n", + "

Output variables (max_height, range, flight_time, final_velocity, impact_angle, energy_loss) are computed by post-processing the trajectory data.

\n", + "\")\n", + " );\n", + "\n", + "end ProjectileMotion;\n", + "'''\n", + "\n", + "# Save enhanced template to tmp directory\n", + "with open('ProjectileMotion.mo', 'w') as f:\n", + " f.write(enhanced_model)\n", + "\n", + "print(f\"✓ Created enhanced FZ template at: ProjectileMotion.mo\")\n", + "print(\"✓ Enhanced base model with:\")\n", + "print(\" - Air resistance (k parameter)\")\n", + "print(\" - Mass parameter (m)\")\n", + "print(\" - Quadratic drag forces\")\n", + "print(\" - Dynamic termination (stops when projectile lands)\")\n", + "print(\"\\nTemplate preview (first 700 chars):\")\n", + "print(\"=\" * 60)\n", + "print(enhanced_model[:700] + \"\\n...\")\n", + "\n", + "print(\"\\n✓ Parameters with FZ variables:\")\n", + "print(\" - v0 = ${v0}\")\n", + "print(\" - angle_deg = ${angle}\")\n", + "print(\" - k = ${k}\")\n", + "print(\" - m = ${m}\")\n", + "print(\"\\n✓ Dynamic termination condition:\")\n", + "print(\" - Stops automatically when y <= 0 after launch\")\n", + "print(\" - No more wasted computation with fixed stopTime!\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Detected input variables (from Modelica template):\n", + "{\n", + " \"angle\": null,\n", + " \"k\": null,\n", + " \"m\": null,\n", + " \"v0\": null\n", + "}\n" + ] + } + ], + "source": [ + "# Parse the Modelica template to identify variables\n", + "import fz\n", + "variables = fz.fzi(\n", + " input_path='ProjectileMotion.mo',\n", + " model='Modelica'\n", + ")\n", + "\n", + "print(\"Detected input variables (from Modelica template):\")\n", + "import json\n", + "print(json.dumps(variables, indent=2))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "✓ Using fz-modelica calculator (installed in .fz/calculators/)\n", + "\n", + "The fz-modelica calculator will:\n", + " 1. Check for OpenModelica installation\n", + " 2. Run omc to simulate the Modelica model\n", + " 3. Extract trajectory data from CSV file\n", + " 4. Return trajectory arrays directly in the DataFrame\n", + "\n", + "✓ Defined compute_projectile_outputs() function\n", + " This function now uses trajectory data directly from fzr results\n", + " No CSV file parsing needed - more efficient!\n" + ] + } + ], + "source": [ + "# The fz-modelica plugin provides the calculator automatically\n", + "print(f\"✓ Using fz-modelica calculator (installed in .fz/calculators/)\")\n", + "print(\"\\nThe fz-modelica calculator will:\")\n", + "print(\" 1. Check for OpenModelica installation\")\n", + "print(\" 2. Run omc to simulate the Modelica model\")\n", + "print(\" 3. Extract trajectory data from CSV file\")\n", + "print(\" 4. Return trajectory arrays directly in the DataFrame\")\n", + "\n", + "# Define function to compute physics outputs from fzr results\n", + "def compute_projectile_outputs(row):\n", + " \"\"\"\n", + " Compute physics outputs from Modelica trajectory data in fzr results.\n", + " \n", + " The fz-modelica calculator returns trajectory data as arrays in columns like:\n", + " - res_ProjectileMotion_x: horizontal position [m]\n", + " - res_ProjectileMotion_y: vertical position [m]\n", + " - res_ProjectileMotion_vx: horizontal velocity [m/s]\n", + " - res_ProjectileMotion_vy: vertical velocity [m/s]\n", + " - res_ProjectileMotion_time: simulation time [s]\n", + " \n", + " Args:\n", + " row: DataFrame row with trajectory columns from fzr results\n", + " \n", + " Returns:\n", + " dict: Computed physics outputs\n", + " \"\"\"\n", + " import numpy as np\n", + " \n", + " # Check if trajectory data is available\n", + " if 'res_ProjectileMotion_y' not in row or row['res_ProjectileMotion_y'] is None:\n", + " return {\n", + " 'max_height': None,\n", + " 'range': None,\n", + " 'flight_time': None,\n", + " 'final_velocity': None,\n", + " 'impact_angle': None,\n", + " 'energy_loss_percent': None,\n", + " 'neg_range': None,\n", + " 'target_error': None\n", + " }\n", + " \n", + " # Extract trajectory arrays from row\n", + " x = np.array(row['res_ProjectileMotion_x'])\n", + " y = np.array(row['res_ProjectileMotion_y'])\n", + " vx = np.array(row['res_ProjectileMotion_vx'])\n", + " vy = np.array(row['res_ProjectileMotion_vy'])\n", + " time = np.array(row['res_ProjectileMotion_time'])\n", + " \n", + " # Compute outputs\n", + " outputs = {}\n", + " \n", + " # Maximum height\n", + " outputs['max_height'] = y.max()\n", + " \n", + " # Find landing point (where y crosses 0 second time)\n", + " below_ground_indices = np.where(y <= 0)[0]\n", + " if len(below_ground_indices) > 1:\n", + " landing_idx = below_ground_indices[1]\n", + " else:\n", + " landing_idx = len(y) - 1\n", + " \n", + " # Range (horizontal distance at landing)\n", + " outputs['range'] = x[landing_idx]\n", + " \n", + " # Flight time\n", + " outputs['flight_time'] = time[landing_idx]\n", + " \n", + " # Final velocity magnitude\n", + " vx_final = vx[landing_idx]\n", + " vy_final = vy[landing_idx]\n", + " outputs['final_velocity'] = np.sqrt(vx_final**2 + vy_final**2)\n", + " \n", + " # Impact angle (degrees)\n", + " outputs['impact_angle'] = abs(np.degrees(np.arctan2(vy_final, vx_final)))\n", + " \n", + " # Energy loss percentage\n", + " v0_squared = vx[0]**2 + vy[0]**2\n", + " vf_squared = vx_final**2 + vy_final**2\n", + " outputs['energy_loss_percent'] = 100 * (1 - vf_squared / v0_squared)\n", + " \n", + " # Negative range (for optimization - minimize negative = maximize positive)\n", + " outputs['neg_range'] = -outputs['range']\n", + " \n", + " # Target error (for root finding - distance from 150m target)\n", + " outputs['target_error'] = abs(outputs['range'] - 150.0)\n", + " \n", + " return outputs\n", + "\n", + "print(\"\\n✓ Defined compute_projectile_outputs() function\")\n", + "print(\" This function now uses trajectory data directly from fzr results\")\n", + "print(\" No CSV file parsing needed - more efficient!\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running Modelica simulation (may take 10-30 seconds for first run)...\n", + "\n", + "[■]\n", + "Computing physics outputs from trajectory data...\n", + "\n", + "Modelica Simulation Results:\n", + "============================================================\n", + "max_height : 34.7367\n", + "range : 97.4732\n", + "flight_time : 5.2800\n", + "final_velocity : 23.7393\n", + "impact_angle : 64.6746\n", + "energy_loss_percent : 77.4579\n", + "neg_range : -97.4732\n", + "target_error : 52.5268\n", + "\n", + "✓ OpenModelica simulation completed!\n" + ] + } + ], + "source": [ + "# Define a single set of parameters\n", + "params_single = {\n", + " 'v0': 50.0,\n", + " 'angle': 45.0,\n", + " 'k': '0.01',\n", + " 'm': '1.0'\n", + "}\n", + "\n", + "# Run the calculation using OpenModelica via fz-modelica plugin\n", + "print(\"Running Modelica simulation (may take 10-30 seconds for first run)...\\n\")\n", + "\n", + "result_single = fz.fzr(\n", + " input_path='ProjectileMotion.mo',\n", + " input_variables=params_single,\n", + " model='Modelica',\n", + " calculators='localhost'\n", + ")\n", + "\n", + "# Convert to DataFrame if needed\n", + "if not hasattr(result_single, 'iloc'):\n", + " result_single = pd.DataFrame(result_single)\n", + "\n", + "# Enrich with computed physics outputs\n", + "print(\"Computing physics outputs from trajectory data...\")\n", + "physics_outputs = result_single.apply(compute_projectile_outputs, axis=1, result_type='expand')\n", + "result_single = pd.concat([result_single, physics_outputs], axis=1)\n", + "\n", + "print(\"\\nModelica Simulation Results:\")\n", + "print(\"=\" * 60)\n", + "\n", + "# Display computed outputs\n", + "output_cols = ['max_height', 'range', 'flight_time', 'final_velocity', \n", + " 'impact_angle', 'energy_loss_percent', 'neg_range', 'target_error']\n", + "for col in output_cols:\n", + " if col in result_single.columns and result_single[col].iloc[0] is not None:\n", + " value = float(result_single[col].iloc[0])\n", + " print(f\"{col:20s}: {value:10.4f}\")\n", + "\n", + "print(\"\\n✓ OpenModelica simulation completed!\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running 42 Modelica simulations (this will take a few minutes)...\n", + "\n", + "[■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■] Total time: 19s\n", + "\n", + "Completed 42 Modelica simulations\n", + "\n", + "Computing physics outputs from trajectory data...\n", + " v0 angle max_height range flight_time\n", + "10.0 20.0 0.583086 6.278069 0.69\n", + "10.0 30.0 1.234990 8.366635 1.01\n", + "10.0 40.0 2.026531 9.376247 1.29\n", + "10.0 50.0 2.863559 9.292611 1.53\n", + "10.0 60.0 3.648112 8.167429 1.73\n", + "10.0 70.0 4.288291 6.084388 1.88\n", + "10.0 80.0 4.707434 3.233619 1.96\n", + "20.0 20.0 2.193538 22.406571 1.34\n", + "20.0 30.0 4.542080 28.619585 1.93\n", + "20.0 40.0 7.326491 31.333505 2.45\n", + "20.0 50.0 10.228201 30.614049 2.89\n", + "20.0 60.0 12.931085 26.712644 3.25\n", + "20.0 70.0 15.137825 19.908221 3.52\n", + "20.0 80.0 16.590243 10.685712 3.68\n", + "30.0 20.0 4.516344 43.056100 1.92\n", + "30.0 30.0 9.096362 52.695867 2.72\n", + "30.0 40.0 14.383297 56.220834 3.42\n", + "30.0 50.0 19.804458 54.123627 4.01\n", + "30.0 60.0 24.814932 46.965268 4.50\n", + "30.0 70.0 28.900927 34.978612 4.86\n", + "30.0 80.0 31.599223 18.873822 5.08\n", + "40.0 20.0 7.233539 64.229306 2.42\n", + "40.0 30.0 14.181963 75.904224 3.38\n", + "40.0 40.0 22.013506 79.237299 4.21\n", + "40.0 50.0 29.928350 75.420053 4.92\n", + "40.0 60.0 37.187510 64.978892 5.50\n", + "40.0 70.0 43.090598 48.317912 5.93\n", + "40.0 80.0 46.991547 26.144837 6.20\n", + "50.0 20.0 10.112590 84.168698 2.85\n", + "50.0 30.0 19.358857 96.720975 3.93\n", + "50.0 40.0 29.576259 99.423345 4.87\n", + "50.0 50.0 39.778770 93.592481 5.66\n", + "50.0 60.0 49.070164 80.144923 6.31\n", + "50.0 70.0 56.599548 59.480279 6.80\n", + "50.0 80.0 61.570301 32.210134 7.11\n", + "60.0 20.0 13.009556 102.300404 3.22\n", + "60.0 30.0 24.401422 115.116131 4.40\n", + "60.0 40.0 36.789712 116.667541 5.41\n", + "60.0 50.0 49.037834 108.952003 6.27\n", + "60.0 60.0 60.123218 92.837216 6.98\n", + "60.0 70.0 69.074267 68.700905 7.51\n", + "60.0 80.0 74.973569 37.187433 7.85\n" + ] + } + ], + "source": [ + "# Define multiple parameter combinations\n", + "params_multi = {\n", + " 'v0': [10.0, 20.0, 30.0, 40.0, 50.0, 60.0],\n", + " 'angle': [20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0],\n", + " 'k': '0.01', # Fixed\n", + " 'm': '1.0' # Fixed\n", + "}\n", + "\n", + "# Run all combinations (3 × 3 = 9 cases)\n", + "print(\"Running 42 Modelica simulations (this will take a few minutes)...\\n\")\n", + "\n", + "results_multi = fz.fzr(\n", + " input_path='ProjectileMotion.mo',\n", + " input_variables=params_multi,\n", + " model='Modelica',\n", + " calculators=['localhost']*6 # Use 5 parallel calculators\n", + ")\n", + "\n", + "print(f\"\\nCompleted {len(results_multi)} Modelica simulations\\n\")\n", + "\n", + "# Convert to DataFrame for analysis (if not already)\n", + "if hasattr(results_multi, 'iloc'):\n", + " df_multi = results_multi\n", + "else:\n", + " df_multi = pd.DataFrame(results_multi)\n", + "\n", + "# Enrich with computed physics outputs\n", + "print(\"Computing physics outputs from trajectory data...\")\n", + "physics_outputs = df_multi.apply(compute_projectile_outputs, axis=1, result_type='expand')\n", + "df_multi = pd.concat([df_multi, physics_outputs], axis=1)\n", + "\n", + "#df_multi = df_multi.astype(float)\n", + "print(df_multi[['v0', 'angle', 'max_height', 'range', 'flight_time']].to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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j7ywsDAA5jOCPXv25MoNBgMSEhLQqlWrcu23tkTeIyIikJOT4/CSwc5QKBQYOHAgfvzxR6xatQpbtmxBdHQ0goKCbNbj8/no3bs3evfujVWrVmH58uVYuHAhDhw4UO5jA+arC167dg0bNmzAuHHjuHJHw789PT0dTrG0nKEsK8sw54sXL5Zre2cwxrBp0yb07NnTbqodALz99tuIjY21C0qVxvp9b30GKT09vdSOjiVBqEqlKtdrFxkZCQC4detWqeuOGTMGkydPhoeHB5588kmH6/j6+kIulyMuLs5u2dWrV8Hn8xESEgLA/LwtZ/CsFd3W8hz9/Pwq9P603l9p75OffvoJDRo0wC+//GLz+bF48WKH61vaz3KWnxBCKpPlO04kEpX7c7CsfawWLVqgTZs2iI2NRb169XDnzh188skn5XwG9nXZu3cvsrOzbUaMXL161aaugHN9FoVCgVGjRmHUqFHQ6XQYNmwYli1bhgULFthN3bIorm9oOXZcXJzd6JK4uDibujkSGxsLkUiE77//3i5wcuTIEXz88ce4c+eO3UifyrZw4UJ8+eWXeOONN7Br1y4AZetnisViDBo0CIMGDYLJZMKMGTPw+eef480337QLgFpr2bIlWrZsiTfeeAPHjh1Dly5dsG7dOrzzzjsAim/3n376CePHj8eHH37IlWk0GmRmZpbhWRey9B0uXrxYbH2pD1V21IcilFOKPPLat28Pb29vfPnllzAYDFx5bGxshabjKRSKCk0dqy4jR47E8ePH8ddff9kty8zMtGmT4owaNQr379/HV199hfPnz2PUqFE2yzMyMuy2sZwd0mq15at4AUvny/osFWPM5hLCFhEREbh69arN5XvPnz9f7qsA+vr6olu3bvjmm29w584dm2WVNWru6NGjSEhIwMSJEzF8+HC726hRo3DgwAHcv3+/TPvt3bs3hEIh1q5da1P+f//3f6Vu265dO0REROCDDz5ATk6O3XJHl0e2FhwcjJCQEJw+fbrUYw0fPhyLFy/GZ5995vAqg4D5PdC3b19s27bN5jLOKSkp2LRpE7p27coNFX/yySfxzz//4OTJkzb1LZqbKyYmBiqVCsuXL7cZAu7scyzq6aefxvnz5/Hrr7/aLbO8Vxy9l0+cOIHjx4873OeZM2fg7u6O5s2bl6kuhBDiDD8/P/To0QOff/45kpKS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BQsWoGvXrti0aRNefPHFKttvplAosGHDBtx999146qmn0K5dOzz++OO4cOECAgMDAQADBw7EunXrsHnzZtx+++248847sXDhQnkQ5eXlhU8++QR9+/ZFly5dsHXrVqxduxa+vr4AgCtXruCPP/7AU089VcO/AhERUePieKl6HC9xvETkSApx4yRoIqJb1OXLlxEaGioXNa0vQgj07t0bL774Iv7xj3/U23WtGT9+PP78889GX1p4+vTpuH79Oj7++ONGbQcRERHVL46X6g/HS0SsKUVEt7Dt27cjPz8fUVFRSE1NxbRp09CqVSvcfffd9XofhUKBjz/+GMePH6/X6wLAu+++i/vuuw9ubm7YuHEjvvjiCyxdurTe71NbAQEBmDp1amM3g4iIiOzE8ZLjcLxExEwpIrqF/fLLL/jnP/+Jc+fOwcPDA3369MGiRYss5vk3dSNGjMDOnTuRl5eH1q1bY9KkSZg4cWJjN4uIiIiaCY6XiMiRGJQiIiIiIiIiIqIGx0LnRERERERERETU4BiUIiIiIiIiIiKiBsegFBERERERERERNTgGpYiIiIiIiIiIqMExKEVERERERERERA2OQSkiIiIiIiIiImpwDEoREREREREREVGDY1CKiIiIiIiIiIgaHINSRERERERERETU4P4fUA3YI649KbcAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "✓ Basic Modelica calculations completed!\n" + ] + } + ], + "source": [ + "# Create visualization of Modelica simulation results\n", + "fig, axes = plt.subplots(2, 2, figsize=(12, 10))\n", + "\n", + "# Plot 1: Range vs Angle for different velocities\n", + "for v0 in df_multi['v0'].unique():\n", + " subset = df_multi[df_multi['v0'] == v0]\n", + " axes[0, 0].plot(subset['angle'], subset['range'], marker='o', label=f'v0={v0} m/s')\n", + "axes[0, 0].set_xlabel('Launch Angle (degrees)')\n", + "axes[0, 0].set_ylabel('Range (m)')\n", + "axes[0, 0].set_title('Range vs Launch Angle (Modelica)')\n", + "axes[0, 0].legend()\n", + "axes[0, 0].grid(True, alpha=0.3)\n", + "\n", + "# Plot 2: Max Height vs Angle for different velocities\n", + "for v0 in df_multi['v0'].unique():\n", + " subset = df_multi[df_multi['v0'] == v0]\n", + " axes[0, 1].plot(subset['angle'], subset['max_height'], marker='o', label=f'v0={v0} m/s')\n", + "axes[0, 1].set_xlabel('Launch Angle (degrees)')\n", + "axes[0, 1].set_ylabel('Max Height (m)')\n", + "axes[0, 1].set_title('Maximum Height vs Launch Angle (Modelica)')\n", + "axes[0, 1].legend()\n", + "axes[0, 1].grid(True, alpha=0.3)\n", + "\n", + "# Plot 3: Flight Time vs Angle\n", + "for v0 in df_multi['v0'].unique():\n", + " subset = df_multi[df_multi['v0'] == v0]\n", + " axes[1, 0].plot(subset['angle'], subset['flight_time'], marker='o', label=f'v0={v0} m/s')\n", + "axes[1, 0].set_xlabel('Launch Angle (degrees)')\n", + "axes[1, 0].set_ylabel('Flight Time (s)')\n", + "axes[1, 0].set_title('Flight Time vs Launch Angle (Modelica)')\n", + "axes[1, 0].legend()\n", + "axes[1, 0].grid(True, alpha=0.3)\n", + "\n", + "# Plot 4: Energy Loss vs Angle\n", + "for v0 in df_multi['v0'].unique():\n", + " subset = df_multi[df_multi['v0'] == v0]\n", + " axes[1, 1].plot(subset['angle'], subset['energy_loss_percent'], marker='o', label=f'v0={v0} m/s')\n", + "axes[1, 1].set_xlabel('Launch Angle (degrees)')\n", + "axes[1, 1].set_ylabel('Energy Loss (%)')\n", + "axes[1, 1].set_title('Energy Loss to Air Resistance (Modelica)')\n", + "axes[1, 1].legend()\n", + "axes[1, 1].grid(True, alpha=0.3)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "print(\"\\n✓ Basic Modelica calculations completed!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## 3. Design of Experiments with Grid Sampling\n", + "\n", + "Now let's use `fzr` to perform a systematic design of experiments with the Modelica model.\n", + "We'll use a grid sampling approach to explore the parameter space systematically." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running DoE with 25 Modelica simulations...\n", + "(This will take several minutes)\n", + "\n", + "[■■■■■■■■■■■■■■■■■■■■■■■■■] Total time: 13s\n", + "============================================================\n", + "0 [0.0, 0.0939223834016754, 0.1877513346985295, ...\n", + "1 [0.0, 0.0818743790221217, 0.1450124904470977, ...\n", + "2 [0.0, 0.0642467513038971, 0.0846238793700119, ...\n", + "3 [0.0, 0.0422407930064658, 0.0469127845394185, ...\n", + "4 [0.0, 0.017356178387599, 0.017722842510228, 0....\n", + "5 [0.0, 0.2111935713780305, 0.2770660730568386, ...\n", + "6 [0.0, 0.1432383175843804, 0.1432383175843804, ...\n", + "7 [0.0, 0.084049073857963, 0.084049073857963, 0....\n", + "8 [0.0, 0.0466859356199648, 0.0466859356199648, ...\n", + "9 [0.0, 0.0176503590020455, 0.0176503590020455, ...\n", + "10 [0.0, 0.2756963701104411, 0.2756963701104411, ...\n", + "11 [0.0, 0.1429892171132139, 0.1429892171132139, ...\n", + "12 [0.0, 0.0839673410088704, 0.0839673410088704, ...\n", + "13 [0.0, 0.0466535339650135, 0.0466535339650135, ...\n", + "14 [0.0, 0.0176399881556713, 0.0176399881556713, ...\n", + "15 [0.0, 0.2752611604961372, 0.2752611604961372, ...\n", + "16 [0.0, 0.1429093920115702, 0.1429093920115702, ...\n", + "17 [0.0, 0.0839410962198039, 0.0839410962198039, ...\n", + "18 [0.0, 0.0466431219747637, 0.0466431219747637, ...\n", + "19 [0.0, 0.0176366546351121, 0.0176366546351121, ...\n", + "20 [0.0, 0.2750690706603109, 0.2750690706603109, ...\n", + "21 [0.0, 0.1428740552125181, 0.1428740552125181, ...\n", + "22 [0.0, 0.0839294699845172, 0.0839294699845172, ...\n", + "23 [0.0, 0.046638508353479, 0.046638508353479, 0....\n", + "24 [0.0, 0.0176351773842918, 0.0176351773842918, ...\n", + "Name: res_ProjectileMotion_x, dtype: object\n", + "============================================================\n", + "Computing physics outputs from trajectory data...\n", + "\n", + "Design of Experiments: 25 samples\n", + "Parameters explored: v0=[10.0, 60.0], angle=[20.0, 80.0]\n", + "\n", + "Output Statistics (from Modelica):\n", + " max_height range flight_time energy_loss_percent\n", + "count 25.000000 25.000000 25.000000 25.000000\n", + "mean 24.092862 49.738782 3.937600 53.681495\n", + "std 21.631808 35.489193 2.059426 26.141834\n", + "min 0.583086 3.233619 0.690000 9.397930\n", + "25% 5.842446 22.685058 2.180000 37.361769\n", + "50% 17.193133 37.187433 3.750000 62.677408\n", + "75% 37.364746 79.372881 5.490000 76.409765\n", + "max 74.973569 117.079774 7.850000 84.280073\n" + ] + } + ], + "source": [ + "# Define parameter combinations for design of experiments\n", + "# Using a grid approach to explore the parameter space\n", + "import numpy as np\n", + "\n", + "v0_values = np.linspace(10.0, 60.0, 5) # 5 velocities\n", + "angle_values = np.linspace(20.0, 80.0, 5) # 5 angles\n", + "\n", + "doe_params = {\n", + " 'v0': [v for v in v0_values],\n", + " 'angle': [a for a in angle_values],\n", + " 'k': '0.01', # Fixed air resistance\n", + " 'm': '1.0' # Fixed mass\n", + "}\n", + "\n", + "# Run design of experiments (5x5 = 25 simulations)\n", + "print(f\"Running DoE with {len(v0_values) * len(angle_values)} Modelica simulations...\")\n", + "print(\"(This will take several minutes)\\n\")\n", + "\n", + "results_doe = fz.fzr(\n", + " input_path='ProjectileMotion.mo',\n", + " input_variables=doe_params,\n", + " model='Modelica',\n", + " calculators=['localhost']*5 # Use 5 parallel calculators\n", + ")\n", + "\n", + "print(\"=\"*60)\n", + "print(results_doe['res_ProjectileMotion_x'])\n", + "print(\"=\"*60)\n", + "\n", + "# Convert to DataFrame\n", + "if hasattr(results_doe, 'iloc'):\n", + " df_doe = results_doe\n", + "else:\n", + " df_doe = pd.DataFrame(results_doe)\n", + "\n", + "# Enrich with computed physics outputs\n", + "print(\"Computing physics outputs from trajectory data...\")\n", + "physics_outputs = df_doe.apply(compute_projectile_outputs, axis=1, result_type='expand').astype(float)\n", + "df_doe = pd.concat([df_doe, physics_outputs], axis=1)\n", + "\n", + "print(f\"\\nDesign of Experiments: {len(df_doe)} samples\")\n", + "print(f\"Parameters explored: v0=[{v0_values[0]:.1f}, {v0_values[-1]:.1f}], angle=[{angle_values[0]:.1f}, {angle_values[-1]:.1f}]\")\n", + "\n", + "# Show statistics\n", + "print(\"\\nOutput Statistics (from Modelica):\")\n", + "print(df_doe[['max_height', 'range', 'flight_time', 'energy_loss_percent']].describe())" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABVQAAAJVCAYAAAAx/34PAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Xd8W+X1P/DP1bS2bMfxXnH2gEC2HUgYZa+ymkK/Tdg/ZqEttLRAwihQoC2EUii0DVAaaIGWAi207L0K8d57xY5tSR6SNe/z+8Pci64s25ItybJ83n3pRSPJulf76NzznMMxxhgIIYQQQgghhBBCCCGETEk22ztACCGEEEIIIYQQQgghcwUlVAkhhBBCCCGEEEIIISRElFAlhBBCCCGEEEIIIYSQEFFClRBCCCGEEEIIIYQQQkJECVVCCCGEEEIIIYQQQggJESVUCSGEEEIIIYQQQgghJESUUCWEEEIIIYQQQgghhJAQUUKVEEIIIYQQQgghhBBCQkQJVUIIIYQQQgghhBBCCAkRJVQJIRIcx2HPnj2zvRvjbN++Hdu3b5/t3Zi3TjnlFFx22WWzvRsAgIKCAuzatWtafxv4+n7yySfBcRxaW1sjsm+BfvrTn2LTpk1RuW1CCCEk0VAcSibT2toKjuPw5JNPTvtvH3jggcjvGACe57F69Wr84he/iMrth2u676Vgj/GePXvAcVzkdi7Ajh07cP7550ft9gmJFkqoRojwo1w4JSUlYenSpbjmmmvQ29s727sXVR9//DH27NkDm80W0+1++OGHOPnkk5GdnY2kpCTk5eXh9NNPx/79+2O6H9Gwfft2yevJ/7R8+fLZ3r2oqa6uxp49e6KW3IokIbAQTkqlEgUFBbjuuuti/l6Ito8++gj//e9/8ZOf/EQ879133xXv+zPPPBP070pKSsBxHFavXh2rXY07119/PcrKyvDyyy/P9q4QQhIYxaEUh0YSxaGts70rUxLiUJlMho6OjnGXDw0NQaPRgOM4XHPNNTHfv4KCApx22mlBLxNiyBdeeCHGexW6f//732EnI5999ll0dHRIHm//z+YPP/xw3N8wxpCbmwuO4yZ8vOaDn/zkJ3jxxRdRVlY227tCSFgUs70DieaOO+5AYWEhnE4nPvzwQzz66KP497//jcrKSmi12tnevaj4+OOPcfvtt2PXrl0wm80x2ebzzz+P73znO1i7di1+8IMfIDk5GS0tLXj//ffxxBNP4IILLojJfkRTTk4O7rnnnnHnm0ymWdib2Kiursbtt9+O7du3o6CgQHLZf//739nZqSk8+uij0Ov1sNvteOutt/Dwww/jq6++Cho0zVX3338/jjvuOCxevHjcZUlJSdi/fz++973vSc5vbW3Fxx9/jKSkpFjt5rT83//9H3bs2AG1Wh2V28/IyMCZZ56JBx54AGeccUZUtkEIIQKKQ80x2SbFoYlpLsaharUazz77LG666SbJ+X//+99naY+iKz8/H6Ojo1AqlVHdzr///W888sgjYSVV77//fuzYsSPoe0SIl7du3So5/7333kNnZ2fU4tBIueWWW/DTn/40ard/xBFHYP369fjVr36Fp59+OmrbISTSKKEaYSeffDLWr18PALj00kuRmpqKX//61/jnP/+J7373u9O+XZ7n4Xa74z45EUkOh2PC4H/Pnj1YuXIlPv30U6hUKsllhw4disXuRZ3JZBqXpJpr7HY7dDpdRG4r8HmOF+eeey4WLFgAALjiiiuwY8cO/PWvf8Xnn3+OjRs3zvLezdyhQ4fwr3/9C4899ljQy0855RS8/PLL6O/vFx8HANi/fz/S09OxZMkSWK3WWO1u2ORyOeRyeVS3cf755+O8885Dc3MzFi1aFNVtEULmN4pDI4fiUIpD/cVrHHrKKacETaju378fp556Kl588cVZ2rPoECrw482BAwdQVlaGX/3qV0EvP+WUU/D8889j7969UCi+ScHs378f69atQ39/f6x2dVoUCoVkv6Ph/PPPx+7du/G73/0Oer0+qtsiJFJoyX+UHXvssQCAlpYWAMADDzyA4uJipKamQqPRYN26dUGXOwjLM/7yl79g1apVUKvVeP3116d1G88//zxWrlwJjUaDLVu2oKKiAgDw+9//HosXL0ZSUhK2b98edHnLZ599hpNOOgkmkwlarRbbtm3DRx99JF6+Z88e3HjjjQCAwsJCcUmD/20988wzWLduHTQaDVJSUrBjx45xS1O2b9+O1atX48svv8TRRx8NrVaLn/3sZxM+rk1NTdiwYUPQ4GbhwoXi//fvlfOb3/wG+fn50Gg02LZtGyorKyV/V15ejl27dmHRokVISkpCRkYGLr74YgwMDIzbRldXFy655BJkZWVBrVajsLAQV155Jdxut3gdm82G66+/Hrm5uVCr1Vi8eDF++ctfguf5Ce9XOEZHR7F8+XIsX74co6Oj4vkWiwWZmZkoLi6Gz+cDAOzatQt6vR7Nzc048cQTodPpkJWVhTvuuAOMsSm3deDAAZx88skwGo3Q6/U47rjj8Omnn0quIyxpee+993DVVVdh4cKFyMnJAQC0tbXhqquuwrJly6DRaJCamorzzjtP8jp58skncd555wEAjjnmGPG19O677wII3rvq0KFDuOSSS5Ceno6kpCQcfvjheOqppyTX8X8NPP744ygqKoJarcaGDRvwxRdfSK7r8XhQW1uLgwcPTvmYTOSoo44CMPYaFVgsFvz4xz/GmjVroNfrYTQacfLJJ49b1iIsgfrb3/6GX/ziF8jJyUFSUhKOO+44NDY2jtvWI488gkWLFkGj0WDjxo344IMPgj5OLpcLu3fvxuLFi6FWq5Gbm4ubbroJLpdryvvzr3/9C16vF8cff3zQy88880yo1Wo8//zzkvP379+P888/P2iy0uv14s477xSfi4KCAvzsZz8btz+MMdx1113IycmBVqvFMcccg6qqqqD7Md3320Q9VF977TVs27YNBoMBRqMRGzZskCzj/OCDD3DeeechLy9PfExvuOEGyXtRIDx2//znPyfdF0IIiTSKQykOpTg0sePQCy64AKWlpaitrRXP6+npwdtvvx20UtrtduO2227DunXrYDKZoNPpcNRRR+Gdd96RXG/37t2QyWR46623JOdffvnlUKlUUVma3dXVhYsvvhjp6elQq9VYtWoV/vSnP0muM1EPVeFzJikpCatXr8Y//vEP7Nq1a1ylsWCy52LXrl145JFHAEDS7mIyL730ElQqFY4++uigl3/3u9/FwMAA3njjDfE8t9uNF154YcKKdrvdjh/96Efie3jZsmV44IEHxr1nXC4XbrjhBqSlpcFgMOCMM85AZ2dn0NsM5TEOZqIeqs888ww2btwIrVaL5ORkHH300ZJq7n/+85849dRTxc+qoqIi3HnnneJng79vfetbsNvtkseIkHhHFapRJiRVUlNTAQAPPfQQzjjjDFx44YVwu9147rnncN555+HVV1/FqaeeKvnbt99+G3/7299wzTXXYMGCBeIXQji38cEHH+Dll1/G1VdfDQC45557cNppp+Gmm27C7373O1x11VWwWq247777cPHFF+Ptt9+W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xj744APJ9h977DEGgH300UeT3s+tW7eydevWjTtf2Nfnn3+evfrqq4zjOPF1feONN7JFixYxxsaet1WrVol/V1paygCwSy+9VHJ7P/7xjxkA9vbbbzPGGDt06BBTqVTs1FNPlXwG/exnPxv3HIXzfgt8fQuvW+Hzy2azMYPBwDZt2sRGR0cltxf4WRjonnvuYRzHsba2tnGXnXDCCWzFihXjzifxa3R0lA0ODsbsFPh6IyQcFIdSHMoYxaHzMQ7t6+tjP/7xj9nixYvFyzZs2MAuuugixtjY43n11VeLl3m9XkmMyRhjVquVpaens4svvlhyfkVFBVOpVOzSSy9lVquVZWdns/Xr10tiz4nk5+dP+BoSTs8//7x4/UsuuYRlZmay/v5+ye3s2LGDmUwm8TkUHqN9+/aJ11mzZg3Lyclhw8PD4nnvvvsuA8Dy8/PF88J5Lq6++moWTqokJyeHnXPOOePOF16XX3zxBfvtb3/LDAaDeF/OO+88dswxx4iP16mnnir+3UsvvcQAsLvuuktye+eeey7jOI41NjYyxr6Jq6+66irJ9S644IJx76WZPMbC603Q0NDAZDIZ+/a3vz3uc2+qePmKK65gWq2WOZ3OcZctXbqUnXzyyePOJ5FBsW3k0ZL/CDv++OORlpaG3Nxc7NixA3q9Hv/4xz/EI2QajUa8rtVqxeDgII466ih89dVX425r27ZtWLly5bjzw7mN4447TrLUQTiKe84558BgMIw7v7m5GQBQWlqKhoYGXHDBBRgYGEB/fz/6+/tht9tx3HHH4f33359yydDf//538DyP888/X/z7/v5+ZGRkYMmSJeOWlqjValx00UWT3qbg4osvxuuvv47t27fjww8/xJ133omjjjoKS5Yswccffzzu+meddZbkKOXGjRuxadMm/Pvf/xbP839cnU4n+vv7sXnzZgAQH1ue5/HSSy/h9NNPF3uU+ROqB55//nkcddRRSE5Oltz3448/Hj6fD++///6U97GgoABvvPHGuFPg0cM9e/Zg1apV2LlzJ6666ips27YN1113XdDb9J86KRyddLvdePPNN4Ne3+fz4b///S/OOussSe/HzMxMXHDBBfjwww8xNDQk+ZvLLrts3DJv/8fW4/FgYGAAixcvhtlsDvq6DcW///1vZGRkSHrCKZVKXHfddRgZGcF7770nuf53vvMd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9//wzjvvoKSkBD6fD7W1tfjb3/6G//znPxMuDwXGPnMUCgXefPNNXH755ZPu15lnnokzzzxz0uscfvjh2LlzJx5//HFxKdDnn3+Op556CmeddZZYcZuWloYf//jHuOeee3DaaafhlFNOwYEDB/Daa6+Ne+9E4v0mMBqN+M1vfoNLL70UGzZswAUXXIDk5GSUlZXB4XDgqaeewvLly1FUVIQf//jH6OrqgtFoxIsvvjjhUq8333wTjLEpHxtCCIkmikMpDqU4NLHj0B/84AdTXue0007D3//+d3z729/GqaeeipaWFjz22GNYuXKlJCFZU1ODW2+9Fbt27RJfz08++STWrl2Lq666StL/NxLuvfdevPPOO9i0aRMuu+wyrFy5EhaLBV999RXefPNNWCyWCf/27rvvxplnnomSkhJcdNFFsFqt+O1vf4vVq1cHPSATCuFz5brrrsOJJ54IuVwurjwL5swzz8Sdd96J9957DyeccMKktx1KO5DTTz8dxxxzDH7+85+jtbUVhx9+OP773//in//8J66//nqxin/t2rX47ne/i9/97ncYHBxEcXEx3nrrraDVuTN5jAMtXrwYP//5z8WBfGeffTbUajW++OILZGVl4Z577kFxcTGSk5Oxc+dOXHfddeA4Dn/+858nbK3wxhtvQKvV4lvf+lbI+0HIrGMkIvbt28cAsC+++GLS6/3xj39kS5YsYWq1mi1fvpzt27eP7d69mwU+FQDY1VdfHfHbaGlpYQDY/fffLzn/nXfeYQDY888/Lzn/wIED7Oyzz2apqalMrVaz/Px8dv7557O33npLcr0777yTZWdnM5lMxgCwlpYW8bIXX3yRbd26lel0OqbT6djy5cvZ1Vdfzerq6sTrbNu2ja1atWrSx87fs88+y3bs2MGKioqYRqNhSUlJbOXKleznP/85GxoaCnp/f/WrX7Hc3FymVqvZUUcdxcrKyiS32dnZyb797W8zs9nMTCYTO++881h3dzcDwHbv3i25bltbG/v+97/P0tLSmFqtZosWLWJXX301c7lc4nWGh4fZzTffzBYvXsxUKhVbsGABKy4uZg888ABzu92T3r9t27YxABOeGGPsyy+/ZAqFgl177bWSv/V6vWzDhg0sKyuLWa1WxhhjO3fuZDqdjjU1NbETTjiBabValp6eznbv3s18Pp/k74Pd36+++oqd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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Interesting Results from Modelica:\n", + "============================================================\n", + "Maximum range: 117.08 m\n", + " at v0=60.00 m/s, angle=35.00°\n", + "\n", + "Maximum height: 74.97 m\n", + " at v0=60.00 m/s, angle=80.00°\n", + "\n", + "✓ Design of experiments with Modelica completed!\n" + ] + } + ], + "source": [ + "# Create 3D scatter plot of the Modelica DoE results\n", + "fig = plt.figure(figsize=(14, 6))\n", + "\n", + "# 3D plot: v0, angle, range\n", + "ax1 = fig.add_subplot(121, projection='3d')\n", + "scatter1 = ax1.scatter(df_doe['v0'], df_doe['angle'], df_doe['range'], \n", + " c=df_doe['range'], cmap='viridis', s=50, alpha=0.6)\n", + "ax1.set_xlabel('Initial Velocity (m/s)')\n", + "ax1.set_ylabel('Launch Angle (deg)')\n", + "ax1.set_zlabel('Range (m)')\n", + "ax1.set_title('Parameter Space Exploration: Range (Modelica)')\n", + "plt.colorbar(scatter1, ax=ax1, label='Range (m)')\n", + "\n", + "# 3D plot: v0, angle, max_height\n", + "ax2 = fig.add_subplot(122, projection='3d')\n", + "scatter2 = ax2.scatter(df_doe['v0'], df_doe['angle'], df_doe['max_height'], \n", + " c=df_doe['max_height'], cmap='plasma', s=50, alpha=0.6)\n", + "ax2.set_xlabel('Initial Velocity (m/s)')\n", + "ax2.set_ylabel('Launch Angle (deg)')\n", + "ax2.set_zlabel('Max Height (m)')\n", + "ax2.set_title('Parameter Space Exploration: Max Height (Modelica)')\n", + "plt.colorbar(scatter2, ax=ax2, label='Max Height (m)')\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "# Find interesting points\n", + "print(\"\\nInteresting Results from Modelica:\")\n", + "print(\"=\" * 60)\n", + "max_range_idx = df_doe['range'].idxmax()\n", + "print(f\"Maximum range: {df_doe.loc[max_range_idx, 'range']:.2f} m\")\n", + "print(f\" at v0={df_doe.loc[max_range_idx, 'v0']:.2f} m/s, angle={df_doe.loc[max_range_idx, 'angle']:.2f}°\\n\")\n", + "\n", + "max_height_idx = df_doe['max_height'].idxmax()\n", + "print(f\"Maximum height: {df_doe.loc[max_height_idx, 'max_height']:.2f} m\")\n", + "print(f\" at v0={df_doe.loc[max_height_idx, 'v0']:.2f} m/s, angle={df_doe.loc[max_height_idx, 'angle']:.2f}°\")\n", + "\n", + "print(\"\\n✓ Design of experiments with Modelica completed!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## 4. Optimization with Gradient Descent\n", + "\n", + "Now let's use the **fz-gradientdescent** algorithm to find the optimal parameters that maximize projectile range.\n", + "\n", + "**Goal**: Maximize the range by finding optimal velocity and launch angle using gradient descent optimization.\n", + "\n", + "First, we'll install the algorithm plugin from GitHub, then run the optimization." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step 4.1: Install Gradient Descent Algorithm\n", + "\n", + "First, we'll install the fz-gradientdescent algorithm plugin from GitHub." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installing fz-gradientdescent algorithm from GitHub...\n", + "\n", + "✓ Installed algorithm: gradientdescent\n", + "✓ Algorithm path: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/.fz/algorithms/gradientdescent.R\n", + "\n", + "✓ Gradient descent algorithm ready!\n" + ] + } + ], + "source": [ + "# Install the gradient descent algorithm plugin\n", + "print(\"Installing fz-gradientdescent algorithm from GitHub...\\n\")\n", + "\n", + "try:\n", + " result = fz.install_algorithm('gradientdescent', global_install=False)\n", + " print(f\"✓ Installed algorithm: {result['algorithm_name']}\")\n", + " print(f\"✓ Algorithm path: {result['install_path']}\")\n", + "except Exception as e:\n", + " print(f\"⚠ Error installing algorithm: {e}\")\n", + " print(\" Will try to use algorithm name directly\")\n", + "\n", + "print(\"\\n✓ Gradient descent algorithm ready!\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Now we'll use the gradient descent algorithm to find the optimal launch parameters.\n", + "\n", + "Running Gradient Descent optimization with Modelica...\n", + "Objective: Minimize -range (maximize range)\n", + "(This will take several minutes due to Modelica simulations)\n", + "\n", + "[■■■] Total time: 2s\n", + "[■■■] Total time: 2s\n", + "[■■■] Total time: 1s\n", + "[■■■] Total time: 2s\n", + "[■■■] Total time: 2s\n", + "\n", + "============================================================\n", + "OPTIMIZATION RESULTS\n", + "============================================================\n", + "\n", + "Algorithm: gradientdescent\n", + "Iterations: 5\n", + "Total Evaluations: 15\n", + "\n", + "Summary:\n", + "gradientdescent completed: 5 iterations, 15 evaluations (15 valid)\n", + "\n", + "============================================================\n", + "OPTIMAL SOLUTION (from Modelica + Gradient Descent)\n", + "============================================================\n", + "Initial Velocity: 59.93 m/s\n", + "Launch Angle: 22.36 degrees\n", + "Maximum Range: 171.89 m\n", + "\n", + "✓ Gradient descent optimization with Modelica completed!\n" + ] + } + ], + "source": [ + "### Step 4.2: Run Optimization with Gradient Descent\n", + "\n", + "print(\"Now we'll use the gradient descent algorithm to find the optimal launch parameters.\\n\")\n", + "\n", + "# Define optimization problem\n", + "opt_params = {\n", + " 'v0': '[10.0; 60.0]', # Search in this range\n", + " 'angle': '[20.0; 80.0]', # Search in this range\n", + " 'k': '0.01', # Fixed\n", + " 'm': '1.0' # Fixed\n", + "}\n", + "\n", + "# Define output we want to minimize (negative range = maximize range)\n", + "print(\"Running Gradient Descent optimization with Modelica...\")\n", + "print(f\"Objective: Minimize -range (maximize range)\")\n", + "print(\"(This will take several minutes due to Modelica simulations)\\n\")\n", + "\n", + "fz.set_log_level('WARNING')\n", + "\n", + "# Run optimization using fzd with gradient descent\n", + "opt_result = fz.fzd(\n", + " input_path='ProjectileMotion.mo',\n", + " input_variables=opt_params,\n", + " model='Modelica',\n", + " calculators=['localhost']*5, # Use 5 parallel calculators\n", + " algorithm='gradientdescent', # Use the installed algorithm\n", + " output_expression=\"-res_ProjectileMotion_x[-1]\", # Negative range at landing\n", + " algorithm_options={\n", + " 'max_iterations': 20, # Limit iterations for faster demo\n", + " 'tolerance': 0.1, # Convergence tolerance\n", + " 'step_size': 1.0 # Initial step size\n", + " }\n", + ")\n", + "\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"OPTIMIZATION RESULTS\")\n", + "print(\"=\" * 60)\n", + "print(f\"\\nAlgorithm: {opt_result['algorithm']}\")\n", + "print(f\"Iterations: {opt_result['iterations']}\")\n", + "print(f\"Total Evaluations: {opt_result['total_evaluations']}\")\n", + "print(f\"\\nSummary:\\n{opt_result['summary']}\")\n", + "\n", + "# Get the best solution from results\n", + "df_opt = opt_result['XY']\n", + "best_idx = df_opt['-res_ProjectileMotion_x[-1]'].idxmin()\n", + "\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"OPTIMAL SOLUTION (from Modelica + Gradient Descent)\")\n", + "print(\"=\" * 60)\n", + "print(f\"Initial Velocity: {df_opt.loc[best_idx, 'v0']:.2f} m/s\")\n", + "print(f\"Launch Angle: {df_opt.loc[best_idx, 'angle']:.2f} degrees\")\n", + "print(f\"Maximum Range: {-df_opt.loc[best_idx, '-res_ProjectileMotion_x[-1]']:.2f} m\")\n", + "\n", + "print(\"\\n✓ Gradient descent optimization with Modelica completed!\")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAPeCAYAAADd/6nHAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Xd4FFXbBvB700MqaSShhBBK6CAggjRpoRNa6F2KiiiICJ8KBBUUQUFFEAugiHQQUHoN0kQFBARDCCA1gTRCSCDZ8/0x72x2sptkE7I19++6uNiZncyePTs7+8wzp6iEEAJEREREREREREQmZGfuAhARERERERERUenDpBQREREREREREZkck1JERERERERERGRyTEoREREREREREZHJMSlFREREREREREQmx6QUERERERERERGZHJNSRERERERERERkckxKERERERERERGRyTEpRUREREREREREJseklJVYsWIFVCoVrl69WmL7nDVrFlQqVYntz9Jfl6g40tPTERAQgB9//NHcRcHVq1ehUqmwYsWKIv/twYMHoVKpcPDgQc26ESNGoHLlyiVWvtJOX32qVCrMmjXLLOUhwwwYMABRUVHmLgYR2aCn+d0uSGmPpbt06YIxY8aYuxj50vf5VK5cGSNGjDBPgcgg06ZNQ9OmTc1djFKJSaliOn/+PIYMGYLy5cvD2dkZwcHBGDx4MM6fP/9U+50zZw62bNlSMoU0o4yMDMyaNUtxAWwJVCqV5p+dnR2Cg4PRsWNHiyunpWvTpo2iLl1dXVGvXj0sXLgQarXa3MUrUYsWLYKHhwcGDBigWScHG3Z2dvjvv/90/iYtLQ2urq5QqVSYMGGCKYtbKsXHx2PChAmoXr06ypQpgzJlyqBWrVp45ZVXcPbsWXMXz+hWr16NhQsXGrx95cqVFedBb29v1K1bF2PHjsWJEyeMV1AzunXrFmbNmoXTp0/rPPfWW29h48aNOHPmjOkLRqWWfLNR/ufi4oLq1atjwoQJuHv3rrmLZ1RHjx7FrFmzkJKSYrLXlH+38/t3584dk5XFUJYaSz+trKwsvPXWWwgODoarqyuaNm2KPXv2GPz3v/32G3bv3o233npL57mEhARMmzYNdevWhbu7O1xcXFC1alWMHDkSR44cKcm3YZF+/fXXIt0I047n7ezs4OnpiRo1amDo0KFF+kys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np4iISFBUdZ27dqJunXriszMTM06tVotmjdvLqpVq6ZZV79+fdG1a9d833NycrIAID7++OMC60Y+xpYvX17gdkII0bp1axEeHi4SExNFYmKiuHjxonjzzTcFAJ2yaNeh7KefftL5HOXjQvs4EkKIXr16CV9fX83yH3/8IQCI119/XbHdiBEjdI650aNHi6CgIHHv3j3FtgMGDBBeXl56yyZ78uSJUKlUeo8ruayJiYliypQpomrVqprnmjRpIkaOHCmEkI63V155RfPcwoULBQCxatUqzbrHjx+LZs2aCXd3d805Y8uWLQKAmDdvnma77Oxs0bJlS53PyNDjRD6utc8Bw4cPVxyP+/fvFwDExIkTdd6zWq3WPNZXbxEREaJKlSo66w0REhKi91xRkNTUVAFAREZG6jyXnJysOTYTExMV5R0+fLgAIKZNm6bzd/re19y5c4VKpVKcTxs0aCCCgoJESkqKZt3u3bt1vt9CiGIfk/LnVbNmTcU5d9GiRQKA+PvvvzXrunbtqvO6BQkJCSnwnPHpp58KAOLnn38WQggRExMjAIgff/xRsd3OnTsV6zdv3iwAiN9//z3ffRtyjF29elXY29uLDz74QPH833//LRwcHBTrW7duLQCI77//XrMuKytLBAYGij59+mjW/f7774We36pXry46d+6c7/NEJUn+zd27d69ITEwU//33n1izZo3w9fUVrq6u4saNG0II3fPS48ePRZ06dUTbtm0V6wEIOzs7cf78eZ3XKso+nJ2dFbGmHD8GBgZqfqOEEGL69OmKuFStVotq1aqJiIgInd+L0NBQ0aFDB826jz/+WCemFaJ43/2lS5fqvF995N9tff9q1Kih8361z7FCCFGrVi1Ffb3++usCgIiJidGse/DggQgNDRWVK1cWOTk5QojcOE/73NO6dWvRunVrnTLm/U22hFg6JCTEoN+X6dOnC0dHR5GUlKRZl5WVJby9vRVxXe3atXWOOyGEOH/+vEGfZ4sWLUSjRo101pctW1Y0aNBAZ31aWpoiHkhPT9c8J9fhwIEDdf7O0Ng1MjJSuLi4KGKECxcuCHt7e51rrJCQEMU13nvvvSfc3NzEv//+q9hu2rRpwt7eXly/fl0IkXsM+fr6Kur3559/FgDEtm3bNOteeeWVAq/t8mrdurWoXbt2vs/Lv+uLFi0SQhj+Hf3rr78E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xx9/RHh4ONq1a4cuXbqgRYsWWLZsmbGKTFaAMRYRERFRIbRbSjFgIiIiMzFrS6k2bdpACMNnRrt69arOOh8fH6xevboES0XWjq3RiYiIiAqhfRePARMREZkJB0Ugm8OWUkRERESFYMBEREQWgEkpsjlyjOXgAJQta96yEBEREVkkdt8jIiILwKQU2Rw5xipXDuAESURERER6yHfxvLwAFxfzloWIiEotXrKTTVGrgcRE6TFv+hERERHlQ05KMWAiIiIzYlKKbMr9+0BOjvSYY3YSERER6ZGRATx4ID1mwERERGbEpBTZFA6PQERERFQIDnJOREQWgkkpsimMsYiIiIgKwYCJiIgsBJNSZFO0W0qxNToRERGRHgyYiIjIQjApRTaFN/6IiIiICsGAiYiILASTUmRTGGMRERERFYIBExERWQgmpcimsDU6ERERUSEYMBERkYVgUopsCm/8ERERERWCARMREVkIJqXIpsgxlqMjULasectCREREZJG0W0oFBJivHEREVOoxKUU2RY6xypUDVCrzloWIiIjIIsl38by9ARcXsxaFiIhKNyalyGbk5ACJidJjtkQnIiIiyoeclGLAREREZsakFNmMe/cAtVp6zDE7iYiIiPR4+BBIT5ceM2AiIiIzczB3AYhKCsfsJCIia6FWq3Ho0CHExMTg2rVryMjIgL+/Pxo2bIj27dujYsWK5i4i2SoGTEREZEHYUopsBmMsIiKydI8ePcL777+PihUrokuXLtixYwdSUlJgb2+Py5cvY+bMmQgNDUWXLl1w/PhxcxeXbBEDJiIisiBsKUU2Q3siGbZGJyIiS1S9enU0a9YMX3/9NTp06ABHR0edba5du4bVq1djwIABePvttzFmzBgzlJRsFgMmIiKyIExKkc3gjT8iIrJ0u3fvRs2aNQvcJiQkBNOnT8eUKVNw/fp1E5WMSg0GTEREZEHYfY9shnaMxRt/RERkiQpLSGlzdHREWFiYEUtDpRKTUkREZEGYlCKbod0anTEWERFZup07d+LIkSOa5cWLF6NBgwYYNGgQkpOTzVgysmnsvkdERBaESSmyGbzxR0RE1uTNN99EWloaAODvv//GG2+8gS5duiA+Ph6TJ082c+nIZjFgIiIiC8KkFNkM+cafkxPg7W3WohARERUqPj4etWrVAgBs3LgR3bp1w5w5c7B48WLs2LGj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IptiyLF8fAC1WtlYiIiIiGySIWFydgY8PZWNhYiI6DGwKEU2Q4iHORYP+hERERHlwdC13M8PkCRlYyEiInoMLEqRzUhMBDIz9fdZlCIiIiIyIzsbuHtXf58JExERlXAsSpHN4CDnRERERAWIj9d3LweYMBERUYnHohTZDF5IhoiIiKgATJiIiMiOsChFNoMXkiEiIiIqALuWExGRHWFRimwGcywiIiKiArCnFBER2REWpchmMMciIiIiKgC7lhMRkR1hUYpsBntKERERERWACRMREdkRFqXIZvDAHxEREVEB2LWciIjsCItSZDMMOZZKBZQrp2wsRERERDaJR/GIiMiOsChFNsOQY/n6Amq1srEQERER2SRDwuTiAnh4KBsLERHRY2JRimyCEA9zLB70IyIiIsqDoWu5nx8gScrGQkRE9JhYlCKbkJAAZGXp77MoRURERGRGVhZw967+PhMmIiKyAyxKkU3ghWSIiIiIChAf//A+EyYiIrIDLEqRTeCFZIiIiIgKwISJiIjsDItSZBPYU4qIiIioAEyYiIjIzrAoRTaBVzcmIiIiKgATJiIisjMsSpFNYG90IiIiogIwYSIiIjvDohTZBPZGJyIiIioAEyYiIrIzLEqRTeCBPyIiIqIC8PQ9IiKyMyxKkU0w5FhqNVCunLKxEBEREdkkHsUjIiI7w6IU2QRDUcrXF1DxU0lERERkypAwuboC7u7KxkJERFQM+POfFKfTPcyxeNCPiIiIKA+GnlJ+foAkKRsLERFRMWBRihSXkABkZ+vvc8xOIiIiIjOysoB79/T3eRSPiIjsBItSpDiO2UlERERUgLi4h/d5FI+IiOwEi1KkOI7ZSURERFQAJkxERGSHWJQixeXsKcUDf0RERERmsGs5ERHZIRalSHE88EdERERUAB7FIyIiO8SiFCmOB/6IiIiICsCjeEREZIdYlCLF8cAfERERUQGYMBERkR1iUYoUxwN/RERERAVg13IiIrJDLEqR4gw5loMDULassrEQERER2SQexSMiIjvEohQpzlCU8vUFVPxEEhEREZkyJExuboC7u7KxEBERFROWAEhROt3DHIsH/YiIiIjywISJiIjsEItSpKh79wCtVn+fY3YSERERmZGZqU+aABaliIjIrrAoRYri8AhEREREBYiLe3ifR/GIiMiOsChFiuKFZIiIiIgKwKN4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fampqdixYwfu3Lljtpt6+/btUbduXQwcOBBHjx7FwYMH8eKLLyIiIgJNmjQp9jYgIiIiyg/zJSKyZSxKEVGJNWHCBKjVaoSGhsLHxwdXr15FYGAg9uzZA61Wi44dO6Ju3boYN24cvL29jUf0zKlfvz4+/vhjzJ07F3Xq1MGqVasQGRkpm6dFixZ4+eWX8dxzz8HHx8dk4E9A3638p59+QpkyZdC6dWu0b98eVatWxQ8//FDs75+IiIioIMyXiMiWSUIIoXQQRERERERERERUurCnFBERERERERERWR2LUkREREREREREZHUsShERERERERERkdWxKEVERERERERERFbHohQREREREREREVkdi1JERERERERERGR1LEoREREREREREZHVsShFRERERERERERWx6IUERERERERERFZHYtSRERERERERERkdSxKERERERERERGR1bEoRUREREREREREVseiFBERERERERERWR2LUkREREREREREZHUsShERERERERERkdWxKEVERERERERERFbHohQREREREREREVkdi1JEpVhMTAwkScLXX39drMudPn06JEkq1mWWdMHBwRgyZEixLlOn06FOnTqYPXt2sS63OA0ZMgTBwcGyaZIkYfr06YrEQ4XTv39/9OvXT+kwiKzm66+/hiRJiImJKbZlKrUvtPd9sCF3mT9//iO9/u+//4YkSfj777+LNzCiYrR27VqULVsWqampSodilrnfEPa+7bEHp0+fhoODA/7991+lQ5FhUYrMMiRnhpuzszNq1KiBMWPGIDY2VunwLGrv3r2YPn06EhMTrbZOw0Y8r9vt27etFkthpaWlYfr06SUuqfvtt98gSRICAwOh0+mUDuexrFmzBteuXcOYMWNMnrt8+TLGjBmDGjVqwNXVFa6urggNDcXo0aNx8uRJBaK1rtWrV2PhwoWFnj84ONj4fVOpVPD29kbdunUxcuRIHDhwwHKBKujmzZuYPn06jh8/bvLc22+/jfXr1+PEiRPWD4wIwKlTp/DCCy+gQoUK0Gg0CAwMxMCBA3Hq1KnHWu6cOXOwadOm4glSQba6D86Zu6hUKgQGBqJjx46PFOdvv/1WYg5g5NyHSJIEX19fhIeHY+PGjUqHZnFKfKdSU1Mxbdo01KlTB25ubihXrhwaNGiA119/HTdv3rRqLJag1Woxbdo0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xbi4OJmiNSzNye3s2bPFgIAAUaVSyRSlYWoqt+fOnROHDx8uenp6ira2tmJ4eLj41VdfyRix4Wgqt6+88oro5eUlWlhYiO3atROXLl0qqtVqGSM2LE199mqpvrYgiqKo27FXREREREREREREN8c1pYiIiIiIiIiIqMWxKEVERERERERERC2ORSkiIiIiIiIiImpxLEoREREREREREVGLY1GKiIiIiIiIiIhaHItSRERERERERETU4liUIiIiIiIiIiKiFseiFBERERERERERtTgWpYiI7lCrVq3w4Ycfyh0GERER6TFBEPDzzz/f9DlPPfUUHn744Wbv88KFCxAEAceOHbuj2JrSnNjl3F99u3btQseOHaFSqSTZf2NOnz4Nf39/lJWVtVibRMaCRSkiMij1O2v9+/fHjBkzWqztdevWwdnZucH2w4cPY+LEiS0WBxEREcnrVotHAJCVlYX77rsPwI2LScuXL8e6det0EySAzp07Y/LkyY0+9vXXX8PKygrXrl3TWXvN1Zxc3K6XX34Z8+bNg5mZmU72FxwcjJ07d970OaGhoejTpw8++OADnbRJZEpYlCIik1dVVXVHr/fw8ICtra2OoiEiIiJj5O3tDSsrq5s+x8nJqdEvwG7XhAkTsHHjRlRUVDR4bO3atXjooYfg7u6us/aaqzm5uB179+5FamoqRowYoZP9nThxAgUFBbjrrruafO748eOxcuVK1NTU6KRtIlPBohQRGaSnnnoKe/bswfLlyyEIAgRBwIULFwAASUlJuO+++2Bvbw8vLy+MGTNG61vA/v37Y+rUqZgxYwbc3d0xZMgQAMAHH3yAzp07w87ODgEBAfi///s/lJaWAgD++ecfjB8/HkVFRZr23njjDQANp+9lZGRg2LBhsLe3h6OjI0aOHImcnBzN42+88Qa6du2Kr7/+Gq1atYKTkxMef/xxlJSUSJs0IiIikkT//v3x/PPP4+WXX4arqyu8vb01/YQ69aesBQcHAwC6desGQRDQv39/AA1HYG3btg39+vWDs7Mz3Nzc8OCDDyI1NbXZcT355JOoqKjA5s2btbanp6fjn3/+wYQJEwAAv/zyC7p37w5ra2u0bt0ab7755k2LKydPnsSAAQNgY2MDNzc3TJw4UdNnqvPll1+iU6dOsLKygo+PD6ZOndrsXMTGxsLCwgLZ2dla+5wxYwai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N+34tW3bFtXV1fj444+RlpaGr7/+WrMAev32SktLsWvXLly7dq3R4dmDBg1C586dMXr0aCQmJuLQoUMYO3Ys7rrrrkYX3iQiIiLT4+npCRsbG80FWYqKiho8x8XFBW5ublizZg3Onz+Pv//+G7Nmzbqt9oKDgzFgwABMnDgRVlZWGD58uOax119/HV999RXefPNNnDp1CmfOnMHGjRsxb968Rvc1evRoWFtbY9y4cUhKSsLu3bsxbdo0jBkzBl5eXgBqr3i3dOlSfPTRR0hJSUFiYmKDUUXNycWQIUPg6OiIBQsWaKYb3syQIUOwd+/eW0lNo7Zt24b27dtrpksCtVf+2759O9LT05GYmIjdu3ejY8eOmscvXLiAy5cvY9CgQXfcPpEpYVGKiAzWiy++CDMzM4SGhsLDwwMZGRnw9fVFfHw8VCoVBg8ejM6dO2PGjBlwdnZu9Nu+Ol26dMEHH3yAJUuWICwsDN9++y0WL16s9Zy+ffti8uTJeOyxx+Dh4YF33323wX4EQcAvv/wCFxcXxMTEYNCgQWjdujW+//57nb9/IiIiMkzm5ub46KOPsHr1avj6+jYYkQPUTrvbuHEjEhISEBYWhpkzZ+K999677TYnTJiAgoICPPHEE1rT8oYMGYLff/8df/31F3r27Ik+ffpg2bJlCAoKanQ/tra22L59O/Lz89GzZ088+uijGDhwID755BPNc8aNG4cPP/wQn376KTp16oQHH3wQKSkpt5yLuqmHKpUKY8eObfI9jh49GqdOnUJycnJz09KoX375RWvqHlA7kmvKlCno2LEj7r33XrRv3x6ffvqp5vHvvvsOgwcPvmHeiKhxgiiKotxBEBEREREREV1vwoQJuHr1Kn799ddmPf+ll15CcXExVq9efVvt1dTUwMvLC1u3bkWvXr2a9Zqqqiq0a9cOGzZsaHKKIRFp40gpIiIiIiIi0itFRUXYu3cvNmzYgGnTpjX7dXPnzkVQUNBtLzKfn5+PmTNnomfPns1+TUZGBubMmcOCFNFt4EgpIiIiIiIi0iv9+/fHoUOHMGnSJCxbtkzucIhIIixKERERERERERFRi+P0PSIiIiIiIiIianEsShERERERERERUYtjUYqIiIiIiIiIiFoci1JERERERERERNTiWJQiIiIiIiIiIqIWx6IUERERERERERG1OBaliIiIiIiIiIioxbEoRURERERERERELY5FKSIiIiIiIiIianH/D/dAkhCbSsVIAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "✓ Gradient descent optimization visualized!\n" + ] + } + ], + "source": [ + "### Step 4.3: Visualize Optimization Progress\n", + "\n", + "# Get optimization data\n", + "df_opt = opt_result['XY']\n", + "\n", + "# Display the HTML analysis if available\n", + "if 'analysis' in opt_result and 'html' in opt_result['analysis']:\n", + " display(HTML(opt_result['analysis']['html']))\n", + "\n", + "# Create additional plots\n", + "fig, axes = plt.subplots(2, 2, figsize=(12, 10))\n", + "\n", + "# Plot 1: Convergence - Range over iterations\n", + "axes[0, 0].plot(range(len(df_opt)), -df_opt['-res_ProjectileMotion_x[-1]'], 'b-o', linewidth=2, markersize=6)\n", + "axes[0, 0].set_xlabel('Iteration')\n", + "axes[0, 0].set_ylabel('Range (m)')\n", + "axes[0, 0].set_title('Optimization Progress: Range (Modelica + Gradient Descent)')\n", + "axes[0, 0].grid(True, alpha=0.3)\n", + "\n", + "# Plot 2: Parameter evolution - v0\n", + "axes[0, 1].plot(range(len(df_opt)), df_opt['v0'], 'r-o', linewidth=2, markersize=6)\n", + "axes[0, 1].set_xlabel('Iteration')\n", + "axes[0, 1].set_ylabel('Initial Velocity (m/s)')\n", + "axes[0, 1].set_title('Parameter Evolution: v0 (Gradient Descent)')\n", + "axes[0, 1].grid(True, alpha=0.3)\n", + "\n", + "# Plot 3: Parameter evolution - angle\n", + "axes[1, 0].plot(range(len(df_opt)), df_opt['angle'], 'g-o', linewidth=2, markersize=6)\n", + "axes[1, 0].set_xlabel('Iteration')\n", + "axes[1, 0].set_ylabel('Launch Angle (degrees)')\n", + "axes[1, 0].set_title('Parameter Evolution: Angle (Gradient Descent)')\n", + "axes[1, 0].grid(True, alpha=0.3)\n", + "\n", + "# Plot 4: Trajectory in parameter space\n", + "axes[1, 1].plot(df_opt['v0'], df_opt['angle'], 'purple', linewidth=2, alpha=0.6)\n", + "axes[1, 1].scatter(df_opt['v0'], df_opt['angle'], c=range(len(df_opt)), \n", + " cmap='viridis', s=100, zorder=5, edgecolors='black', linewidth=1)\n", + "axes[1, 1].scatter(df_opt['v0'].iloc[0], df_opt['angle'].iloc[0], \n", + " c='green', s=200, marker='s', zorder=10, edgecolors='black', \n", + " linewidth=2, label='Start')\n", + "axes[1, 1].scatter(df_opt['v0'].iloc[-1], df_opt['angle'].iloc[-1], \n", + " c='red', s=200, marker='*', zorder=10, edgecolors='black', \n", + " linewidth=2, label='End')\n", + "axes[1, 1].set_xlabel('Initial Velocity (m/s)')\n", + "axes[1, 1].set_ylabel('Launch Angle (degrees)')\n", + "axes[1, 1].set_title('Optimization Path in Parameter Space (Gradient Descent)')\n", + "axes[1, 1].legend()\n", + "axes[1, 1].grid(True, alpha=0.3)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "print(\"\\n✓ Gradient descent optimization visualized!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## 5. Root Finding with Brent's Method\n", + "\n", + "Finally, let's use the **fz-brent** algorithm to find the launch angle that achieves a specific target range.\n", + "\n", + "**Goal**: Find the launch angle that produces exactly 150m range with v0=45 m/s using Brent's method.\n", + "\n", + "Brent's method is a robust and efficient root-finding algorithm that combines bisection, secant method, and inverse quadratic interpolation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step 5.1: Install Brent's Method Algorithm\n", + "\n", + "First, we'll install the fz-brent algorithm plugin from GitHub." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installing fz-brent algorithm from GitHub...\n", + "\n", + "✓ Installed algorithm: brent\n", + "✓ Algorithm path: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/.fz/algorithms/brent.R\n", + "\n", + "✓ Brent's method algorithm ready!\n" + ] + } + ], + "source": [ + "# Install the Brent algorithm plugin\n", + "print(\"Installing fz-brent algorithm from GitHub...\\n\")\n", + "\n", + "try:\n", + " result = fz.install_algorithm('brent', global_install=False)\n", + " print(f\"✓ Installed algorithm: {result['algorithm_name']}\")\n", + " print(f\"✓ Algorithm path: {result['install_path']}\")\n", + "except Exception as e:\n", + " print(f\"⚠ Error installing algorithm: {e}\")\n", + " print(\" Will try to use algorithm name directly\")\n", + "\n", + "print(\"\\n✓ Brent's method algorithm ready!\")" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "✓ Root finding problem configured:\n", + " Target range: 100.0m\n", + " Fixed velocity: 45.0 m/s\n", + " Search range: 20-70 degrees\n", + " Algorithm: Brent's method (1D root finding)\n" + ] + } + ], + "source": [ + "### Step 5.2: Configure Root Finding Problem\n", + "\n", + "# Target range for root finding\n", + "target_range = 100.0 # meters\n", + "\n", + "print(f\"✓ Root finding problem configured:\")\n", + "print(f\" Target range: {target_range}m\")\n", + "print(f\" Fixed velocity: 45.0 m/s\")\n", + "print(f\" Search range: 20-70 degrees\")\n", + "print(f\" Algorithm: Brent's method (1D root finding)\")" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running root finding with Brent's method and Modelica...\n", + "Objective: Find angle where range = 100.0m\n", + "(This will take several minutes due to Modelica simulations)\n", + "\n", + "[◢◢◢] ETA: ... ⚠️ [Thread 124739337053888] angle=80.0,v0=45.0,k=0.01,m=1.0: Could not clean up temp directory /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/.fz/tmp/fz_temp_fa32d20bcd1e_1761942980/angle=80.0,v0=45.0,k=0.01,m=1.0: [Errno 2] Aucun fichier ou dossier de ce nom: 'ProjectileMotion_17inl.c'\n", + "[■■■] Total time: 2s\n", + "[ ] ETA: ...Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter001/angle=80.0,v0=45.0,k=0.01,m=1.0\n", + "Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter001/angle=20.0,v0=45.0,k=0.01,m=1.0\n", + "[■■■] Total time: 1s\n", + "[ ] ETA: ...Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter001/angle=80.0,v0=45.0,k=0.01,m=1.0\n", + "Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter002/angle=45.90151917729081,v0=45.0,k=0.01,m=1.0\n", + "[■■■] Total time: 1s\n", + "[ ] ETA: ...Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter003/angle=65.03639906943988,v0=45.0,k=0.01,m=1.0\n", + "Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter002/angle=45.90151917729081,v0=45.0,k=0.01,m=1.0\n", + "[■■■] Total time: 1s\n", + "[ ] ETA: ...Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter003/angle=65.03639906943988,v0=45.0,k=0.01,m=1.0\n", + "Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter004/angle=57.41022609074264,v0=45.0,k=0.01,m=1.0\n", + "[■■■] Total time: 1s\n", + "[ ] ETA: ...Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter005/angle=58.460728665139534,v0=45.0,k=0.01,m=1.0\n", + "Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter003/angle=65.03639906943988,v0=45.0,k=0.01,m=1.0\n", + "[■■■] Total time: 1s\n", + "[ ] ETA: ...Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter005/angle=58.460728665139534,v0=45.0,k=0.01,m=1.0\n", + "Cache match found in subdirectory: /home/richet/Sync/Open/Funz/github/fz/examples/tmp/tmp/analysis/iter006/angle=58.5525229919334,v0=45.0,k=0.01,m=1.0\n", + "[■■■] Total time: 1s\n", + "\n", + "============================================================\n", + "ROOT FINDING RESULTS\n", + "============================================================\n", + "\n", + "Algorithm: brent\n", + "Iterations: 7\n", + "Total Evaluations: 21\n", + "\n", + "Summary:\n", + "brent completed: 7 iterations, 21 evaluations (21 valid)\n", + "{'XY': angle v0 k m res_ProjectileMotion_x[-1] - 100.0\n", + "0 20.000000 45.0 0.01 1.0 47.302622\n", + "1 80.000000 45.0 0.01 1.0 -62.272314\n", + "2 80.000000 45.0 0.01 1.0 -62.272314\n", + "3 20.000000 45.0 0.01 1.0 47.302622\n", + "4 45.901519 45.0 0.01 1.0 23.913880\n", + "5 80.000000 45.0 0.01 1.0 -62.272314\n", + "6 45.901519 45.0 0.01 1.0 23.913880\n", + "7 65.036399 45.0 0.01 1.0 -15.846384\n", + "8 80.000000 45.0 0.01 1.0 -62.272314\n", + "9 65.036399 45.0 0.01 1.0 -15.846384\n", + "10 57.410226 45.0 0.01 1.0 2.531554\n", + "11 45.901519 45.0 0.01 1.0 23.913880\n", + "12 57.410226 45.0 0.01 1.0 2.531554\n", + "13 58.460729 45.0 0.01 1.0 0.205862\n", + "14 65.036399 45.0 0.01 1.0 -15.846384\n", + "15 58.460729 45.0 0.01 1.0 0.205862\n", + "16 58.552523 45.0 0.01 1.0 -0.000446\n", + "17 65.036399 45.0 0.01 1.0 -15.846384\n", + "18 58.552523 45.0 0.01 1.0 -0.000446\n", + "19 58.547523 45.0 0.01 1.0 0.010804\n", + "20 58.460729 45.0 0.01 1.0 0.205862, 'analysis': {'data': {'root': 58.5475229919334, 'value': 0.010804151258398065, 'iterations': 7.0, 'converged': [10]\n", + "R classes: ('logical',)\n", + "[ 1], 'exit_code': 0.0}, 'html_file': 'analysis_7.html', 'text': 'Brent Root Finding Results:\\n Iterations: 7\\n Root approximation: 58.547523\\n Corresponding value: 0.010804\\n Target value: 0.000000\\n Exit status: algorithm converged\\n'}, 'algorithm': 'brent', 'iterations': 7, 'total_evaluations': 21, 'summary': 'brent completed: 7 iterations, 21 evaluations (21 valid)'}\n", + "\n", + "============================================================\n", + "ROOT FINDING SOLUTION (from Modelica + Brent)\n", + "============================================================\n", + "Target Range: 100.00 m\n", + "Achieved Range: 100.00 m\n", + "\n", + "Required Angle: 58.553 degrees\n", + "\n", + "✓ Root finding with Brent's method and Modelica completed!\n" + ] + } + ], + "source": [ + "### Step 5.3: Run Root Finding with Brent's Method\n", + "\n", + "# Define root-finding problem\n", + "root_params = {\n", + " 'v0': '45.0', # Fixed velocity\n", + " 'angle': '[20.0; 80.0]', # Search for angle in this range (1D problem)\n", + " 'k': '0.01', # Fixed\n", + " 'm': '1.0' # Fixed\n", + "}\n", + "\n", + "# Define the output expression - we want range - target = 0\n", + "# For Brent's method, we need to find where target_error crosses zero\n", + "# Since target_error = abs(range - 150), we'll use (range - 150) instead\n", + "output_expression = f'res_ProjectileMotion_x[-1] - {target_range}'\n", + "\n", + "print(\"Running root finding with Brent's method and Modelica...\")\n", + "print(f\"Objective: Find angle where range = {target_range}m\")\n", + "print(\"(This will take several minutes due to Modelica simulations)\\n\")\n", + "\n", + "# Run root finding using fzd with Brent's method\n", + "root_result = fz.fzd(\n", + " input_path='ProjectileMotion.mo',\n", + " input_variables=root_params,\n", + " model='Modelica',\n", + " calculators=['localhost']*3, # Use 3 parallel calculators\n", + " algorithm='brent', # Use the installed Brent algorithm\n", + " output_expression=output_expression,\n", + " algorithm_options={\n", + " 'tolerance': 0.01, # Convergence tolerance (m)\n", + " 'max_iterations': 50 # Maximum iterations\n", + " }\n", + ")\n", + "\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"ROOT FINDING RESULTS\")\n", + "print(\"=\" * 60)\n", + "print(f\"\\nAlgorithm: {root_result['algorithm']}\")\n", + "print(f\"Iterations: {root_result['iterations']}\")\n", + "print(f\"Total Evaluations: {root_result['total_evaluations']}\")\n", + "print(f\"\\nSummary:\\n{root_result['summary']}\")\n", + "\n", + "print(root_result)\n", + "\n", + "# Get the solution\n", + "df_root = root_result['XY']\n", + "best_idx = np.abs(df_root[output_expression]).idxmin()\n", + "\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"ROOT FINDING SOLUTION (from Modelica + Brent)\")\n", + "print(\"=\" * 60)\n", + "print(f\"Target Range: {target_range:.2f} m\")\n", + "print(f\"Achieved Range: {target_range + df_root.loc[best_idx, output_expression]:.2f} m\")\n", + "print(f\"\\nRequired Angle: {df_root.loc[best_idx, 'angle']:.3f} degrees\")\n", + "\n", + "print(\"\\n✓ Root finding with Brent's method and Modelica completed!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## Summary\n", + "\n", + "In this notebook, we've demonstrated the complete FZ framework workflow using **OpenModelica** for rigorous differential equation solving and **adaptive algorithms** for optimization and root finding:\n", + "\n", + "### What We Accomplished\n", + "\n", + "1. **✓ Installation** - Installed FZ, fz-modelica, fz-gradientdescent, and fz-brent from GitHub\n", + "2. **✓ Modelica Model** - Downloaded and enhanced Modelica differential equations with air resistance\n", + "3. **✓ Basic Calculations** - Parametric simulations using OpenModelica ODE solvers\n", + "4. **✓ Design of Experiments** - Explored parameter space systematically\n", + "5. **✓ Optimization** - Used **Gradient Descent** algorithm to maximize projectile range\n", + "6. **✓ Root Finding** - Used **Brent's method** to find angle for target range\n", + "\n", + "### Key Features Demonstrated\n", + "\n", + "- **Modelica Integration**: FZ seamlessly works with OpenModelica for rigorous ODE solving\n", + "- **Algorithm Plugins**: Installed optimization and root-finding algorithms from GitHub\n", + " - **fz-gradientdescent**: First-order local optimization (gradient-based)\n", + " - **fz-brent**: 1D root finding (hybrid bisection/secant/quadratic)\n", + "- **Adaptive Design**: Algorithms intelligently sample the parameter space\n", + "- **Same FZ API**: All FZ functions (`fzi`, `fzr`, `fzd`) work identically with any model\n", + "- **Online Resources**: Everything downloaded from GitHub (model, calculator, algorithms)\n", + "\n", + "### Algorithms Used\n", + "\n", + "#### Gradient Descent (Optimization)\n", + "- **Purpose**: Find parameters that minimize/maximize an objective\n", + "- **Method**: Follows the gradient (steepest descent direction)\n", + "- **Best for**: Smooth, differentiable objectives\n", + "- **Efficiency**: Fewer evaluations than grid search (~10-20 vs 100+)\n", + "\n", + "#### Brent's Method (Root Finding)\n", + "- **Purpose**: Find parameter where objective equals target value\n", + "- **Method**: Combines bisection, secant, and inverse quadratic interpolation\n", + "- **Best for**: 1D root-finding problems\n", + "- **Efficiency**: Superlinear convergence, very robust\n", + "\n", + "### Performance Comparison\n", + "\n", + "| Method | Evaluations | Time | Precision |\n", + "|--------|------------|------|-----------|\n", + "| **Grid Search (10×10)** | 100 | ~120s | Low (depends on grid) |\n", + "| **Gradient Descent** | 10-20 | ~30-60s | High (converges to optimum) |\n", + "| **Grid Search (20 angles)** | 20 | ~40s | Low (depends on samples) |\n", + "| **Brent's Method** | 5-10 | ~15-30s | Very High (< 0.01m error) |\n", + "\n", + "**Key Insight**: Adaptive algorithms (Gradient Descent, Brent) are 2-5× more efficient than grid search and achieve better precision!\n", + "\n", + "### When to Use Each Approach\n", + "\n", + "✅ **Use Grid Search when:**\n", + "- Exploring an unknown parameter space\n", + "- You need a complete map of the response surface\n", + "- The objective function is non-smooth or has multiple optima\n", + "\n", + "✅ **Use Gradient Descent when:**\n", + "- Optimizing smooth, differentiable objectives\n", + "- You need to find local optima efficiently\n", + "- Computational budget is limited\n", + "- Working with multiple parameters (2D, 3D, etc.)\n", + "\n", + "✅ **Use Brent's Method when:**\n", + "- Finding roots in 1D problems\n", + "- You need high precision\n", + "- The function is smooth and monotonic (or has known bracketing interval)\n", + "- Robustness is critical\n", + "\n", + "### Online Resources Used\n", + "\n", + "All components downloaded from GitHub:\n", + "- **FZ Framework**: `pip install git+https://github.com/Funz/fz.git`\n", + "- **Modelica Plugin**: `fz.install_model('modelica')` → https://github.com/Funz/fz-modelica\n", + "- **Gradient Descent**: `fz.install_algo('gradientdescent')` → https://github.com/Funz/algorithm-GradientDescent\n", + "- **Brent's Method**: `fz.install_algo('brent')` → https://github.com/Funz/algorithm-Brent\n", + "\n", + "### Next Steps\n", + "\n", + "- Try other algorithms: BFGS, Nelder-Mead, Genetic Algorithms\n", + "- Create your own algorithm plugins (Python or R)\n", + "- Use multi-dimensional optimization (both algorithms support multiple parameters)\n", + "- Combine algorithms: Grid search to explore → Gradient descent to refine\n", + "- Apply to your own Modelica models\n", + "\n", + "### Documentation\n", + "\n", + "- **FZ Documentation**: https://github.com/Funz/fz\n", + "- **Modelica Integration Guide**: `examples/models/MODELICA_README.md`\n", + "- **OpenModelica**: https://openmodelica.org/\n", + "- **Algorithm Development**: `examples/algorithms/` directory\n", + "\n", + "---\n", + "\n", + "**This notebook demonstrates FZ's power in combining professional ODE solvers (OpenModelica) with adaptive algorithms for efficient parameter studies!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/fzd_example.md b/examples/fzd_example.md new file mode 100644 index 0000000..904f470 --- /dev/null +++ b/examples/fzd_example.md @@ -0,0 +1,488 @@ +# FZD - Iterative Design of Experiments Examples + +This guide demonstrates how to use `fzd()` with different algorithms for iterative design of experiments and optimization. + +## Overview + +The `fzd()` function enables **adaptive sampling** where algorithms intelligently choose which points to evaluate next based on previous results. This is much more efficient than grid search for optimization and root-finding problems. + +## Prerequisites + +**Required:** +- Python 3.7+ +- FZ framework: `pip install git+https://github.com/Funz/fz.git` +- `bc` calculator: + - Debian/Ubuntu: `sudo apt install bc` + - macOS: `brew install bc` + +**Optional algorithms** (installed as needed): +- `randomsampling.py` - Simple random sampling +- `brent.py` - 1D optimization (Brent's method) +- `bfgs.py` - Multi-dimensional optimization (BFGS method) + +## Test Model + +All examples use a simple mathematical model to demonstrate the concepts: + +**Model:** Computes `x² + y²` (distance from origin) +- **Minimum:** at (0, 0) with value 0 +- **Variables:** x and y in range [-2, 2] + +### Model Definition + +```python +model = { + "varprefix": "$", + "delim": "()", + "run": "bash -c 'source input.txt && result=$(echo \"scale=6; $x * $x + $y * $y\" | bc) && echo \"result = $result\" > output.txt'", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2 | tr -d ' '" + } +} +``` + +--- + +## Example 1: Random Sampling + +Explores the parameter space using random sampling. Good for: +- Initial exploration +- Understanding the response surface +- Baseline for comparison with optimization algorithms + +### Code + +```python +import fz + +# Run fzd with random sampling algorithm +result = fz.fzd( + input_path="input/", + input_variables={"x": "[-2;2]", "y": "[-2;2]"}, + model=model, + output_expression="result", + algorithm="examples/algorithms/randomsampling.py", + algorithm_options={"nvalues": 10, "seed": 42} +) + +print(f"Algorithm: {result['algorithm']}") +print(f"Total evaluations: {result['total_evaluations']}") +print(f"Summary: {result['summary']}") + +# Find best result +df = result['XY'] +best_idx = df['result'].idxmin() +print(f"\nBest result found:") +print(f" x = {df.loc[best_idx, 'x']:.6f}") +print(f" y = {df.loc[best_idx, 'y']:.6f}") +print(f" result = {df.loc[best_idx, 'result']:.6f}") +``` + +### Key Parameters + +- **`nvalues`**: Number of random samples to evaluate +- **`seed`**: Random seed for reproducibility + +### Expected Output + +``` +Algorithm: examples/algorithms/randomsampling.py +Total evaluations: 10 + +Best result found: + x = -0.123456 + y = 0.234567 + result = 0.070123 +``` + +--- + +## Example 2: Brent's Method (1D Optimization) + +Uses Brent's method to find the minimum of a 1D function. This is a **root-finding algorithm** adapted for optimization. + +**Problem:** Find minimum of `(x - 0.7)²` +- **Expected minimum:** x = 0.7, output ≈ 0 + +### Code + +```python +import fz + +# Modified model for 1D problem: (x - 0.7)^2 +model_1d = { + "varprefix": "$", + "delim": "()", + "run": "bash -c 'source input.txt && result=$(echo \"scale=6; ($x - 0.7) * ($x - 0.7)\" | bc) && echo \"result = $result\" > output.txt'", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2 | tr -d ' '" + } +} + +# Run fzd with Brent's method +result = fz.fzd( + input_path="input/", + input_variables={"x": "[0;2]"}, # Only x variable (1D) + model=model_1d, + output_expression="result", + algorithm="examples/algorithms/brent.py", + algorithm_options={"max_iter": 20, "tol": 1e-3} +) + +print(f"Iterations: {result['iterations']}") +print(f"Total evaluations: {result['total_evaluations']}") + +# Get optimal result +df = result['XY'] +best_idx = df['result'].idxmin() +print(f"\nOptimal result:") +print(f" x = {df.loc[best_idx, 'x']:.6f} (expected: 0.7)") +print(f" result = {df.loc[best_idx, 'result']:.6f} (expected: ~0.0)") +``` + +### Key Parameters + +- **`max_iter`**: Maximum number of iterations +- **`tol`**: Convergence tolerance + +### Algorithm Characteristics + +- **Type:** 1D root finding/optimization +- **Method:** Combines bisection, secant, and inverse quadratic interpolation +- **Convergence:** Superlinear +- **Robustness:** Very robust, guaranteed to converge +- **Evaluations:** Typically 5-15 for good precision + +### Expected Output + +``` +Iterations: 12 +Total evaluations: 12 + +Optimal result: + x = 0.700023 (expected: 0.7) + result = 0.000001 (expected: ~0.0) +``` + +--- + +## Example 3: BFGS (Multi-dimensional Optimization) + +Uses BFGS (Broyden-Fletcher-Goldfarb-Shanno) for multi-dimensional optimization. This is a **quasi-Newton method** that approximates the Hessian matrix. + +**Problem:** Find minimum of `x² + y²` +- **Expected minimum:** (0, 0) with output = 0 + +### Code + +```python +import fz + +# Run fzd with BFGS algorithm +result = fz.fzd( + input_path="input/", + input_variables={"x": "[-2;2]", "y": "[-2;2]"}, + model=model, + output_expression="result", + algorithm="examples/algorithms/bfgs.py", + algorithm_options={"max_iter": 20, "tol": 1e-4} +) + +print(f"Algorithm: {result['algorithm']}") +print(f"Iterations: {result['iterations']}") +print(f"Total evaluations: {result['total_evaluations']}") + +# Get optimal result +df = result['XY'] +best_idx = df['result'].idxmin() +print(f"\nOptimal result:") +print(f" x = {df.loc[best_idx, 'x']:.6f} (expected: 0.0)") +print(f" y = {df.loc[best_idx, 'y']:.6f} (expected: 0.0)") +print(f" result = {df.loc[best_idx, 'result']:.6f} (expected: ~0.0)") +``` + +### Key Parameters + +- **`max_iter`**: Maximum number of iterations +- **`tol`**: Convergence tolerance for gradient norm + +### Algorithm Characteristics + +- **Type:** Multi-dimensional gradient-based optimization +- **Method:** Quasi-Newton (approximates second derivatives) +- **Convergence:** Superlinear +- **Best for:** Smooth, differentiable functions +- **Evaluations:** Typically 10-30 for good precision +- **Scales:** Works well for 2-50 dimensions + +### Expected Output + +``` +Iterations: 8 +Total evaluations: 18 + +Optimal result: + x = 0.000012 (expected: 0.0) + y = -0.000008 (expected: 0.0) + result = 0.000000 (expected: ~0.0) +``` + +--- + +## Example 4: Custom Output Expression + +Demonstrates using mathematical expressions to combine multiple model outputs. + +**Model outputs:** +- `r1 = x²` +- `r2 = y²` + +**Output expression:** `r1 + r2 * 2` (minimize x² + 2y²) + +### Code + +```python +import fz + +# Model with two separate outputs +model_multi = { + "varprefix": "$", + "delim": "()", + "run": "bash -c 'source input.txt && r1=$(echo \"scale=6; $x * $x\" | bc) && r2=$(echo \"scale=6; $y * $y\" | bc) && echo \"r1 = $r1\" > output.txt && echo \"r2 = $r2\" >> output.txt'", + "output": { + "r1": "grep 'r1 = ' output.txt | cut -d '=' -f2 | tr -d ' '", + "r2": "grep 'r2 = ' output.txt | cut -d '=' -f2 | tr -d ' '" + } +} + +# Run fzd with custom expression combining r1 and r2 +result = fz.fzd( + input_path="input/", + input_variables={"x": "[-2;2]", "y": "[-2;2]"}, + model=model_multi, + output_expression="r1 + r2 * 2", # Custom expression + algorithm="examples/algorithms/randomsampling.py", + algorithm_options={"nvalues": 10, "seed": 42} +) + +print(f"Output expression: r1 + r2 * 2") +print(f"Total evaluations: {result['total_evaluations']}") + +# Get best result +df = result['XY'] +best_idx = df['r1 + r2 * 2'].idxmin() +print(f"\nBest result:") +print(f" x = {df.loc[best_idx, 'x']:.6f}") +print(f" y = {df.loc[best_idx, 'y']:.6f}") +print(f" r1 = {df.loc[best_idx, 'r1']:.6f}") +print(f" r2 = {df.loc[best_idx, 'r2']:.6f}") +print(f" r1 + r2 * 2 = {df.loc[best_idx, 'r1 + r2 * 2']:.6f}") +``` + +### Available Expression Operators + +The output expression supports: +- **Arithmetic:** `+`, `-`, `*`, `/`, `**` (power) +- **Functions:** `abs()`, `min()`, `max()`, `sqrt()`, `exp()`, `log()`, etc. +- **Math constants:** `pi`, `e` +- **Model outputs:** Any variable from `model["output"]` + +### Example Expressions + +```python +# Simple sum +output_expression = "output1 + output2" + +# Weighted sum +output_expression = "0.7 * pressure + 0.3 * temperature" + +# Constraint violation penalty +output_expression = "cost + 1000 * max(0, temperature - 100)" + +# Root mean square +output_expression = "sqrt((x1**2 + x2**2 + x3**2) / 3)" + +# Array indexing (for trajectory data) +output_expression = "res_x[-1]" # Last element +``` + +--- + +## Complete Running Example + +Here's a complete, self-contained example you can run: + +```python +#!/usr/bin/env python3 +"""Complete fzd example""" + +import fz +import tempfile +import shutil +from pathlib import Path + +# Create temporary directory +tmpdir = Path(tempfile.mkdtemp()) + +try: + # Create input directory + input_dir = tmpdir / "input" + input_dir.mkdir() + + # Create input file + (input_dir / "input.txt").write_text("x = $x\ny = $y\n") + + # Define model + model = { + "varprefix": "$", + "delim": "()", + "run": "bash -c 'source input.txt && result=$(echo \"scale=6; $x * $x + $y * $y\" | bc) && echo \"result = $result\" > output.txt'", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2 | tr -d ' '" + } + } + + # Run optimization + result = fz.fzd( + input_path=str(input_dir), + input_variables={"x": "[-2;2]", "y": "[-2;2]"}, + model=model, + output_expression="result", + algorithm="examples/algorithms/randomsampling.py", + algorithm_options={"nvalues": 10, "seed": 42} + ) + + # Display results + print(f"Total evaluations: {result['total_evaluations']}") + df = result['XY'] + best_idx = df['result'].idxmin() + print(f"Best: x={df.loc[best_idx, 'x']:.4f}, y={df.loc[best_idx, 'y']:.4f}, result={df.loc[best_idx, 'result']:.6f}") + +finally: + shutil.rmtree(tmpdir) +``` + +--- + +## Algorithm Comparison + +| Algorithm | Type | Dimensions | Evaluations | Best For | +|-----------|------|------------|-------------|----------| +| **Random Sampling** | Exploration | Any | High (10-100+) | Exploration, baselines | +| **Brent** | Optimization | 1D only | Low (5-15) | 1D root finding, precise 1D optim | +| **BFGS** | Optimization | 2-50 | Medium (10-30) | Smooth multi-D optimization | +| **Gradient Descent** | Optimization | Any | Medium (10-50) | Large-scale, simple implementation | +| **Monte Carlo** | Integration | Any | High (100-10000) | Uncertainty quantification | + +--- + +## Tips and Best Practices + +### 1. Choose the Right Algorithm + +- **1D problems:** Use Brent's method +- **2-10D smooth problems:** Use BFGS +- **10-50D smooth problems:** Use gradient descent +- **Non-smooth or exploratory:** Use random sampling +- **Global optimization:** Combine random sampling → local optimization + +### 2. Set Appropriate Tolerances + +```python +# High precision (more evaluations) +algorithm_options={"tol": 1e-6, "max_iter": 100} + +# Fast exploration (fewer evaluations) +algorithm_options={"tol": 1e-2, "max_iter": 20} +``` + +### 3. Use Fixed Variables + +```python +# Optimize angle, keep velocity fixed +input_variables={ + "angle": "[20;80]", # Variable (search range) + "velocity": "45.0" # Fixed value +} +``` + +### 4. Monitor Progress + +All algorithms support `get_analysis_tmp()` for intermediate results: + +```python +# Results saved after each iteration +# Check: analysis_dir/results_1.html, results_2.html, etc. +``` + +### 5. Combine Approaches + +```python +# 1. Explore with random sampling +explore = fz.fzd(..., algorithm="randomsampling", nvalues=20) + +# 2. Refine with BFGS starting near best point +# Use best result from exploration as initial guess +refine = fz.fzd(..., algorithm="bfgs", x0=best_from_explore) +``` + +--- + +## Troubleshooting + +### Issue: Algorithm not found + +```python +# ✗ Wrong +algorithm="bfgs" # Looks for installed plugin + +# ✓ Correct +algorithm="examples/algorithms/bfgs.py" # Full path +``` + +### Issue: Output expression fails + +Check available variables and use proper syntax: + +```python +# See what's available +print(result['XY'].columns) + +# Use correct variable names +output_expression="pressure" # Must match model output key +``` + +### Issue: Slow convergence + +Try adjusting algorithm parameters: + +```python +# Increase step size (gradient descent) +algorithm_options={"step_size": 2.0} + +# Relax tolerance +algorithm_options={"tol": 1e-3} +``` + +--- + +## See Also + +- **FZ Documentation:** https://github.com/Funz/fz +- **Algorithm Development:** See `examples/algorithms/` for templates +- **Modelica Integration:** See `examples/fz_modelica_projectile.ipynb` +- **API Reference:** Run `python -c "import fz; help(fz.fzd)"` + +--- + +## Summary + +The `fzd()` function provides a unified interface for iterative design of experiments: + +1. **Define your problem:** Input variables, model, output expression +2. **Choose an algorithm:** Based on problem type and dimensionality +3. **Set options:** Tolerance, iterations, algorithm-specific parameters +4. **Run optimization:** `fz.fzd()` handles the iterative sampling +5. **Analyze results:** DataFrame with all evaluations + algorithm analysis + +**Key advantage:** Adaptive algorithms are 2-10× more efficient than grid search while achieving better precision! diff --git a/examples/variable_substitution.md b/examples/variable_substitution.md deleted file mode 100644 index c567ea9..0000000 --- a/examples/variable_substitution.md +++ /dev/null @@ -1,359 +0,0 @@ -# Variable Substitution in FZ - -This document explains how variable substitution works in the FZ package, including the new default value syntax. - -## Basic Syntax - -Variables in template files are replaced using a prefix (default `$`) and optional delimiters: - -### Simple Variables - -``` -Name: $name -Version: $version -``` - -### Delimited Variables - -Use delimiters `{}` when the variable name is followed by alphanumeric characters: - -``` -File: ${name}_config.txt -Path: /home/${user}/documents -``` - -## Default Values (v0.9.1+) - -You can specify default values that will be used when a variable is not provided. - -### Syntax - -``` -${variable~default_value} -``` - -- Variable name: `variable` -- Separator: `~` (tilde) -- Default value: `default_value` - -### Examples - -```python -from fz.interpreter import replace_variables_in_content - -content = """ -Application Configuration: - name: ${app_name~MyApplication} - host: ${host~localhost} - port: ${port~8080} - debug: ${debug~false} - max_connections: ${max_conn~100} -""" - -# Only provide some variables -input_variables = { - "app_name": "ProductionApp", - "host": "example.com" -} - -result = replace_variables_in_content(content, input_variables) -``` - -**Output:** -``` -Application Configuration: - name: ProductionApp - host: example.com - port: 8080 - debug: false - max_connections: 100 -``` - -**Warnings printed:** -``` -Warning: Variable 'port' not found in input_variables, using default value: '8080' -Warning: Variable 'debug' not found in input_variables, using default value: 'false' -Warning: Variable 'max_conn' not found in input_variables, using default value: '100' -``` - -## Behavior Rules - -### 1. Variable Provided - -When a variable is provided in `input_variables`, its value is used regardless of any default: - -```python -content = "Port: ${port~8080}" -input_variables = {"port": 3000} -# Result: "Port: 3000" -# No warning -``` - -### 2. Variable Not Provided, Has Default - -When a variable is not provided but has a default value, the default is used and a warning is printed: - -```python -content = "Port: ${port~8080}" -input_variables = {} -# Result: "Port: 8080" -# Warning: Variable 'port' not found in input_variables, using default value: '8080' -``` - -### 3. Variable Not Provided, No Default - -When a variable is not provided and has no default, it remains unchanged: - -```python -content = "Port: ${port}" -input_variables = {} -# Result: "Port: ${port}" -# No warning -``` - -## Use Cases - -### Configuration Templates - -Create configuration files with sensible defaults: - -```yaml -# config.yaml.template -server: - host: ${SERVER_HOST~0.0.0.0} - port: ${SERVER_PORT~8080} - workers: ${WORKERS~4} - -database: - url: ${DATABASE_URL~sqlite:///./app.db} - pool_size: ${DB_POOL~5} - -logging: - level: ${LOG_LEVEL~INFO} - file: ${LOG_FILE~/var/log/app.log} -``` - -### Environment-Specific Deployments - -Different defaults for different environments: - -```python -# Development -dev_vars = {"host": "localhost", "debug": "true"} - -# Production -prod_vars = {"host": "production.example.com", "workers": "8"} - -# Both use same template with defaults -template = """ -Host: ${host~0.0.0.0} -Port: ${port~8080} -Debug: ${debug~false} -Workers: ${workers~4} -""" -``` - -### Parametric Studies with Optional Parameters - -```python -from fz import fzi - -# Some variables have defaults in the template -results = fzi( - input_path="simulation.template", - input_variables={ - "temperature": [100, 200, 300], # Required - # pressure uses default from template - # time_step uses default from template - }, - output_expression="max_temp" -) -``` - -## Default Value Types - -### Numeric Values - -``` -Threads: ${threads~4} -Timeout: ${timeout~30.5} -``` - -### String Values - -``` -Name: ${name~MyApp} -Message: ${msg~Hello World} -Path: ${path~/usr/local/bin} -``` - -### Boolean-like Values - -``` -Debug: ${debug~false} -Enabled: ${enabled~true} -``` - -### URLs and Paths - -``` -API: ${api_url~http://localhost:8080/api} -Config: ${config_path~./config/default.json} -``` - -### Empty Strings - -Use empty default to make variable optional: - -``` -Suffix: ${suffix~} -Optional: ${opt~} -``` - -## Advanced Usage - -### With Formulas - -Default values work alongside formula evaluation: - -``` -# Template -Port: ${port~8080} -URL: http://localhost:@{$port}/api - -# Python code -content = replace_variables_in_content(template, {"port": 3000}) -result = evaluate_formulas(content, model, {"port": 3000}) -# Result: "Port: 3000" and "URL: http://localhost:3000/api" -``` - -### Parsing Variables - -The `parse_variables_from_content` function extracts variable names, ignoring defaults: - -```python -from fz.interpreter import parse_variables_from_content - -content = "${var1~default1}, ${var2}, ${var3~default3}" -variables = parse_variables_from_content(content) -# Returns: {"var1", "var2", "var3"} -``` - -## Limitations - -### Tilde in Default Values - -If your default value contains a tilde `~`, only the part before the first `~` in the variable definition is treated as the variable name: - -``` -# This may not work as expected: -${path~~~home/user} # Variable: path, Default: ~home/user -``` - -### Braces in Default Values - -If your default value contains the closing delimiter `}`, it will prematurely close the variable pattern: - -``` -# Problematic: -${json~{key: value}} # Will only capture up to first } -``` - -## Migration from Earlier Versions - -If you're upgrading from an earlier version of FZ: - -### Before (v0.9.0 and earlier) - -All variables had to be provided, or they would remain as placeholders: - -```python -content = "Port: ${port}" -input_variables = {} -# Result: "Port: ${port}" -``` - -### After (v0.9.1+) - -You can now specify defaults: - -```python -content = "Port: ${port~8080}" -input_variables = {} -# Result: "Port: 8080" -# Warning: Variable 'port' not found in input_variables, using default value: '8080' -``` - -### Backward Compatibility - -The old syntax still works exactly as before. Default values are opt-in: - -- `$var` - Simple variable (unchanged) -- `${var}` - Delimited variable (unchanged) -- `${var~default}` - New: variable with default - -## Best Practices - -1. **Use descriptive default values** that make sense in a development/testing context -2. **Document your template variables** and their defaults -3. **Keep defaults simple** - avoid complex expressions or special characters -4. **Use defaults for optional configuration** but require critical parameters -5. **Review warnings** - they indicate which variables are using defaults - -## Examples - -### Docker Configuration - -```dockerfile -# Dockerfile.template -FROM ${BASE_IMAGE~python:3.11-slim} - -ENV APP_HOME=${APP_HOME~/app} -ENV PORT=${PORT~8080} -ENV WORKERS=${WORKERS~4} - -WORKDIR $APP_HOME -COPY . . - -CMD gunicorn -w $WORKERS -b 0.0.0.0:$PORT app:app -``` - -### Kubernetes ConfigMap - -```yaml -# configmap.yaml.template -apiVersion: v1 -kind: ConfigMap -metadata: - name: ${APP_NAME~myapp}-config -data: - database.url: ${DATABASE_URL~postgresql://localhost:5432/mydb} - cache.ttl: "${CACHE_TTL~3600}" - log.level: ${LOG_LEVEL~INFO} - feature.beta: "${FEATURE_BETA~false}" -``` - -### Scientific Simulation - -``` -# simulation.template -Simulation Parameters: - particles: $n_particles - time_steps: ${time_steps~1000} - dt: ${dt~0.001} - temperature: ${temp~300.0} - pressure: ${pressure~1.0} - output_freq: ${output_freq~100} -``` - -## Summary - -Default values provide a powerful way to create flexible, reusable templates with sensible fallback values. They're especially useful for: - -- Configuration management -- Environment-specific deployments -- Optional parameters in parametric studies -- Template files with development defaults -- Reducing the number of required variables - -The syntax is simple: `${variable~default}`, and the behavior is predictable: use the provided value if available, otherwise use the default and warn. diff --git a/fz/__init__.py b/fz/__init__.py index 891c875..ee7d36e 100644 --- a/fz/__init__.py +++ b/fz/__init__.py @@ -10,7 +10,7 @@ - Smart caching and retry mechanisms """ -from .core import fzi, fzc, fzo, fzr, check_bash_availability_on_windows +from .core import fzi, fzc, fzo, fzr, fzd, check_bash_availability_on_windows # Check bash availability on Windows at import time # This ensures users get immediate feedback if bash is not available @@ -30,68 +30,16 @@ install_model, uninstall_model, list_installed_models, + install_algorithm, + uninstall_algorithm, + list_installed_algorithms, ) - -def install(model, global_install=False): - """ - Install a model from a source (GitHub name, URL, or local zip file) - - Args: - model: Model source to install (GitHub name, URL, or local zip file) - global_install: If True, install to ~/.fz/models/, else ./.fz/models/ - - Returns: - Installation result dict with 'model_name' and 'install_path' keys - - Examples: - >>> install(model='moret') - >>> install(model='https://github.com/Funz/fz-moret') - >>> install(model='fz-moret.zip') - >>> install(model='moret', global_install=True) - """ - return install_model(model, global_install=global_install) - - -def uninstall(model, global_uninstall=False): - """ - Uninstall a model - - Args: - model: Name of the model to uninstall - global_uninstall: If True, uninstall from ~/.fz/models/, else from ./.fz/models/ - - Returns: - True if successful, False otherwise - - Examples: - >>> uninstall(model='moret') - >>> uninstall(model='moret', global_uninstall=True) - """ - return uninstall_model(model, global_uninstall=global_uninstall) - - -def list_models(global_list=False): - """ - List installed models - - Args: - global_list: If True, list from ~/.fz/models/, else from ./.fz/models/ - - Returns: - Dict mapping model names to their definitions - - Examples: - >>> list_models() - >>> list_models(global_list=True) - """ - return list_installed_models(global_list=global_list) - - __version__ = "0.9.0" __all__ = [ - "fzi", "fzc", "fzo", "fzr", - "install", "uninstall", "list_models", + "fzi", "fzc", "fzo", "fzr", "fzd", + "install_model", "uninstall_model", "list_installed_models", + "install_algorithm", "uninstall_algorithm", "list_installed_algorithms", "set_log_level", "get_log_level", "get_config", "reload_config", "print_config", "set_interpreter", "get_interpreter", diff --git a/fz/algorithms.py b/fz/algorithms.py new file mode 100644 index 0000000..80a94a1 --- /dev/null +++ b/fz/algorithms.py @@ -0,0 +1,989 @@ +""" +Algorithm framework for iterative design of experiments (fzd) + +This module provides the base interface and utilities for algorithms used with fzd. + +Algorithm Interface: +------------------- +Each algorithm must be a class with the following methods: + +1. __init__(self, **options): + Constructor that accepts algorithm-specific options + +2. get_initial_design(self, input_vars, output_vars): + Returns initial design of experiments + Args: + input_vars: Dict[str, tuple] - {var_name: (min, max)} + e.g., {"x": (0.0, 1.0), "y": (-5.0, 5.0)} + output_vars: List[str] - List of output variable names + Returns: + List[Dict[str, float]] - List of input variable combinations to evaluate + e.g., [{"x": 0.5, "y": 0.0}, {"x": 0.7, "y": 2.3}] + +3. get_next_design(self, previous_input_vars, previous_output_values): + Returns next design of experiments based on previous results + Args: + previous_input_vars: List[Dict[str, float]] - Previous input combinations + e.g., [{"x": 0.5, "y": 0.0}, {"x": 0.7, "y": 2.3}] + previous_output_values: List[float] - Corresponding output values (may contain None) + e.g., [1.5, None, 2.3, 0.8] + Returns: + List[Dict[str, float]] - Next input variable combinations to evaluate + Returns empty list [] when algorithm is finished + + Note: While the interface uses Python lists, algorithms can convert to numpy arrays + internally for numerical computation. Output values may contain None for failed + evaluations, so filter these out before numerical operations. + +4. get_analysis(self, input_vars, output_values): + Returns results to analysis + Args: + input_vars: List[Dict[str, float]] - All evaluated input combinations + output_values: List[float] - All corresponding output values (may contain None) + Returns: + Dict with analysis information (can include 'text', 'data', 'plot', etc.) + + Note: Should handle None values in output_values (failed evaluations) + +5. get_analysis_tmp(self, input_vars, output_values): [OPTIONAL] + Display intermediate results at each iteration + Args: + input_vars: List[Dict[str, float]] - All evaluated inputs so far + output_values: List[float] - All outputs so far (may contain None) + Returns: + Dict with analysis information (typically 'text' and 'data' keys) + + Note: This method is optional. If present, it will be called after each iteration + to show progress. If not present, no intermediate results are displayed. +""" + +import re +import importlib +import importlib.util +import sys +import subprocess +import inspect +from pathlib import Path +from typing import Dict, List, Tuple, Any, Optional +import logging + + +def parse_input_vars(input_vars: Dict[str, str]) -> Dict[str, Tuple[float, float]]: + """ + Parse input variable ranges from string descriptions + + Supports two formats: + - Range (variable): "[min;max]" or "[min,max]" - will be varied by algorithm + - Fixed (unique): single numeric value - will NOT be varied by algorithm + + Args: + input_vars: Dict of {var_name: "[min;max]"} or {var_name: "value"} + + Returns: + Dict of {var_name: (min, max)} for range variables only + + Examples: + >>> parse_input_vars({"x": "[0;1]", "y": "[-5.5;5.5]"}) + {'x': (0.0, 1.0), 'y': (-5.5, 5.5)} + + >>> parse_input_vars({"x": "[0;1]", "z": "0.5"}) # z is fixed + {'x': (0.0, 1.0)} + """ + parsed = {} + + for var_name, range_str in input_vars.items(): + # Check if it's a range format [min;max] or [min,max] + match = re.match(r'\[([^;,]+)[;,]([^;,]+)\]', range_str.strip()) + + if match: + # It's a range - parse it + try: + min_val = float(match.group(1).strip()) + max_val = float(match.group(2).strip()) + except ValueError as e: + raise ValueError( + f"Invalid numeric values in range for variable '{var_name}': '{range_str}'" + ) from e + + if min_val >= max_val: + raise ValueError( + f"Invalid range for variable '{var_name}': min ({min_val}) must be < max ({max_val})" + ) + + parsed[var_name] = (min_val, max_val) + else: + # It's a fixed value - skip it (will be handled by parse_fixed_vars) + # Try to validate it's a number + try: + float(range_str.strip()) + except ValueError: + raise ValueError( + f"Invalid format for variable '{var_name}': '{range_str}'. " + f"Expected '[min;max]' for range or numeric value for fixed variable" + ) + + return parsed + + +def parse_fixed_vars(input_vars: Dict[str, str]) -> Dict[str, float]: + """ + Parse fixed (unique) input variables from string descriptions + + Fixed variables have single numeric values and will NOT be varied by the algorithm. + + Args: + input_vars: Dict of {var_name: "value"} + + Returns: + Dict of {var_name: value} for fixed variables only + + Examples: + >>> parse_fixed_vars({"x": "[0;1]", "z": "0.5"}) + {'z': 0.5} + """ + fixed = {} + + for var_name, value_str in input_vars.items(): + # Check if it's NOT a range format + if not re.match(r'\[([^;,]+)[;,]([^;,]+)\]', value_str.strip()): + try: + fixed[var_name] = float(value_str.strip()) + except ValueError as e: + raise ValueError( + f"Invalid numeric value for fixed variable '{var_name}': '{value_str}'" + ) from e + + return fixed + + +def evaluate_output_expression( + expression: str, + output_data: Dict[str, Any] +) -> float: + """ + Evaluate mathematical expression using output variables + + Args: + expression: Mathematical expression like "output1 + output2 * 2" + output_data: Dict of output variable values + + Returns: + Evaluated numeric result + + Examples: + >>> evaluate_output_expression("x + y * 2", {"x": 1.0, "y": 3.0}) + 7.0 + """ + try: + # Create a safe evaluation environment with only the output variables + # and math functions + import math + safe_dict = { + # Math functions + 'abs': abs, + 'min': min, + 'max': max, + 'pow': pow, + 'sqrt': math.sqrt, + 'exp': math.exp, + 'log': math.log, + 'log10': math.log10, + 'sin': math.sin, + 'cos': math.cos, + 'tan': math.tan, + 'asin': math.asin, + 'acos': math.acos, + 'atan': math.atan, + 'atan2': math.atan2, + 'pi': math.pi, + 'e': math.e, + } + + # Add output variables + safe_dict.update(output_data) + + # Evaluate the expression + result = eval(expression, {"__builtins__": {}}, safe_dict) + + return float(result) + + except Exception as e: + raise ValueError( + f"Failed to evaluate output expression '{expression}' with data {output_data}: {e}" + ) from e + + +def _is_algorithm_class(obj) -> bool: + """ + Check if an object is a valid algorithm class + + Args: + obj: Object to check + + Returns: + True if obj is a class with required algorithm methods + """ + if not inspect.isclass(obj): + return False + + # Check for required methods + required_methods = ['get_initial_design', 'get_next_design', 'get_analysis'] + for method_name in required_methods: + if not hasattr(obj, method_name): + return False + + return True + + +def _parse_algorithm_metadata(file_path: Path) -> Dict[str, Any]: + """ + Parse metadata from algorithm file comments + + Looks for comments like: + #title: Algorithm title + #author: Author name + #type: algorithm type + #options: key1=value1;key2=value2 + #require: package1;package2;package3 + + Args: + file_path: Path to algorithm file + + Returns: + Dict with parsed metadata + """ + metadata = {} + + try: + with open(file_path, 'r') as f: + for line in f: + line = line.strip() + + # Stop at first non-comment line + if line and not line.startswith('#'): + break + + # Parse metadata lines + if line.startswith('#'): + # Remove leading # and split on first : + content = line[1:].strip() + if ':' in content: + key, value = content.split(':', 1) + key = key.strip() + value = value.strip() + + # Store metadata + if key == 'options': + # Parse options as key=value pairs separated by semicolons + options_dict = {} + for opt in value.split(';'): + if '=' in opt: + opt_key, opt_val = opt.split('=', 1) + options_dict[opt_key.strip()] = opt_val.strip() + metadata[key] = options_dict + elif key == 'require': + # Parse requirements as semicolon-separated list + metadata[key] = [pkg.strip() for pkg in value.split(';')] + else: + metadata[key] = value + except Exception as e: + logging.warning(f"Failed to parse metadata from {file_path}: {e}") + + return metadata + + +def _load_algorithm_from_file(file_path: Path, **options): + """ + Load algorithm class from a Python file + + Args: + file_path: Path to Python file containing algorithm class + **options: Options to pass to algorithm constructor + + Returns: + Algorithm instance + + Raises: + ValueError: If no valid algorithm class is found in the file + """ + # Parse metadata from file + metadata = _parse_algorithm_metadata(file_path) + + # Check and install required packages if specified + if 'require' in metadata: + for package in metadata['require']: + try: + importlib.import_module(package) + logging.info(f"✓ Package '{package}' is available") + except ImportError: + logging.info(f"⚠️ Package '{package}' not found - attempting to install...") + try: + # Install the package using pip + subprocess.check_call( + [sys.executable, "-m", "pip", "install", package], + stdout=subprocess.DEVNULL, + stderr=subprocess.PIPE + ) + logging.info(f"✓ Successfully installed '{package}'") + + # Verify the installation + try: + importlib.import_module(package) + except ImportError: + logging.warning( + f"Package '{package}' was installed but could not be imported. " + f"You may need to restart your Python session." + ) + except subprocess.CalledProcessError as e: + error_msg = e.stderr.decode('utf-8') if e.stderr else '' + raise RuntimeError( + f"Failed to install required package '{package}'. " + f"Please install it manually with: pip install {package}\n" + f"Error: {error_msg}" + ) from e + except Exception as e: + raise RuntimeError( + f"Unexpected error while installing package '{package}': {e}\n" + f"Please install it manually with: pip install {package}" + ) from e + + # Merge metadata options with passed options (passed options take precedence) + if 'options' in metadata: + merged_options = metadata['options'].copy() + merged_options.update(options) + options = merged_options + + # Load the Python module from file + module_name = file_path.stem + spec = importlib.util.spec_from_file_location(module_name, file_path) + + if spec is None or spec.loader is None: + raise ValueError(f"Failed to load module from {file_path}") + + module = importlib.util.module_from_spec(spec) + + # Add to sys.modules to allow imports within the module + sys.modules[module_name] = module + + try: + spec.loader.exec_module(module) + except Exception as e: + # Clean up sys.modules on failure + if module_name in sys.modules: + del sys.modules[module_name] + raise ValueError(f"Failed to execute module from {file_path}: {e}") from e + + # Find algorithm classes in the module + algorithm_classes = [] + for name, obj in inspect.getmembers(module): + if _is_algorithm_class(obj): + algorithm_classes.append((name, obj)) + + if not algorithm_classes: + raise ValueError( + f"No valid algorithm class found in {file_path}. " + f"Algorithm class must have methods: get_initial_design, get_next_design, get_analysis" + ) + + # If multiple classes found, prefer one that's not BaseAlgorithm + if len(algorithm_classes) > 1: + algorithm_classes = [(n, c) for n, c in algorithm_classes if n != 'BaseAlgorithm'] + + if not algorithm_classes: + raise ValueError(f"No valid algorithm class found in {file_path} (only BaseAlgorithm found)") + + # Use the first (or only) algorithm class + algorithm_name, algorithm_class = algorithm_classes[0] + + logging.info(f"Loaded algorithm class '{algorithm_name}' from {file_path}") + if metadata: + logging.info(f"Algorithm metadata: {metadata}") + + # Create and return instance + return algorithm_class(**options) + + +class RAlgorithmWrapper: + """ + Python wrapper for R algorithms loaded via rpy2 + + This class wraps an R algorithm instance and exposes its methods as Python methods, + handling data conversion between Python and R. + """ + + def __init__(self, r_instance, r_globals): + """ + Initialize wrapper with R instance + + Args: + r_instance: R algorithm instance from rpy2 + r_globals: R global environment containing generic functions + """ + self.r_instance = r_instance + self.r_globals = r_globals + + def get_initial_design(self, input_vars: Dict[str, Tuple[float, float]], output_vars: List[str]) -> List[Dict[str, float]]: + """ + Call R's get_initial_design method and convert result to Python + + Args: + input_vars: Dict of {var_name: (min, max)} + output_vars: List of output variable names + + Returns: + List of input variable combinations (Python dicts) + """ + try: + from rpy2 import robjects + from rpy2.robjects import vectors + except ImportError: + raise ImportError("rpy2 is required to use R algorithms. Install with: pip install rpy2") + + # Convert input_vars to R format: named list with c(min, max) vectors + r_input_vars = robjects.ListVector({ + var: vectors.FloatVector([bounds[0], bounds[1]]) + for var, bounds in input_vars.items() + }) + + # Convert output_vars to R character vector + r_output_vars = vectors.StrVector(output_vars) + + # Call R method + r_result = self.r_globals['get_initial_design'](self.r_instance, r_input_vars, r_output_vars) + + # Convert R list of lists to Python list of dicts + return self._r_design_to_python(r_result) + + def get_next_design(self, X: List[Dict[str, float]], Y: List[float]) -> List[Dict[str, float]]: + """ + Call R's get_next_design method and convert result to Python + + Args: + X: Previous input combinations (list of dicts) + Y: Previous output values (list of floats, may contain None) + + Returns: + Next input variable combinations (Python dicts), or empty list if finished + """ + try: + from rpy2 import robjects + except ImportError: + raise ImportError("rpy2 is required to use R algorithms. Install with: pip install rpy2") + + # Convert X and Y to R format + r_X = self._python_design_to_r(X) + r_Y = self._python_outputs_to_r(Y) + + # Call R method + r_result = self.r_globals['get_next_design'](self.r_instance, r_X, r_Y) + + # Convert result to Python + return self._r_design_to_python(r_result) + + def get_analysis(self, X: List[Dict[str, float]], Y: List[float]) -> Dict[str, Any]: + """ + Call R's get_analysis method and convert result to Python + + Args: + X: All evaluated input combinations + Y: All output values (may contain None) + + Returns: + Dict with analysis information ('text', 'data', etc.) + """ + try: + from rpy2 import robjects + except ImportError: + raise ImportError("rpy2 is required to use R algorithms. Install with: pip install rpy2") + + # Convert X and Y to R format + r_X = self._python_design_to_r(X) + r_Y = self._python_outputs_to_r(Y) + + # Call R method + r_result = self.r_globals['get_analysis'](self.r_instance, r_X, r_Y) + + # Convert R list to Python dict + return self._r_dict_to_python(r_result) + + def get_analysis_tmp(self, X: List[Dict[str, float]], Y: List[float]) -> Dict[str, Any]: + """ + Call R's get_analysis_tmp method if it exists + + Args: + X: Evaluated input combinations so far + Y: Output values so far (may contain None) + + Returns: + Dict with intermediate analysis information, or None if method doesn't exist + """ + try: + from rpy2 import robjects + except ImportError: + raise ImportError("rpy2 is required to use R algorithms. Install with: pip install rpy2") + + # Check if method exists in R + try: + # Convert X and Y to R format + r_X = self._python_design_to_r(X) + r_Y = self._python_outputs_to_r(Y) + + # Call R method + r_result = self.r_globals['get_analysis_tmp'](self.r_instance, r_X, r_Y) + + # Convert R list to Python dict + return self._r_dict_to_python(r_result) + except Exception: + # Method doesn't exist or failed - return None + return None + + def _python_design_to_r(self, design: List[Dict[str, float]]): + """Convert Python design (list of dicts) to R list of lists""" + from rpy2 import robjects + from rpy2.robjects import vectors + + if not design: + # Empty list + return robjects.r('list()') + + # Convert to R list of lists + r_list = robjects.r('list()') + for point in design: + r_point = robjects.ListVector(point) + r_list = robjects.r.c(r_list, robjects.r.list(r_point)) + + return r_list + + def _python_outputs_to_r(self, outputs: List[float]): + """Convert Python outputs (list of floats/None) to R list""" + from rpy2 import robjects + + # Convert Python list to R list, preserving None as NULL + # Use R's list() function directly + r_list = robjects.r('list()') + + for val in outputs: + if val is None: + # Append R NULL + r_list = robjects.r.c(r_list, robjects.r('list(NULL)')) + else: + # Append numeric value + r_list = robjects.r.c(r_list, robjects.r.list(val)) + + return r_list + + def _r_design_to_python(self, r_design) -> List[Dict[str, float]]: + """Convert R design (list of lists) to Python list of dicts""" + if r_design is None or len(r_design) == 0: + return [] + + result = [] + for r_point in r_design: + # Convert R list to Python dict + point = {} + for name in r_point.names: + point[name] = float(r_point.rx2(name)[0]) + result.append(point) + + return result + + def _r_dict_to_python(self, r_list) -> Dict[str, Any]: + """Convert R list to Python dict, handling nested structures""" + from rpy2 import robjects + from rpy2.robjects import vectors + + result = {} + + if r_list is None: + return result + + for name in r_list.names: + r_value = r_list.rx2(name) + + # Convert based on R type + if isinstance(r_value, vectors.StrVector): + # String or character vector + if len(r_value) == 1: + result[name] = str(r_value[0]) + else: + result[name] = [str(v) for v in r_value] + elif isinstance(r_value, (vectors.FloatVector, vectors.IntVector)): + # Numeric vector + if len(r_value) == 1: + result[name] = float(r_value[0]) + else: + result[name] = [float(v) for v in r_value] + elif isinstance(r_value, vectors.ListVector): + # Nested list - recursively convert + result[name] = self._r_dict_to_python(r_value) + else: + # Try to convert to Python directly + try: + result[name] = r_value + except Exception: + # If conversion fails, store as string + result[name] = str(r_value) + + return result + + +def _load_r_algorithm_from_file(file_path: Path, **options): + """ + Load algorithm from an R file using rpy2 + + Args: + file_path: Path to R file containing algorithm S3 class + **options: Options to pass to algorithm constructor + + Returns: + RAlgorithmWrapper instance wrapping the R algorithm + + Raises: + ImportError: If rpy2 is not installed + ValueError: If R algorithm cannot be loaded + """ + try: + from rpy2 import robjects + from rpy2.robjects import vectors + except ImportError: + raise ImportError( + "rpy2 is required to use R algorithms.\n" + "Install with: pip install rpy2\n" + "Note: R must also be installed on your system." + ) + + # Parse metadata from R file + metadata = _parse_algorithm_metadata(file_path) + + # Check and install required R packages if specified + if 'require' in metadata: + for package in metadata['require']: + # Check if R package is available + r_check = robjects.r(f''' + if (!requireNamespace("{package}", quietly = TRUE)) {{ + FALSE + }} else {{ + TRUE + }} + ''') + + if not r_check[0]: + logging.warning( + f"⚠️ R package '{package}' not found.\n" + f" Install in R with: install.packages('{package}')" + ) + + # Merge metadata options with passed options + if 'options' in metadata: + merged_options = metadata['options'].copy() + merged_options.update(options) + options = merged_options + + # Source the R file + logging.info(f"Loading R algorithm from {file_path}") + try: + robjects.r.source(str(file_path)) + except Exception as e: + raise ValueError(f"Failed to source R file {file_path}: {e}") from e + + # Get R global environment + r_globals = robjects.globalenv + + # Find the algorithm constructor function + # Search for functions in R global environment that could be constructors + # Priority: try matching the file stem first, then search all functions + + # Try different naming conventions for the file stem + possible_names = [ + file_path.stem, # montecarlo_uniform + file_path.stem.replace('_', '').title(), # Montecarlouniform + ''.join(word.capitalize() for word in file_path.stem.split('_')), # MontecarloUniform + '_'.join(word.capitalize() for word in file_path.stem.split('_')), # Montecarlo_Uniform + file_path.stem.title(), # Montecarlo_Uniform + ] + + constructor = None + constructor_name = None + + # First, try the expected naming conventions + for name in possible_names: + if name in r_globals: + constructor = r_globals[name] + constructor_name = name + logging.info(f"Found constructor by name matching: {name}") + break + + # If not found, search all objects for likely constructors + # Look for functions that match pattern: PascalCase or Mixed_Case + if constructor is None: + logging.info(f"Constructor not found in expected names: {possible_names}") + logging.info("Searching all R objects for potential constructors...") + + for name in sorted(list(r_globals.keys()), reverse=True): # Reverse sort to prefer longer/specific names + # Skip generic functions (they have dots for S3 dispatch) + if '.' in name: + continue + + # Skip all-lowercase names (likely helper functions, not constructors) + if name.islower(): + continue + + # Skip names starting with lowercase (not constructors) + if name[0].islower(): + continue + + # Check if it's a function + try: + obj = r_globals[name] + # Check if it's callable (function) + if robjects.r['is.function'](obj)[0]: + constructor = obj + constructor_name = name + logging.info(f"Found potential constructor: {name}") + break + except Exception: + continue + + if constructor is None: + available_objects = [name for name in r_globals.keys() if not name.startswith('.')] + raise ValueError( + f"No algorithm constructor found in {file_path}.\n" + f"Tried names: {possible_names}\n" + f"Available objects in R file: {available_objects}\n" + f"The R file should define a constructor function matching the filename." + ) + + logging.info(f"Found R algorithm constructor: {constructor_name}") + + # Call constructor with options + # R constructors use ... syntax, so we need to pass as named arguments + # rpy2 requires explicit conversion for some types + if options: + # Convert Python options to R-compatible types and pass as kwargs + r_kwargs = {} + for k, v in options.items(): + if isinstance(v, bool): + r_kwargs[k] = robjects.vectors.BoolVector([v]) + elif isinstance(v, int): + r_kwargs[k] = robjects.vectors.IntVector([v]) + elif isinstance(v, float): + r_kwargs[k] = robjects.vectors.FloatVector([v]) + elif isinstance(v, str): + r_kwargs[k] = robjects.vectors.StrVector([v]) + else: + r_kwargs[k] = v + + # Call with **kwargs - rpy2 will handle the ... properly + r_instance = constructor(**r_kwargs) + else: + r_instance = constructor() + + logging.info(f"Created R algorithm instance of class: {robjects.r['class'](r_instance)[0]}") + + # Create and return wrapper + return RAlgorithmWrapper(r_instance, r_globals) + + +def resolve_algorithm_path(algorithm: str) -> Optional[Path]: + """ + Resolve algorithm name to file path, searching in plugin directories + + This function implements the algorithm plugin system, similar to model aliases. + When given a simple name (e.g., "myalgorithm"), it searches for the algorithm + file in: + 1. .fz/algorithms/ (project-level, priority) + 2. ~/.fz/algorithms/ (global) + + Supports both .py and .R extensions. + + Args: + algorithm: Algorithm name (e.g., "myalgorithm") or path (e.g., "path/to/algo.py") + + Returns: + Path to algorithm file if found, None otherwise + + Examples: + >>> resolve_algorithm_path("myalgorithm") # Looks for .fz/algorithms/myalgorithm.py + Path('/path/to/project/.fz/algorithms/myalgorithm.py') + + >>> resolve_algorithm_path("path/to/algo.py") # Returns as-is (it's a path) + None # Caller should handle as direct path + """ + import os + + # If algorithm looks like a path (contains / or \ or has extension), don't resolve + if '/' in algorithm or '\\' in algorithm or algorithm.endswith(('.py', '.R')): + return None + + # Search in plugin directories + # Respect environment variables for home directory (for test mocking) + # Try HOME first (Unix), then USERPROFILE (Windows), then fall back to expanduser + home_dir = os.environ.get('HOME') or os.environ.get('USERPROFILE') or os.path.expanduser('~') + + search_dirs = [ + Path.cwd() / ".fz" / "algorithms", # Project-level (priority) + Path(home_dir) / ".fz" / "algorithms" # Global + ] + + # Try both .py and .R extensions + extensions = ['.py', '.R'] + + for base_dir in search_dirs: + if not base_dir.exists(): + continue + + for ext in extensions: + algo_path = base_dir / f"{algorithm}{ext}" + if algo_path.exists() and algo_path.is_file(): + logging.info(f"Found algorithm plugin: {algo_path}") + return algo_path + + return None + + +def load_algorithm(algorithm: str, **options): + """ + Load an algorithm from a Python or R file and create an instance with options + + This function supports two modes: + 1. Plugin mode: Simple name (e.g., "myalgorithm") - searches in .fz/algorithms/ + 2. Direct path: File path (e.g., "path/to/algo.py" or "algorithms/monte_carlo.R") + + Plugin directories (searched in order): + - .fz/algorithms/ (project-level, priority) + - ~/.fz/algorithms/ (global) + + Args: + algorithm: Algorithm name (plugin) or path to Python (.py) or R (.R) file + **options: Algorithm-specific options passed to the algorithm's __init__ method + + Returns: + Algorithm instance (Python object or R wrapper) + + Raises: + ValueError: If the file doesn't exist, contains no valid algorithm class, or cannot be loaded + ImportError: If rpy2 is not installed for .R files + + Examples: + # Plugin mode - searches in .fz/algorithms/ + >>> algo = load_algorithm("myalgorithm", batch_size=10) + + # Direct path mode + >>> algo = load_algorithm("algorithms/monte_carlo.py", batch_size=10, max_iter=100) + >>> algo = load_algorithm("algorithms/monte_carlo.R", batch_size=10) # requires rpy2 + """ + # Try to resolve as plugin first + resolved_path = resolve_algorithm_path(algorithm) + + if resolved_path is not None: + # Found as plugin + algorithm_path = str(resolved_path) + logging.info(f"Loading algorithm from plugin: {algorithm_path}") + else: + # Treat as direct path + algorithm_path = algorithm + + # Convert to Path object + algo_path = Path(algorithm_path) + + # Resolve to absolute path if relative + if not algo_path.is_absolute(): + algo_path = Path.cwd() / algo_path + + # Validate path + if not algo_path.exists(): + # Provide helpful error message + error_msg = f"Algorithm file not found: {algo_path}\n" + + # If it looks like a plugin name, suggest where to place it + if '/' not in algorithm and '\\' not in algorithm and not algorithm.endswith(('.py', '.R')): + error_msg += ( + f"Plugin '{algorithm}' not found. To use as plugin, place algorithm file at:\n" + f" - .fz/algorithms/{algorithm}.py (project-level), or\n" + f" - ~/.fz/algorithms/{algorithm}.py (global)\n" + f"Supported extensions: .py, .R" + ) + else: + error_msg += "Please provide a valid path to a Python (.py) or R (.R) file containing an algorithm class." + + raise ValueError(error_msg) + + if not algo_path.is_file(): + raise ValueError(f"Algorithm path is not a file: {algo_path}") + + # Check file extension and load appropriately + if str(algo_path).endswith('.py'): + # Load Python algorithm + return _load_algorithm_from_file(algo_path, **options) + elif str(algo_path).endswith('.R'): + # Load R algorithm + return _load_r_algorithm_from_file(algo_path, **options) + else: + raise ValueError( + f"Algorithm file must be a Python (.py) or R (.R) file: {algo_path}\n" + f"Got: {algo_path.suffix}" + ) + + +class BaseAlgorithm: + """ + Base class for algorithms (optional, for reference) + + Algorithms don't need to inherit from this, but it documents the interface + """ + + def __init__(self, **options): + """Initialize algorithm with options""" + self.options = options + + def get_initial_design( + self, + input_vars: Dict[str, Tuple[float, float]], + output_vars: List[str] + ) -> List[Dict[str, float]]: + """ + Generate initial design of experiments + + Args: + input_vars: Dict of {var_name: (min, max)} + output_vars: List of output variable names + + Returns: + List of input variable combinations to evaluate + """ + raise NotImplementedError() + + def get_next_design( + self, + previous_input_vars: List[Dict[str, float]], + previous_output_values: List[float] + ) -> List[Dict[str, float]]: + """ + Generate next design based on previous results + + Args: + previous_input_vars: Previous input combinations + previous_output_values: Corresponding output values + + Returns: + Next input variable combinations to evaluate + Returns empty list when finished + """ + raise NotImplementedError() + + def get_analysis( + self, + input_vars: List[Dict[str, float]], + output_values: List[float] + ) -> Dict[str, Any]: + """ + Format results for analysis + + Args: + input_vars: All evaluated input combinations + output_values: All corresponding output values + + Returns: + Dict with analysis information + """ + raise NotImplementedError() diff --git a/fz/cli.py b/fz/cli.py index b0ff0ba..db7ef50 100644 --- a/fz/cli.py +++ b/fz/cli.py @@ -12,7 +12,7 @@ except ImportError: from importlib_metadata import version -from . import fzi as fzi_func, fzc as fzc_func, fzo as fzo_func, fzr as fzr_func +from . import fzi as fzi_func, fzc as fzc_func, fzo as fzo_func, fzr as fzr_func, fzd as fzd_func # Get package version @@ -20,13 +20,26 @@ def get_version(): """Get the package version""" try: # Try the new package name first - return version("funz-fz") + v = version("funz-fz") + if v is not None: + return v except Exception: - try: - # Fallback to old package name for backward compatibility - return version("fz") - except Exception: - return "unknown" + pass + + try: + # Fallback to old package name for backward compatibility + v = version("fz") + if v is not None: + return v + except Exception: + pass + + # Fallback to __version__ from __init__.py + try: + from fz import __version__ + return __version__ + except: + return "unknown" # Helper functions used by all CLI commands @@ -128,6 +141,15 @@ def parse_calculators(calc_str): return result +def parse_algorithm(algo_str): + """Parse algorithm from JSON string, JSON file, or alias""" + return parse_argument(algo_str, alias_type='algorithms') + + +def parse_algorithm_options(opts_str): + """Parse algorithm options from JSON string or JSON file""" + return parse_argument(opts_str, alias_type=None) + def format_output(data, format_type='markdown'): """ Format output data in various formats @@ -368,6 +390,65 @@ def fzr_main(): return 1 +def fzd_main(): + """Entry point for fzd command""" + parser = argparse.ArgumentParser(description="fzd - Iterative design of experiments with algorithms") + parser.add_argument("--version", action="version", version=f"fzd {get_version()}") + parser.add_argument("--input_dir", "-i", required=True, help="Input directory path") + parser.add_argument("--input_vars", "-v", required=True, help="Input variable ranges (JSON file or inline JSON)") + parser.add_argument("--model", "-m", required=True, help="Model definition (JSON file, inline JSON, or alias)") + parser.add_argument("--output_expression", "-e", required=True, help="Output expression to minimize (e.g., 'out1 + out2 * 2')") + parser.add_argument("--algorithm", "-a", required=True, help="Algorithm name (randomsampling, brent, bfgs, ...)") + parser.add_argument("--results_dir", "-r", default="results_fzd", help="Results directory (default: results_fzd)") + parser.add_argument("--calculators", "-c", help="Calculator specifications (JSON file or inline JSON)") + parser.add_argument("--options", "-o", help="Algorithm options (JSON file or inline JSON)") + + args = parser.parse_args() + + try: + model = parse_model(args.model) + variables = parse_variables(args.input_vars) + + calculators = parse_calculators(args.calculators) if args.calculators else None + algo_options = parse_algorithm_options(args.options) if args.options else {} + + result = fzd_func( + args.input_dir, + variables, + model, + args.output_expression, + args.algorithm, + results_dir=args.results_dir, + calculators=calculators, + **(algo_options if isinstance(algo_options, dict) else {}) + ) + + # Print summary + print("\n" + "="*60) + print(result['summary']) + print("="*60) + + if 'analysis' in result and 'text' in result['analysis']: + print(result['analysis']['text']) + + return 0 + except TypeError as e: + # TypeError messages already printed by decorator + # Just show help and exit + print(file=sys.stderr) + parser.print_help(sys.stderr) + return 1 + except (ValueError, FileNotFoundError) as e: + # These error messages already printed by decorator + # Just exit with error code + return 1 + except Exception as e: + print(f"Error: {e}", file=sys.stderr) + import traceback + traceback.print_exc() + return 1 + + def main(): """Entry point for 'fz' command with subcommands""" parser = argparse.ArgumentParser(description="fz - Parametric scientific computing") @@ -408,22 +489,62 @@ def main(): choices=["json", "csv", "html", "markdown", "table"], help="Output format (default: markdown)") - # install command - parser_install = subparsers.add_parser("install", help="Install a model from GitHub or local zip file") - parser_install.add_argument("source", help="Model source (GitHub name, URL, or local zip file)") - parser_install.add_argument("--global", dest="global_install", action="store_true", - help="Install to ~/.fz/models/ (default: ./.fz/models/)") - - # list command - parser_list = subparsers.add_parser("list", help="List installed models") - parser_list.add_argument("--global", dest="global_list", action="store_true", - help="List models from ~/.fz/models/ (default: ./.fz/models/)") - - # uninstall command - parser_uninstall = subparsers.add_parser("uninstall", help="Uninstall a model") - parser_uninstall.add_argument("model", help="Model name to uninstall") - parser_uninstall.add_argument("--global", dest="global_uninstall", action="store_true", - help="Uninstall from ~/.fz/models/ (default: ./.fz/models/)") + # design command (fzd) + parser_design = subparsers.add_parser("design", help="Iterative design of experiments with algorithms") + parser_design.add_argument("--input_dir", "-i", required=True, help="Input directory path") + parser_design.add_argument("--input_vars", "-v", required=True, help="Input variable ranges (JSON file or inline JSON)") + parser_design.add_argument("--model", "-m", required=True, help="Model definition (JSON file, inline JSON, or alias)") + parser_design.add_argument("--output_expression", "-e", required=True, help="Output expression to minimize (e.g., 'out1 + out2 * 2')") + parser_design.add_argument("--algorithm", "-a", required=True, help="Algorithm name (randomsampling, brent, bfgs, ...)") + parser_design.add_argument("--results_dir", "-r", default="results_fzd", help="Results directory (default: results_fzd)") + parser_design.add_argument("--calculators", "-c", help="Calculator specifications (JSON file or inline JSON)") + parser_design.add_argument("--options", "-o", help="Algorithm options (JSON file or inline JSON)") + + # install command (supports both models and algorithms) + parser_install = subparsers.add_parser("install", help="Install a model or algorithm from GitHub or local zip file") + install_subparsers = parser_install.add_subparsers(dest="install_type", help="Type of resource to install") + + # install model subcommand + parser_install_model = install_subparsers.add_parser("model", help="Install a model") + parser_install_model.add_argument("source", help="Model source (GitHub name, URL, or local zip file)") + parser_install_model.add_argument("--global", dest="global_install", action="store_true", + help="Install to ~/.fz/models/ (default: ./.fz/models/)") + + # install algorithm subcommand + parser_install_algorithm = install_subparsers.add_parser("algorithm", help="Install an algorithm") + parser_install_algorithm.add_argument("source", help="Algorithm source (GitHub name, URL, or local zip file)") + parser_install_algorithm.add_argument("--global", dest="global_install", action="store_true", + help="Install to ~/.fz/algorithms/ (default: ./.fz/algorithms/)") + + # list command (supports both models and algorithms) + parser_list = subparsers.add_parser("list", help="List installed models or algorithms") + list_subparsers = parser_list.add_subparsers(dest="list_type", help="Type of resource to list") + + # list models subcommand + parser_list_models = list_subparsers.add_parser("models", help="List installed models") + parser_list_models.add_argument("--global", dest="global_list", action="store_true", + help="List models from ~/.fz/models/ (default: ./.fz/models/)") + + # list algorithms subcommand + parser_list_algorithms = list_subparsers.add_parser("algorithms", help="List installed algorithms") + parser_list_algorithms.add_argument("--global", dest="global_list", action="store_true", + help="List algorithms from ~/.fz/algorithms/ (default: ./.fz/algorithms/)") + + # uninstall command (supports both models and algorithms) + parser_uninstall = subparsers.add_parser("uninstall", help="Uninstall a model or algorithm") + uninstall_subparsers = parser_uninstall.add_subparsers(dest="uninstall_type", help="Type of resource to uninstall") + + # uninstall model subcommand + parser_uninstall_model = uninstall_subparsers.add_parser("model", help="Uninstall a model") + parser_uninstall_model.add_argument("name", help="Model name to uninstall") + parser_uninstall_model.add_argument("--global", dest="global_uninstall", action="store_true", + help="Uninstall from ~/.fz/models/ (default: ./.fz/models/)") + + # uninstall algorithm subcommand + parser_uninstall_algorithm = uninstall_subparsers.add_parser("algorithm", help="Uninstall an algorithm") + parser_uninstall_algorithm.add_argument("name", help="Algorithm name to uninstall") + parser_uninstall_algorithm.add_argument("--global", dest="global_uninstall", action="store_true", + help="Uninstall from ~/.fz/algorithms/ (default: ./.fz/algorithms/)") args = parser.parse_args() @@ -458,36 +579,118 @@ def main(): calculators=calculators) print(format_output(result, args.format)) + elif args.command == "design": + model = parse_model(args.model) + variables = parse_variables(args.input_vars) + + calculators = None + calculators = parse_calculators(args.calculators) if args.calculators else None + + # Parse algorithm options + algo_options = {} + if args.options: + if args.options.endswith('.json'): + with open(args.options) as f: + algo_options = json.load(f) + else: + algo_options = json.loads(args.options) + + result = fzd_func( + args.input_dir, + variables, + model, + args.output_expression, + args.algorithm, + results_dir=args.results_dir, + calculators=calculators, + **algo_options + ) + + # Print summary + print("\n" + "="*60) + print(result['summary']) + print("="*60) + + if 'analysis' in result and 'text' in result['analysis']: + print(result['analysis']['text']) + elif args.command == "install": - from .installer import install_model - result = install_model(args.source, global_install=args.global_install) - print(f"Successfully installed model '{result['model_name']}'") - if result.get('installed_files'): - print(f" Installed {len(result['installed_files'])} additional files from .fz subdirectories") + if args.install_type == "model": + from .installer import install_model + result = install_model(args.source, global_install=args.global_install) + print(f"Successfully installed model '{result['model_name']}'") + if result.get('installed_files'): + print(f" Installed {len(result['installed_files'])} additional files from .fz subdirectories") + elif args.install_type == "algorithm": + from .installer import install_algorithm + result = install_algorithm(args.source, global_install=args.global_install) + print(f"Successfully installed algorithm '{result['algorithm_name']}'") + if len(result.get('all_files', [])) > 1: + print(f" Installed {len(result['all_files'])} files") + else: + print("Error: Please specify 'model' or 'algorithm' to install") + print("Usage: fz install model ") + print(" fz install algorithm ") + return 1 elif args.command == "list": - from .installer import list_installed_models - models = list_installed_models(global_list=args.global_list) - if not models: - location = "~/.fz/models/" if args.global_list else "./.fz/models/" - print(f"No models installed in {location}") + if args.list_type == "models": + from .installer import list_installed_models + models = list_installed_models(global_list=args.global_list) + if not models: + location = "~/.fz/models/" if args.global_list else "./.fz/models/" + print(f"No models installed in {location}") + else: + print(f"Installed models:") + for model_name, model_info in models.items(): + model_id = model_info.get('id', 'N/A') + is_global = model_info.get('global', False) + location = "[global]" if is_global else "[local]" + print(f" - {model_name} (id: {model_id}) {location}") + elif args.list_type == "algorithms": + from .installer import list_installed_algorithms + algorithms = list_installed_algorithms(global_list=args.global_list) + if not algorithms: + location = "~/.fz/algorithms/" if args.global_list else "./.fz/algorithms/" + print(f"No algorithms installed in {location}") + else: + print(f"Installed algorithms:") + for algo_name, algo_info in algorithms.items(): + algo_type = algo_info.get('type', 'N/A') + is_global = algo_info.get('global', False) + location = "[global]" if is_global else "[local]" + print(f" - {algo_name} ({algo_type}) {location}") else: - print(f"Installed models:") - for model_name, model_info in models.items(): - model_id = model_info.get('id', 'N/A') - is_global = model_info.get('global', False) - location = "[global]" if is_global else "[local]" - print(f" - {model_name} (id: {model_id}) {location}") + print("Error: Please specify 'models' or 'algorithms' to list") + print("Usage: fz list models") + print(" fz list algorithms") + return 1 elif args.command == "uninstall": - from .installer import uninstall_model - success = uninstall_model(args.model, global_uninstall=args.global_uninstall) - if success: - location = "~/.fz/models/" if args.global_uninstall else "./.fz/models/" - print(f"Successfully uninstalled model '{args.model}' from {location}") + if args.uninstall_type == "model": + from .installer import uninstall_model + success = uninstall_model(args.name, global_uninstall=args.global_uninstall) + if success: + location = "~/.fz/models/" if args.global_uninstall else "./.fz/models/" + print(f"Successfully uninstalled model '{args.name}' from {location}") + else: + location = "~/.fz/models/" if args.global_uninstall else "./.fz/models/" + print(f"Model '{args.name}' not found in {location}") + return 1 + elif args.uninstall_type == "algorithm": + from .installer import uninstall_algorithm + success = uninstall_algorithm(args.name, global_uninstall=args.global_uninstall) + if success: + location = "~/.fz/algorithms/" if args.global_uninstall else "./.fz/algorithms/" + print(f"Successfully uninstalled algorithm '{args.name}' from {location}") + else: + location = "~/.fz/algorithms/" if args.global_uninstall else "./.fz/algorithms/" + print(f"Algorithm '{args.name}' not found in {location}") + return 1 else: - location = "~/.fz/models/" if args.global_uninstall else "./.fz/models/" - print(f"Model '{args.model}' not found in {location}") + print("Error: Please specify 'model' or 'algorithm' to uninstall") + print("Usage: fz uninstall model ") + print(" fz uninstall algorithm ") return 1 except Exception as e: @@ -498,4 +701,4 @@ def main(): if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/fz/config.py b/fz/config.py index baac186..befb91e 100644 --- a/fz/config.py +++ b/fz/config.py @@ -5,7 +5,7 @@ """ import os -from typing import Optional, Union +from typing import Optional from enum import Enum diff --git a/fz/core.py b/fz/core.py index 91f3c54..de2ff0a 100644 --- a/fz/core.py +++ b/fz/core.py @@ -3,22 +3,16 @@ """ import os -import re -import subprocess -import tempfile -import json -import ast import logging import time import uuid +import threading +from collections import defaultdict import signal import sys -import io import platform from pathlib import Path -from typing import Dict, List, Union, Any, Optional, Tuple, TYPE_CHECKING -from concurrent.futures import ThreadPoolExecutor, as_completed -from contextlib import contextmanager +from typing import Dict, List, Union, Any, Optional, TYPE_CHECKING # Configure UTF-8 encoding for Windows to handle emoji output if platform.system() == "Windows": @@ -61,50 +55,117 @@ def utf8_open( if TYPE_CHECKING: import pandas -try: - import pandas as pd - - PANDAS_AVAILABLE = True -except ImportError: - PANDAS_AVAILABLE = False - pd = None - logging.warning("pandas not available, fzo() and fzr() will return dicts instead of DataFrames") +import pandas as pd -import threading -from collections import defaultdict import shutil -from .logging import log_error, log_warning, log_info, log_debug, log_progress -from .config import get_config +from .logging import log_error, log_warning, log_info, log_debug from .helpers import ( fz_temporary_directory, - _get_result_directory, - _get_case_directories, _cleanup_fzr_resources, _resolve_model, - get_calculator_manager, - try_calculators_with_retry, - run_single_case, run_cases_parallel, compile_to_result_directories, prepare_temp_directories, - prepare_case_directories, ) from .shell import run_command, replace_commands_in_string from .io import ( + flatten_dict_columns, + get_analysis, + get_and_process_analysis, ensure_unique_directory, - create_hash_file, resolve_cache_paths, find_cache_match, load_aliases, + process_analysis_content, ) from .interpreter import ( parse_variables_from_path, cast_output, ) from .runners import resolve_calculators, run_calculation +from .algorithms import ( + parse_input_vars, + parse_fixed_vars, + evaluate_output_expression, + load_algorithm, +) +import json +def _parse_argument(arg, alias_type=None): + """ + Parse an argument that can be: JSON string, JSON file path, or alias. + + Tries in order: + 1. JSON string (e.g., '{"key": "value"}') + 2. JSON file path (e.g., 'path/to/file.json') + 3. Alias (e.g., 'myalias' -> looks for .fz//myalias.json) + + Args: + arg: The argument to parse (str, dict, list, or other) + alias_type: Type of alias ('models', 'calculators', 'algorithms', etc.) + + Returns: + Parsed data or the original argument if it's not a string + """ + # If not a string, return as-is + if not isinstance(arg, str): + return arg + + if not arg: + return None + + # Try 1: Parse as JSON string (preferred) + if arg.strip().startswith(('{', '[')): + try: + return json.loads(arg) + except json.JSONDecodeError: + pass # Fall through to next option + + # Try 2: Load as JSON file path + if arg.endswith('.json'): + try: + path = Path(arg) + if path.exists(): + with open(path) as f: + return json.load(f) + except (IOError, json.JSONDecodeError): + pass # Fall through to next option + + # Try 3: Load as alias + if alias_type: + from .io import load_aliases + alias_data = load_aliases(arg, alias_type) + if alias_data is not None: + return alias_data + + # If alias_type not provided or alias not found, return as-is + return arg + + +def _resolve_calculators_arg(calculators): + """ + Parse and resolve calculator argument. + + Handles: + - None (defaults to ["sh://"]) + - JSON string, JSON file, or alias string + - Single calculator dict (wraps in list) + - List of calculator specs + """ + if calculators is None: + return ["sh://"] + + # Parse the argument (could be JSON string, file, or alias) + calculators = _parse_argument(calculators, alias_type='calculators') + + # Wrap dict in list if it's a single calculator definition + if isinstance(calculators, dict): + calculators = [calculators] + + return calculators + def _print_function_help(func_name: str, func_doc: str): """Print function signature and docstring to help users""" print(f"\n{'='*60}", file=sys.stderr) @@ -641,8 +702,9 @@ def fzc( if not isinstance(input_path, (str, Path)): raise TypeError(f"input_path must be a string or Path, got {type(input_path).__name__}") - if not isinstance(input_variables, dict): - raise TypeError(f"input_variables must be a dictionary, got {type(input_variables).__name__}") + # Allow dict or pandas DataFrame for input_variables + if not isinstance(input_variables, (dict, pd.DataFrame)): + raise TypeError(f"input_variables must be a dictionary or DataFrame, got {type(input_variables).__name__}") if not isinstance(output_dir, (str, Path)): raise TypeError(f"output_dir must be a string or Path, got {type(output_dir).__name__}") @@ -779,7 +841,7 @@ def fzo( rows.append(row) # Return DataFrame if pandas is available, otherwise return first row as dict for backward compatibility - if PANDAS_AVAILABLE: + if True: # pandas is always available df = pd.DataFrame(rows) # Check if all 'path' values follow the "key1=val1,key2=val2,..." pattern @@ -841,86 +903,20 @@ def fzo( cast_values.append(v) df[key] = cast_values + # Flatten any dict-valued columns into separate columns + df = flatten_dict_columns(df) + # Always restore the original working directory os.chdir(working_dir) return df - else: - # Return dict with lists for backward compatibility when no pandas - if not rows: - return {} - - # Convert list of dicts to dict of lists - result_dict = {} - for row in rows: - for key, value in row.items(): - if key not in result_dict: - result_dict[key] = [] - result_dict[key].append(value) - - # Also parse variable values from path if applicable - if len(rows) > 0 and "path" in result_dict: - parsed_vars = {} - all_parseable = True - - for path_val in result_dict["path"]: - # Extract just the last component (subdirectory name) for parsing - path_obj = Path(path_val) - last_component = path_obj.name - - # If last component doesn't contain '=', it's not a key=value pattern - if '=' not in last_component: - all_parseable = False - break - - try: - parts = last_component.split(",") - row_vars = {} - for part in parts: - if "=" in part: - key, val = part.split("=", 1) - row_vars[key.strip()] = val.strip() - else: - all_parseable = False - break - - if not all_parseable: - break - - for key in row_vars: - if key not in parsed_vars: - parsed_vars[key] = [] - parsed_vars[key].append(row_vars[key]) - - except Exception: - all_parseable = False - break - - # If all paths were parseable, add the extracted columns - if all_parseable and parsed_vars: - for key, values in parsed_vars.items(): - # Try to cast values to appropriate types - cast_values = [] - for v in values: - try: - if "." not in v: - cast_values.append(int(v)) - else: - cast_values.append(float(v)) - except ValueError: - cast_values.append(v) - result_dict[key] = cast_values - - # Always restore the original working directory - os.chdir(working_dir) - return result_dict @with_helpful_errors def fzr( input_path: str, - input_variables: Dict, + input_variables: Union[Dict, "pandas.DataFrame"], model: Union[str, Dict], results_dir: str = "results", calculators: Union[str, List[str]] = None, @@ -931,7 +927,8 @@ def fzr( Args: input_path: Path to input file or directory - input_variables: Dict of variable values or lists of values for grid + input_variables: Dict of variable values or lists of values for factorial grid, + or pandas DataFrame for non-factorial designs (each row is one case) model: Model definition dict or alias string results_dir: Results directory calculators: Calculator specifications @@ -955,8 +952,9 @@ def fzr( if not isinstance(input_path, (str, Path)): raise TypeError(f"input_path must be a string or Path, got {type(input_path).__name__}") - if not isinstance(input_variables, dict): - raise TypeError(f"input_variables must be a dictionary, got {type(input_variables).__name__}") + # Allow dict or pandas DataFrame for input_variables + if not isinstance(input_variables, (dict, pd.DataFrame)): + raise TypeError(f"input_variables must be a dictionary or DataFrame, got {type(input_variables).__name__}") if not isinstance(results_dir, (str, Path)): raise TypeError(f"results_dir must be a string or Path, got {type(results_dir).__name__}") @@ -1050,6 +1048,9 @@ def fzr( # Prepare results structure results = {var: [] for var in var_names} + # Get output keys from model (for reference), but don't pre-initialize arrays + # Output arrays will be created dynamically based on actual case results + # (especially important for dict outputs that get flattened) output_keys = list(model.get("output", {}).keys()) for key in output_keys: results[key] = [] @@ -1064,7 +1065,11 @@ def fzr( temp_path = Path(temp_dir) # Determine if input_variables is non-empty for directory structure decisions - has_input_variables = bool(input_variables) + # Handle both dict and DataFrame input types + if isinstance(input_variables, pd.DataFrame): + has_input_variables = not input_variables.empty + else: + has_input_variables = bool(input_variables) # Compile all combinations directly to result directories, then prepare temp directories compile_to_result_directories( @@ -1091,15 +1096,35 @@ def fzr( ) # Collect results in the correct order, filtering out None (interrupted/incomplete cases) + # First pass: collect all output columns from all cases to support dict flattening + all_output_cols = set() + valid_case_results = [] + for case_result in case_results: # Skip None results (incomplete cases from interrupts) if case_result is None: continue + valid_case_results.append(case_result) + + # Collect all output columns (including flattened dict columns) + metadata_keys = {"var_combo", "path", "calculator", "status", "error", "command"} + for key in case_result.keys(): + if key not in var_names and key not in metadata_keys: + all_output_cols.add(key) + + # Initialize all output columns in results dict + for key in all_output_cols: + if key not in results: + results[key] = [] + + # Second pass: populate results + for case_result in valid_case_results: for var in var_names: results[var].append(case_result["var_combo"][var]) - for key in output_keys: + # Append values for all output columns + for key in all_output_cols: results[key].append(case_result.get(key)) results["path"].append(case_result.get("path", ".")) @@ -1133,11 +1158,15 @@ def fzr( # Always restore the original working directory os.chdir(working_dir) - # Prepare final results - if PANDAS_AVAILABLE: - final_results = pd.DataFrame(results) - else: - final_results = results + # Return DataFrame + # Remove any columns that are empty (e.g., original dict columns that were flattened) + # This happens when dict flattening creates new columns (min, max, diff) and the + # original column (stats) is no longer populated + non_empty_results = {k: v for k, v in results.items() if len(v) > 0} + + df = pd.DataFrame(non_empty_results) + # Flatten any dict-valued columns into separate columns + final_results = flatten_dict_columns(df) # Call on_complete callback if callbacks and 'on_complete' in callbacks: @@ -1149,3 +1178,448 @@ def fzr( # Return final results return final_results + + +def _get_and_process_analysis( + algo_instance, + all_input_vars: List[Dict[str, float]], + all_output_values: List[float], + iteration: int, + results_dir: Path, + method_name: str = 'get_analysis' +) -> Optional[Dict[str, Any]]: + """ + Helper to call algorithm's analysis method and process the results. + + Args: + algo_instance: Algorithm instance + all_input_vars: All evaluated input combinations + all_output_values: All corresponding output values + iteration: Current iteration number + results_dir: Directory to save processed results + method_name: Name of the display method ('get_analysis' or 'get_analysis_tmp') + + Returns: + Processed analysis dict or None if method doesn't exist or fails + """ + if not hasattr(algo_instance, method_name): + return None + + try: + analysis_method = getattr(algo_instance, method_name) + analysis_dict = analysis_method(all_input_vars, all_output_values) + + if display_dict: + # Log text content before processing (for console output) + if 'text' in display_dict: + log_info(display_dict['text']) + + # Process and save content intelligently + processed = process_analysis_content(display_dict, iteration, results_dir) + return processed + return None + + except Exception as e: + log_warning(f"⚠️ {method_name} failed: {e}") + return None + + +def _get_analysis( + algo_instance, + all_input_vars: List[Dict[str, float]], + all_output_values: List[float], + output_expression: str, + algorithm: str, + iteration: int, + results_dir: Path +) -> Dict[str, Any]: + """ + Create final analysis results with analysis information and DataFrame. + + Args: + algo_instance: Algorithm instance + all_input_vars: All evaluated input combinations + all_output_values: All corresponding output values + output_expression: Expression for output column name + algorithm: Algorithm path/name + iteration: Final iteration number + results_dir: Directory for saving results + + Returns: + Dict with analysis results including XY DataFrame and analysis info + """ + # Display final results + log_info("\n" + "="*60) + log_info("📈 Final Results") + log_info("="*60) + + # Get and process final display results (logging is done inside) + processed_final_display = _get_and_process_analysis( + algo_instance, all_input_vars, all_output_values, + iteration, results_dir, 'get_analysis' + ) + + # If processed_final_display is None, create empty dict for backward compatibility + if processed_final_display is None: + processed_final_display = {} + + # Create DataFrame with all input and output values + df_data = [] + for inp_dict, out_val in zip(all_input_vars, all_output_values): + row = inp_dict.copy() + row[output_expression] = out_val # Use output_expression as column name + df_data.append(row) + + data_df = pd.DataFrame(df_data) + + # Prepare return value + result = { + 'XY': data_df, # DataFrame with all X and Y values + 'analysis': processed_final_analysis, # Use processed analysis instead of raw + 'algorithm': algorithm, + 'iterations': iteration, + 'total_evaluations': len(all_input_vars), + } + + # Add summary + valid_count = sum(1 for v in all_output_values if v is not None) + summary = f"{algorithm} completed: {iteration} iterations, {len(all_input_vars)} evaluations ({valid_count} valid)" + result['summary'] = summary + + return result + + +def fzd( + input_path: str, + input_variables: Dict[str, str], + model: Union[str, Dict], + output_expression: str, + algorithm: str, + calculators: Union[str, List[str]] = None, + algorithm_options: Dict[str, Any] = None, + analysis_dir: str = "analysis" +) -> Dict[str, Any]: + """ + Run iterative design of experiments with algorithms + + Requires pandas to be installed. + + Args: + input_path: Path to input file or directory + input_variables: Input variables to vary, as dict of strings {"var1": "[min;max]", ...} + model: Model definition dict or alias string + output_expression: Expression to extract from output files, e.g. "output1 + output2 * 2" + algorithm: Path to algorithm Python file (e.g., "algorithms/montecarlo.py") + calculators: Calculator specifications (default: ["sh://"]) + algorithm_options: Dict of algorithm-specific options (e.g., {"batch_size": 10, "max_iter": 100}) + analysis_dir: Analysis results directory (default: "results_fzd") + + Returns: + Dict with algorithm results including: + - 'input_vars': List of evaluated input combinations + - 'output_values': List of corresponding output values + - 'analysis': Display information from algorithm.get_analysis() + - 'summary': Summary text + + Raises: + ImportError: If pandas is not installed + + Example: + >>> analysis = fz.fzd( + ... input_path='input.txt', + ... input_variables={"x1": "[0;10]", "x2": "[0;5]"}, + ... model="mymodel", + ... output_expression="pressure", + ... algorithm="algorithms/montecarlo_uniform.py", + ... calculators=["sh://bash ./calculator.sh"], + ... algorithm_options={"batch_sample_size": 20, "max_iterations": 50}, + ... analysis_dir="fzd_analysis" + ... ) + """ + # This represents the directory from which the function was launched + working_dir = os.getcwd() + + # Install signal handler for graceful interrupt handling + global _interrupt_requested + _interrupt_requested = False + _install_signal_handler() + + + try: + model = _resolve_model(model) + + # Parse calculator argument (handles JSON string, file, or alias) + calculators = _resolve_calculators_arg(calculators) + + # Get model ID for calculator resolution + model_id = model.get("id") if isinstance(model, dict) else None + calculators = resolve_calculators(calculators, model_id) + + # Convert to absolute paths + input_dir = Path(input_path).resolve() + results_dir = Path(analysis_dir).resolve() + + # Ensure analysis directory is unique (rename existing with timestamp) + results_dir, renamed_results_dir = ensure_unique_directory(results_dir) + + # Parse input variable ranges and fixed values + parsed_input_vars = parse_input_vars(input_variables) # Only variables with ranges + fixed_input_vars = parse_fixed_vars(input_variables) # Fixed (unique) values + + # Log what we're doing + if fixed_input_vars: + log_info(f"🔒 Fixed variables: {', '.join(f'{k}={v}' for k, v in fixed_input_vars.items())}") + if parsed_input_vars: + log_info(f"🔄 Variable ranges: {', '.join(f'{k}={v}' for k, v in parsed_input_vars.items())}") + + # Extract output variable names from the model + output_spec = model.get("output", {}) + output_var_names = list(output_spec.keys()) + + if not output_var_names: + raise ValueError("Model must specify output variables in 'output' field") + + # Load algorithm with options + if algorithm_options is None: + algorithm_options = {} + algo_instance = load_algorithm(algorithm, **algorithm_options) + + # Get initial design from algorithm (only for variable inputs) + log_info(f"🎯 Starting {algorithm} algorithm...") + initial_design_vars = algo_instance.get_initial_design(parsed_input_vars, output_expression) + + # Merge fixed values with algorithm-generated design + initial_design = [] + for design_point in initial_design_vars: + # Combine variable values (from algorithm) with fixed values + full_point = {**design_point, **fixed_input_vars} + initial_design.append(full_point) + + # Track all evaluations + all_input_vars = [] + all_output_values = [] + + # Iterative loop + iteration = 0 + current_design = initial_design + + while current_design and not _interrupt_requested: + iteration += 1 + log_info(f"\n📊 Iteration {iteration}: Evaluating {len(current_design)} point(s)...") + + # Create results subdirectory for this iteration + iteration_result_dir = results_dir / f"iter{iteration:03d}" + iteration_result_dir.mkdir(parents=True, exist_ok=True) + + # Run fzr for all points in parallel using calculators + try: + log_info(f" Running {len(current_design)} cases in parallel...") + # Create DataFrame with all variables (both variable and fixed) + all_var_names = list(parsed_input_vars.keys()) + list(fixed_input_vars.keys()) + # Build cache paths: include current iterations and renamed directory if it exists + cache_paths = [f"cache://{results_dir / f'iter{j:03d}'}" for j in range(1, iteration)] + if renamed_results_dir is not None: + # Also check renamed directory for cached results from previous runs + cache_paths.extend([f"cache://{renamed_results_dir / f'iter{j:03d}'}" for j in range(1, 100)]) # Check up to 99 iterations + + result_df = fzr( + str(input_dir), + pd.DataFrame(current_design, columns=all_var_names),# All points in batch + model, + results_dir=str(iteration_result_dir), + calculators=[*cache_paths, *calculators] # Cache paths first, then actual calculators + ) + + # Extract output values for each point + iteration_inputs = [] + iteration_outputs = [] + + # result_df is a DataFrame (pandas is required for fzd) + for i, point in enumerate(current_design): + iteration_inputs.append(point) + + if i < len(result_df): + row = result_df.iloc[i] + output_data = row #{key: row.get(key, None) for key in output_var_names} + + # Evaluate output expression + try: + output_value = evaluate_output_expression( + output_expression, + output_data + ) + log_info(f" Point {i+1}: {point} → {output_value:.6g}") + iteration_outputs.append(output_value) + except Exception as e: + available_vars = ', '.join(f"'{k}'" for k in output_data.keys()) + log_warning( + f" Point {i+1}: Failed to evaluate expression '{output_expression}': {e}\n" + f" Available output variables: {available_vars}" + ) + iteration_outputs.append(None) + else: + log_warning(f" Point {i+1}: No results") + iteration_outputs.append(None) + + except Exception as e: + log_error(f" ❌ Error evaluating batch: {e}") + # Add all points with None outputs + iteration_inputs = current_design + iteration_outputs = [None] * len(current_design) + + # Add iteration results to overall tracking + all_input_vars.extend(iteration_inputs) + all_output_values.extend(iteration_outputs) + + # Display intermediate results if the method exists + tmp_analysis_processed = get_and_process_analysis( + algo_instance, all_input_vars, all_output_values, + iteration, results_dir, 'get_analysis_tmp' + ) + if tmp_analysis_processed: + log_info(f"\n📊 Iteration {iteration} intermediate results:") + # Text logging is done inside _get_and_process_analysis + + # Save iteration results to files + try: + # Save X (input variables) to CSV + x_file = results_dir / f"X_{iteration}.csv" + with open(x_file, 'w') as f: + if all_input_vars: + # Get all variable names from the first entry + var_names = list(all_input_vars[0].keys()) + f.write(','.join(var_names) + '\n') + for inp in all_input_vars: + f.write(','.join(str(inp[var]) for var in var_names) + '\n') + + # Save Y (output values) to CSV + y_file = results_dir / f"Y_{iteration}.csv" + with open(y_file, 'w') as f: + f.write('output\n') + for val in all_output_values: + f.write(f"{val if val is not None else 'NA'}\n") + + # Save HTML results + html_file = results_dir / f"results_{iteration}.html" + html_content = f""" + + + + Iteration {iteration} Results + + + +

Algorithm Results - Iteration {iteration}

+
+

Summary

+

Total samples: {len(all_input_vars)}

+

Valid samples: {sum(1 for v in all_output_values if v is not None)}

+

Iteration: {iteration}

+
+""" + # Add intermediate results from get_analysis_tmp + if tmp_display_processed: + html_content += """ +
+

Intermediate Progress

+""" + # Link to analysis files if they were created + if 'html_file' in tmp_display_processed: + html_content += f'

📄 View HTML Analysis

\n' + if 'md_file' in tmp_display_processed: + html_content += f'

📄 View Markdown Analysis

\n' + if 'json_file' in tmp_display_processed: + html_content += f'

📄 View JSON Data

\n' + if 'txt_file' in tmp_display_processed: + html_content += f'

📄 View Text Data

\n' + if 'text' in tmp_display_processed: + html_content += f"
{tmp_display_processed['text']}
\n" + if 'data' in tmp_display_processed and tmp_display_processed['data']: + html_content += "

Data:

\n
\n"
+                        for key, value in tmp_display_processed['data'].items():
+                            html_content += f"{key}: {value}\n"
+                        html_content += "
\n" + html_content += "
\n" + + # Always call get_analysis for this iteration and process content + iter_analysis_processed = get_and_process_analysis( + algo_instance, all_input_vars, all_output_values, + iteration, results_dir, 'get_analysis' + ) + if iter_display_processed: + html_content += """ +
+

Current Results

+""" + # Link to analysis files if they were created + if 'html_file' in iter_display_processed: + html_content += f'

📄 View HTML Analysis

\n' + if 'md_file' in iter_display_processed: + html_content += f'

📄 View Markdown Analysis

\n' + if 'json_file' in iter_display_processed: + html_content += f'

📄 View JSON Data

\n' + if 'txt_file' in iter_display_processed: + html_content += f'

📄 View Text Data

\n' + if 'text' in iter_display_processed: + html_content += f"
{iter_display_processed['text']}
\n" + if 'data' in iter_display_processed and iter_display_processed['data']: + html_content += "

Data:

\n
\n"
+                        for key, value in iter_display_processed['data'].items():
+                            html_content += f"{key}: {value}\n"
+                        html_content += "
\n" + html_content += "
\n" + + html_content += """ + + +""" + with open(html_file, 'w') as f: + f.write(html_content) + + log_info(f" 💾 Saved iteration results: {x_file.name}, {y_file.name}, {html_file.name}") + + except Exception as e: + log_warning(f"⚠️ Failed to save iteration files: {e}") + + if _interrupt_requested: + break + + # Get next design from algorithm (only for variable inputs) + next_design_vars = algo_instance.get_next_design( + all_input_vars, + all_output_values + ) + + # Merge fixed values with algorithm-generated design + current_design = [] + for design_point in next_design_vars: + # Combine variable values (from algorithm) with fixed values + full_point = {**design_point, **fixed_input_vars} + current_design.append(full_point) + + # Get final analysis results + result = get_analysis( + algo_instance, all_input_vars, all_output_values, + output_expression, algorithm, iteration, results_dir + ) + + return result + + finally: + # Restore signal handler + _restore_signal_handler() + + # Always restore the original working directory + os.chdir(working_dir) + + if _interrupt_requested: + log_warning("⚠️ Execution was interrupted. Partial results may be available.") diff --git a/fz/helpers.py b/fz/helpers.py index 3e4f5b1..0a16a54 100644 --- a/fz/helpers.py +++ b/fz/helpers.py @@ -12,11 +12,120 @@ from contextlib import contextmanager from concurrent.futures import ThreadPoolExecutor, as_completed -from .logging import log_debug, log_info, log_warning, log_error, log_progress, get_log_level, LogLevel +# Optional pandas import for DataFrame support +try: + import pandas as pd + HAS_PANDAS = True +except ImportError: + HAS_PANDAS = False + +from .logging import log_debug, log_info, log_warning, log_error, log_progress from .config import get_config from .spinner import CaseSpinner, CaseStatus +def _get_windows_short_path(path: str) -> str: + r""" + Convert a Windows path with spaces to its short (8.3) name format. + + This is necessary because Python's subprocess module on Windows doesn't + properly handle spaces in the executable parameter when using shell=True. + + Args: + path: Windows file path + + Returns: + Short format path (e.g., C:\PROGRA~1\...) or original path if conversion fails + """ + if not path or ' ' not in path: + return path + + try: + import ctypes + from ctypes import wintypes + + GetShortPathName = ctypes.windll.kernel32.GetShortPathNameW + GetShortPathName.argtypes = [wintypes.LPCWSTR, wintypes.LPWSTR, wintypes.DWORD] + GetShortPathName.restype = wintypes.DWORD + + buffer = ctypes.create_unicode_buffer(260) + GetShortPathName(path, buffer, 260) + short_path = buffer.value + + if short_path: + log_debug(f"Converted path with spaces: {path} -> {short_path}") + return short_path + except Exception as e: + log_debug(f"Failed to get short path for {path}: {e}") + + return path + + +def get_windows_bash_executable() -> Optional[str]: + """ + Get the bash executable path on Windows. + + This function determines the appropriate bash executable to use on Windows + by checking both the system PATH and common installation locations. + + Priority order: + 1. Bash in system/user PATH (from MSYS2, Git Bash, WSL, Cygwin, etc.) + 2. MSYS2 bash at C:\\msys64\\usr\\bin\\bash.exe (preferred) + 3. Git for Windows bash + 4. Cygwin bash + 5. WSL bash + 6. win-bash + + Returns: + Optional[str]: Path to bash executable if found on Windows, None otherwise. + Returns None if not on Windows or if bash is not found. + """ + if platform.system() != "Windows": + return None + + # Try system/user PATH first + bash_in_path = shutil.which("bash") + if bash_in_path: + log_debug(f"Using bash from PATH: {bash_in_path}") + # Convert to short name if path contains spaces + return _get_windows_short_path(bash_in_path) + + # Check common bash installation paths, prioritizing MSYS2 + # Include both short names (8.3) and long names to handle various Git installations + bash_paths = [ + # MSYS2 bash (preferred - provides complete Unix environment) + r"C:\msys64\usr\bin\bash.exe", + # Git for Windows with short names (always works) + r"C:\Progra~1\Git\bin\bash.exe", + r"C:\Progra~2\Git\bin\bash.exe", + # Git for Windows with long names (may have spaces issue, will be converted) + r"C:\Program Files\Git\bin\bash.exe", + r"C:\Program Files (x86)\Git\bin\bash.exe", + # Also check usr/bin for newer Git for Windows + r"C:\Program Files\Git\usr\bin\bash.exe", + r"C:\Program Files (x86)\Git\usr\bin\bash.exe", + # Cygwin bash (alternative Unix environment) + r"C:\cygwin64\bin\bash.exe", + r"C:\cygwin\bin\bash.exe", + # WSL bash (almost always available on modern Windows) + r"C:\Windows\System32\bash.exe", + # win-bash + r"C:\win-bash\bin\bash.exe", + ] + + for bash_path in bash_paths: + if os.path.exists(bash_path): + log_debug(f"Using bash at: {bash_path}") + # Convert to short name if path contains spaces + return _get_windows_short_path(bash_path) + + # No bash found + log_warning( + "Bash not found on Windows. Commands may fail if they use bash-specific syntax." + ) + return None + + @contextmanager def fz_temporary_directory(session_cwd=None): """ @@ -40,7 +149,6 @@ def fz_temporary_directory(session_cwd=None): fz_tmp_base.mkdir(parents=True, exist_ok=True) # Create unique temp directory name - pid = os.getpid() unique_id = uuid.uuid4().hex[:12] timestamp = int(time.time()) temp_name = f"fz_temp_{unique_id}_{timestamp}" @@ -119,30 +227,57 @@ def _get_case_directories(var_combo: Dict, case_index: int, temp_path: Path, res return tmp_dir, result_dir, case_name -def generate_variable_combinations(input_variables: Dict) -> List[Dict]: +def generate_variable_combinations(input_variables: Union[Dict, Any]) -> List[Dict]: """ Generate variable combinations from input variables - - Converts input variables dict into a list of variable combinations. - If any value is a list, generates the cartesian product of all variables. - Single values are treated as single-element lists. - + + Supports two input formats: + 1. Dict: Creates Cartesian product (full factorial design) + - If any value is a list, generates the cartesian product of all variables + - Single values are treated as single-element lists + + 2. DataFrame: Non-factorial design + - Each row represents one case + - Column names become variable names + - Allows arbitrary combinations of values + Args: - input_variables: Dict of variable values or lists of values - + input_variables: Dict of variable values/lists OR pandas DataFrame + Returns: List of variable combination dicts - - Example: - >>> generate_variable_combinations({"x": [1, 2], "y": 3}) - [{"x": 1, "y": 3}, {"x": 2, "y": 3}] - + + Examples: + Dict (factorial design): + >>> generate_variable_combinations({"x": [1, 2], "y": [3, 4]}) + [{"x": 1, "y": 3}, {"x": 1, "y": 4}, {"x": 2, "y": 3}, {"x": 2, "y": 4}] + >>> generate_variable_combinations({"x": 1, "y": 2}) [{"x": 1, "y": 2}] + + DataFrame (non-factorial design): + >>> df = pd.DataFrame({"x": [1, 2, 3], "y": [10, 10, 20]}) + >>> generate_variable_combinations(df) + [{"x": 1, "y": 10}, {"x": 2, "y": 10}, {"x": 3, "y": 20}] """ + # Check if input is a pandas DataFrame + if isinstance(input_variables, pd.DataFrame): + # Each row is one case (non-factorial design) + var_combinations = [] + for _, row in input_variables.iterrows(): + var_combinations.append(row.to_dict()) + + log_info(f"📊 DataFrame input detected: {len(var_combinations)} cases (non-factorial design)") + return var_combinations + + # Original dict behavior (factorial design) + if not isinstance(input_variables, dict): + # If not dict and not DataFrame, raise error + raise TypeError(f"input_variables must be a dict or pandas DataFrame, got {type(input_variables)}") + var_names = list(input_variables.keys()) has_lists = any(isinstance(v, list) for v in input_variables.values()) - + if has_lists: list_values = [] for var in var_names: @@ -151,13 +286,13 @@ def generate_variable_combinations(input_variables: Dict) -> List[Dict]: list_values.append(val) else: list_values.append([val]) - + var_combinations = [ dict(zip(var_names, combo)) for combo in itertools.product(*list_values) ] else: var_combinations = [input_variables] - + return var_combinations @@ -328,14 +463,14 @@ def _resolve_model(model: Union[str, Dict]) -> Dict: def get_calculator_manager(): """ Get or create the global calculator manager instance - + Returns: CalculatorManager instance """ global _calculator_manager if _calculator_manager is None: - from .core import CalculatorManager - _calculator_manager = CalculatorManager() + from .runners import _calculator_manager as calc_mgr + _calculator_manager = calc_mgr return _calculator_manager @@ -498,7 +633,6 @@ def try_calculators_with_retry(non_cache_calculator_ids: List[str], case_index: "calculator_uri": "multiple_failed" } - used_calculator_uri = final_error.get("calculator_uri", "unknown") log_error(f"❌ [Thread {thread_id}] Case {case_index}: All {len(attempted_calculator_ids)} calculator attempts failed") # Convert calculator IDs back to URIs for logging attempted_uris = [calc_mgr.get_original_uri(calc_id) for calc_id in attempted_calculator_ids] @@ -520,7 +654,6 @@ def run_single_case(case_info: Dict) -> Dict[str, Any]: Returns: Dict with case results """ - from .runners import select_calculator_for_case, run_single_case_calculation from .io import resolve_cache_paths, find_cache_match from .core import fzo @@ -613,12 +746,19 @@ def run_single_case(case_info: Dict) -> Dict[str, Any]: # Validate that cached outputs don't contain None values try: cached_output = fzo(result_dir, model) - output_keys = list(model.get("output", {}).keys()) + + # Get all output columns (including flattened dict columns) + # We use all keys from cached_output to capture flattened dict columns + all_output_keys = list(cached_output.keys()) if hasattr(cached_output, 'keys') else cached_output.columns.tolist() + + # Filter out metadata columns + metadata_cols = ['path'] + output_columns = [k for k in all_output_keys if k not in metadata_cols] # Check if any expected output is None # Extract scalar values properly from DataFrame/dict returned by fzo none_keys = [] - for key in output_keys: + for key in output_columns: value = cached_output.get(key) # Extract scalar from pandas Series or list if hasattr(value, 'iloc'): @@ -822,7 +962,17 @@ def run_single_case(case_info: Dict) -> Dict[str, Any]: result_output = fzo(result_dir, model) log_debug(f"🔄 [Thread {thread_id}] {case_name}: Parsed output: {list(result_output.keys())}") - for key in output_keys: + + # Extract all columns from fzo result (includes flattened dict columns) + # We use all keys from result_output instead of just output_keys to capture + # flattened dict columns (e.g., if "stats" was a dict, we now have "min", "max", etc.) + all_output_keys = list(result_output.keys()) if hasattr(result_output, 'keys') else result_output.columns.tolist() + + # Filter out metadata columns (path, etc.) to only get output values + metadata_cols = ['path'] + output_columns = [k for k in all_output_keys if k not in metadata_cols] + + for key in output_columns: value = result_output.get(key) # Extract scalar from pandas Series if applicable if hasattr(value, 'iloc'): @@ -1087,7 +1237,6 @@ def run_cases_parallel(var_combinations: List[Dict], temp_path: Path, resultsdir # Progress tracking for multiple cases (only if spinner is disabled) if len(var_combinations) > 1 and not spinner.enabled: completed_count = i + 1 - case_elapsed = time.time() - case_start_time total_elapsed = time.time() - start_time # Estimate remaining time based on average time per case @@ -1277,7 +1426,11 @@ def compile_to_result_directories(input_path: str, model: Dict, input_variables: input_path = Path(input_path) # Determine if input_variables is non-empty - has_input_variables = bool(input_variables) + # Handle both dict and DataFrame input types + if isinstance(input_variables, pd.DataFrame): + has_input_variables = not input_variables.empty + else: + has_input_variables = bool(input_variables) # Ensure main results directory exists resultsdir.mkdir(parents=True, exist_ok=True) diff --git a/fz/installer.py b/fz/installer.py index 6425fc5..dec7d27 100644 --- a/fz/installer.py +++ b/fz/installer.py @@ -137,7 +137,6 @@ def extract_model_files(zip_path: Path, extract_dir: Path) -> Dict[str, Path]: # Second try: look for .fz/models/*.json if not model_json_paths: - fz_models_dir = extract_dir / '*' / '.fz' / 'models' model_json_paths = list(extract_dir.glob('*/.fz/models/*.json')) log_debug(f"Looking in .fz/models/: found {len(model_json_paths)} files") @@ -362,3 +361,247 @@ def list_installed_models(global_list: bool = False) -> Dict[str, Dict]: log_warning(f"Failed to load model {model_file}: {e}") return models + + +# ============================================================================ +# Algorithm Installation Functions +# ============================================================================ + + +def extract_algorithm_files(zip_path: Path, extract_dir: Path) -> Dict[str, Path]: + """ + Extract algorithm files from a zip archive + + The expected structure of an algorithm zip is: + - fz-algorithm-name-main/ + - algorithm.py or algorithm.R (algorithm implementation) + - README.md (optional) + - examples/ (optional) + + Args: + zip_path: Path to the zip file + extract_dir: Directory to extract to + + Returns: + Dict with 'algorithm_files' key pointing to list of algorithm files (.py or .R), + and 'algorithm_name' key with the algorithm name + + Raises: + Exception: If extraction fails or no algorithm files found + """ + log_info(f"Extracting: {zip_path}") + + try: + with zipfile.ZipFile(zip_path, 'r') as zip_ref: + zip_ref.extractall(extract_dir) + log_debug(f"Extracted files: {zip_ref.namelist()[:10]}") # Show first 10 files + except Exception as e: + raise Exception(f"Failed to extract {zip_path}: {e}") + + # Find algorithm files (.py or .R) + # Look in two places: + # 1. Algorithm files in the root (simple case) + # 2. .fz/algorithms/*.py or *.R (fz repository structure) + + log_debug(f"Searching for algorithm files in: {extract_dir}") + + # First try: look for .py/.R files in root + py_files = list(extract_dir.rglob('*.py')) + r_files = list(extract_dir.rglob('*.R')) + + # Filter out test files, setup files, etc. + def is_algorithm_file(path: Path) -> bool: + """Check if file is likely an algorithm implementation""" + name_lower = path.name.lower() + # Exclude common non-algorithm files + exclude_patterns = ['setup.py', 'test_', '_test.', 'conftest.py', '__init__.py'] + return not any(pattern in name_lower for pattern in exclude_patterns) + + py_files = [f for f in py_files if is_algorithm_file(f)] + r_files = [f for f in r_files if is_algorithm_file(f)] + + # Second try: specifically look for .fz/algorithms/*.py or *.R + fz_algo_py = list(extract_dir.glob('*/.fz/algorithms/*.py')) + fz_algo_r = list(extract_dir.glob('*/.fz/algorithms/*.R')) + + # Combine and prioritize .fz/algorithms/ files if they exist + if fz_algo_py or fz_algo_r: + algorithm_files = fz_algo_py + fz_algo_r + log_debug(f"Found {len(algorithm_files)} algorithm files in .fz/algorithms/") + else: + algorithm_files = py_files + r_files + log_debug(f"Found {len(algorithm_files)} algorithm files in root") + + if not algorithm_files: + # List what we did find to help debugging + all_files = list(extract_dir.rglob('*')) + log_debug(f"Files found in extraction: {[str(f.relative_to(extract_dir)) for f in all_files[:20]]}") + raise Exception(f"No algorithm files (.py or .R) found in extracted archive. Extracted to: {extract_dir}") + + # Extract algorithm name from first file + # For fz-algorithm repositories, the file is typically named after the algorithm + algorithm_file = algorithm_files[0] + algorithm_name = algorithm_file.stem + log_info(f"Found algorithm file: {algorithm_file}") + + return { + 'algorithm_files': algorithm_files, + 'algorithm_name': algorithm_name, + 'extract_dir': algorithm_file.parent + } + + +def install_algorithm(source: str, global_install: bool = False) -> Dict[str, str]: + """ + Install an algorithm from a source (GitHub name, URL, or local zip file) + + Args: + source: Algorithm source to install from + - GitHub name: "montecarlo" → "https://github.com/Funz/fz-montecarlo" + - Full URL: "https://github.com/user/fz-myalgo" + - Local zip: "fz-myalgo.zip" + global_install: If True, install to ~/.fz/algorithms/, else to ./.fz/algorithms/ + + Returns: + Dict with 'algorithm_name' and 'install_path' keys + + Raises: + Exception: If installation fails + """ + # Determine installation directory + if global_install: + install_base = Path.home() / '.fz' / 'algorithms' + else: + install_base = Path.cwd() / '.fz' / 'algorithms' + + install_base.mkdir(parents=True, exist_ok=True) + + # Create a temporary directory for download and extraction + with tempfile.TemporaryDirectory() as temp_dir: + temp_path = Path(temp_dir) + + try: + # Download the algorithm (reuse download_model function) + zip_path = download_model(source, temp_path) + + # Extract the algorithm files + extract_path = temp_path / 'extract' + extract_path.mkdir(exist_ok=True) + algo_info = extract_algorithm_files(zip_path, extract_path) + + algorithm_name = algo_info['algorithm_name'] + algorithm_files = algo_info['algorithm_files'] + + # Install the algorithm file(s) + installed_files = [] + for algo_file in algorithm_files: + # Use the original filename for installation + dest_file = install_base / algo_file.name + shutil.copy2(algo_file, dest_file) + installed_files.append(str(dest_file)) + log_info(f"Installed algorithm '{algo_file.name}' to: {dest_file}") + + return { + 'algorithm_name': algorithm_name, + 'install_path': str(installed_files[0]), + 'all_files': installed_files + } + + except Exception as e: + log_error(f"Algorithm installation failed: {e}") + raise + + +def uninstall_algorithm(algorithm_name: str, global_uninstall: bool = False) -> bool: + """ + Uninstall an algorithm + + Args: + algorithm_name: Name of the algorithm to uninstall (without extension) + global_uninstall: If True, uninstall from ~/.fz/algorithms/, else from ./.fz/algorithms/ + + Returns: + True if successful, False otherwise + """ + if global_uninstall: + install_base = Path.home() / '.fz' / 'algorithms' + else: + install_base = Path.cwd() / '.fz' / 'algorithms' + + # Try both .py and .R extensions + removed_any = False + for ext in ['.py', '.R']: + algo_path = install_base / f"{algorithm_name}{ext}" + if algo_path.exists(): + try: + algo_path.unlink() + log_info(f"Uninstalled algorithm '{algorithm_name}{ext}'") + removed_any = True + except Exception as e: + log_error(f"Failed to uninstall algorithm '{algorithm_name}{ext}': {e}") + return False + + if not removed_any: + log_warning(f"Algorithm '{algorithm_name}' not found at: {install_base}") + return False + + return True + + +def list_installed_algorithms(global_list: bool = False) -> Dict[str, Dict]: + """ + List installed algorithms + + Args: + global_list: If True, list from ~/.fz/algorithms/, else from ./.fz/algorithms/ + If False, lists from both locations and marks each with 'global' property + + Returns: + Dict mapping algorithm names to their info (with 'global' property added) + """ + algorithms = {} + + if global_list: + # Only list global algorithms + install_base = Path.home() / '.fz' / 'algorithms' + if install_base.exists(): + for algo_file in install_base.glob('*'): + if algo_file.suffix in ['.py', '.R'] and algo_file.is_file(): + algo_name = algo_file.stem + algorithms[algo_name] = { + 'name': algo_name, + 'file': str(algo_file), + 'type': 'Python' if algo_file.suffix == '.py' else 'R', + 'global': True + } + else: + # List from both local and global, marking each + # First, check local algorithms + local_base = Path.cwd() / '.fz' / 'algorithms' + if local_base.exists(): + for algo_file in local_base.glob('*'): + if algo_file.suffix in ['.py', '.R'] and algo_file.is_file(): + algo_name = algo_file.stem + algorithms[algo_name] = { + 'name': algo_name, + 'file': str(algo_file), + 'type': 'Python' if algo_file.suffix == '.py' else 'R', + 'global': False + } + + # Then check global algorithms (but don't override local ones) + global_base = Path.home() / '.fz' / 'algorithms' + if global_base.exists(): + for algo_file in global_base.glob('*'): + if algo_file.suffix in ['.py', '.R'] and algo_file.is_file(): + algo_name = algo_file.stem + # Only add if not already present (local takes precedence) + if algo_name not in algorithms: + algorithms[algo_name] = { + 'name': algo_name, + 'file': str(algo_file), + 'type': 'Python' if algo_file.suffix == '.py' else 'R', + 'global': True + } + + return algorithms diff --git a/fz/interpreter.py b/fz/interpreter.py index 210f9a3..2a29c45 100644 --- a/fz/interpreter.py +++ b/fz/interpreter.py @@ -190,6 +190,9 @@ def evaluate_formulas(content: str, model: Dict, input_variables: Dict, interpre # Extract the code part and preserve any indentation from original code_part = stripped[len(commentline + formulaprefix):] context_lines.append(code_part) + # If delimiters are empty, skip formula evaluation (no formulas possible) + if len(delim) == 0: + return content # If delimiters are empty, skip formula evaluation (no formulas possible) if len(delim) == 0: @@ -393,4 +396,4 @@ def cast_output(value: str) -> Any: pass # Return as string - return value \ No newline at end of file + return value diff --git a/fz/io.py b/fz/io.py index 8ca31cb..035dcff 100644 --- a/fz/io.py +++ b/fz/io.py @@ -7,11 +7,16 @@ import json import hashlib from pathlib import Path -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Any, TYPE_CHECKING -from .logging import log_info +from .logging import log_info, log_warning from datetime import datetime +if TYPE_CHECKING: + import pandas + +import pandas as pd + def ensure_unique_directory(directory_path: Path) -> tuple[Path, Optional[Path]]: """ @@ -220,7 +225,7 @@ def find_cache_match(cache_base_path: Path, current_hash_file: Path) -> Optional print(f"Could not read cache hash file {cache_hash_file}: {e}") continue - print(f"No cache match found in {cache_base_path} or its subdirectories") + log_info(f"No cache match found in {cache_base_path} or its subdirectories") return None @@ -236,4 +241,361 @@ def load_aliases(name: str, alias_type: str = "models") -> Optional[Dict]: return json.load(f) except (json.JSONDecodeError, IOError): continue - return None \ No newline at end of file + return None + + +def detect_content_type(text: str) -> str: + """ + Detect the type of content in a text string. + + Returns: 'html', 'json', 'keyvalue', 'markdown', or 'plain' + """ + if not text or not isinstance(text, str): + return 'plain' + + text_stripped = text.strip() + + # Check for HTML tags + if re.search(r'<(html|div|p|h1|h2|h3|img|table|body|head)', text_stripped, re.IGNORECASE): + return 'html' + + # Check for JSON (starts with { or [) + if text_stripped.startswith(('{', '[')): + try: + json.loads(text_stripped) + return 'json' + except (json.JSONDecodeError, ValueError): + pass + + # Check for markdown (has markdown syntax like #, ##, *, -, ```, etc.) + markdown_patterns = [ + r'^#{1,6}\s+.+$', # Headers + r'^\*\*.+\*\*$', # Bold + r'^_.+_$', # Italic + r'^\[.+\]\(.+\)$', # Links + r'^```', # Code blocks + r'^\* .+$', # Unordered lists + r'^\d+\. .+$', # Ordered lists + ] + for pattern in markdown_patterns: + if re.search(pattern, text_stripped, re.MULTILINE): + return 'markdown' + + # Check for key=value format (at least 2 lines with = signs) + lines = text_stripped.split('\n') + kv_lines = [l for l in lines if '=' in l and not l.strip().startswith('#')] + if len(kv_lines) >= 2: + # Verify they look like key=value pairs + if all(len(l.split('=', 1)) == 2 for l in kv_lines[:3]): + return 'keyvalue' + + return 'plain' + + +def parse_keyvalue_text(text: str) -> Dict[str, str]: + """Parse key=value text into a dictionary.""" + result = {} + for line in text.strip().split('\n'): + line = line.strip() + if not line or line.startswith('#'): + continue + if '=' in line: + key, value = line.split('=', 1) + result[key.strip()] = value.strip() + return result + + +def process_analysis_content( + analysis_dict: Dict[str, Any], + iteration: int, + results_dir: Path +) -> Dict[str, Any]: + """ + Process get_analysis() output, detecting content types and saving to files. + + Args: + analysis_dict: The dict returned by get_analysis() + iteration: Current iteration number + results_dir: Directory to save files + + Returns: + Processed dict with file references instead of raw content + """ + processed = {'data': analysis_dict.get('data', {})} + + # Process 'html' field if present + if 'html' in analysis_dict: + html_content = analysis_dict['html'] + html_file = results_dir / f"analysis_{iteration}.html" + with open(html_file, 'w') as f: + f.write(html_content) + processed['html_file'] = str(html_file.name) + log_info(f" 💾 Saved HTML to {html_file.name}") + + # Process 'text' field if present + if 'text' in analysis_dict: + text_content = analysis_dict['text'] + content_type = detect_content_type(text_content) + + if content_type == 'html': + # Save as HTML file + html_file = results_dir / f"analysis_{iteration}.html" + with open(html_file, 'w') as f: + f.write(text_content) + processed['html_file'] = str(html_file.name) + log_info(f" 💾 Detected HTML in text, saved to {html_file.name}") + + elif content_type == 'json': + # Parse JSON and save to file + json_file = results_dir / f"analysis_{iteration}.json" + try: + parsed_json = json.loads(text_content) + with open(json_file, 'w') as f: + json.dump(parsed_json, f, indent=2) + processed['json_data'] = parsed_json + processed['json_file'] = str(json_file.name) + log_info(f" 💾 Detected JSON, parsed and saved to {json_file.name}") + except Exception as e: + log_warning(f"⚠️ Failed to parse JSON: {e}") + processed['text'] = text_content + + elif content_type == 'keyvalue': + # Parse key=value format and save to file + txt_file = results_dir / f"analysis_{iteration}.txt" + with open(txt_file, 'w') as f: + f.write(text_content) + try: + parsed_kv = parse_keyvalue_text(text_content) + processed['keyvalue_data'] = parsed_kv + processed['txt_file'] = str(txt_file.name) + log_info(f" 💾 Detected key=value format, parsed and saved to {txt_file.name}") + except Exception as e: + log_warning(f"⚠️ Failed to parse key=value: {e}") + processed['text'] = text_content + + elif content_type == 'markdown': + # Save as markdown file + md_file = results_dir / f"analysis_{iteration}.md" + with open(md_file, 'w') as f: + f.write(text_content) + processed['md_file'] = str(md_file.name) + log_info(f" 💾 Detected markdown, saved to {md_file.name}") + + else: + # Keep as plain text + processed['text'] = text_content + + return processed + + +def flatten_dict_recursive(d: dict, parent_key: str = '', sep: str = '_') -> dict: + """ + Recursively flatten a nested dictionary. + + Args: + d: Dictionary to flatten + parent_key: Parent key prefix for nested keys + sep: Separator to use between nested keys + + Returns: + Flattened dictionary with keys joined by separator + """ + items = [] + for k, v in d.items(): + new_key = f"{parent_key}{sep}{k}" if parent_key else k + if isinstance(v, dict): + # Recursively flatten nested dict + items.extend(flatten_dict_recursive(v, new_key, sep=sep).items()) + else: + items.append((new_key, v)) + return dict(items) + + +def flatten_dict_columns(df: "pandas.DataFrame") -> "pandas.DataFrame": + """ + Recursively flatten dictionary-valued columns into separate columns. + + For each column containing dict values, creates new columns with the dict keys. + Nested dicts are flattened recursively with keys joined by '_'. + For example, {"stats": {"basic": {"min": 1, "max": 4}}} becomes: + - stats_basic_min: 1 + - stats_basic_max: 4 + + The original dict column is removed. + + Args: + df: DataFrame potentially containing dict-valued columns + + Returns: + DataFrame with dict columns recursively flattened + """ + + if df.empty: + return df + + # Keep flattening until no more dict columns remain + max_iterations = 10 # Prevent infinite loops + iteration = 0 + + while iteration < max_iterations: + iteration += 1 + + # Track which columns contain dicts and need to be flattened + dict_columns = [] + + for col in df.columns: + # Check if this column contains dict values + # Sample first non-None value to check type + sample_value = None + for val in df[col]: + if val is not None: + sample_value = val + break + + if isinstance(sample_value, dict): + dict_columns.append(col) + + if not dict_columns: + break # No more dict columns to flatten + + # Flatten each dict column + new_columns = {} + + for col in dict_columns: + # Process each row in this column + for row_idx, val in enumerate(df[col]): + if isinstance(val, dict): + # Recursively flatten this dict + flattened = flatten_dict_recursive(val, parent_key=col, sep='_') + + # Add flattened keys to new_columns + for flat_key, flat_val in flattened.items(): + if flat_key not in new_columns: + # Initialize column with None for all rows + new_columns[flat_key] = [None] * len(df) + new_columns[flat_key][row_idx] = flat_val + + # Create new DataFrame with original columns plus flattened dict columns + df = df.copy() + + # Add new columns + for col_name, values in new_columns.items(): + df[col_name] = values + + # Drop original dict columns + df = df.drop(columns=dict_columns) + + return df + + +def get_and_process_analysis( + algo_instance, + all_input_vars: List[Dict[str, float]], + all_output_values: List[float], + iteration: int, + results_dir: Path, + method_name: str = 'get_analysis' +) -> Optional[Dict[str, Any]]: + """ + Helper to call algorithm's analysis method and process the results. + + Args: + algo_instance: Algorithm instance + all_input_vars: All evaluated input combinations + all_output_values: All corresponding output values + iteration: Current iteration number + results_dir: Directory to save processed results + method_name: Name of the display method ('get_analysis' or 'get_analysis_tmp') + + Returns: + Processed analysis dict or None if method doesn't exist or fails + """ + if not hasattr(algo_instance, method_name): + return None + + try: + analysis_method = getattr(algo_instance, method_name) + analysis_dict = analysis_method(all_input_vars, all_output_values) + + if analysis_dict: + # Process and save content intelligently + processed = process_analysis_content(analysis_dict, iteration, results_dir) + # Also keep the original text/html for backward compatibility + processed['_raw'] = analysis_dict + return processed + return None + + except Exception as e: + log_warning(f"⚠️ {method_name} failed: {e}") + return None + + +def get_analysis( + algo_instance, + all_input_vars: List[Dict[str, float]], + all_output_values: List[float], + output_expression: str, + algorithm: str, + iteration: int, + results_dir: Path +) -> Dict[str, Any]: + """ + Create final analysis results with analysis information and DataFrame. + + Args: + algo_instance: Algorithm instance + all_input_vars: All evaluated input combinations + all_output_values: All corresponding output values + output_expression: Expression for output column name + algorithm: Algorithm path/name + iteration: Final iteration number + results_dir: Directory for saving results + + Returns: + Dict with analysis results including XY DataFrame and analysis info + """ + # Display final results + log_info("\n" + "="*60) + log_info("📈 Final Results") + log_info("="*60) + + # Get and process final analysis results + processed_final_analysis = get_and_process_analysis( + algo_instance, all_input_vars, all_output_values, + iteration, results_dir, 'get_analysis' + ) + + if processed_final_analysis and '_raw' in processed_final_analysis: + if 'text' in processed_final_analysis['_raw']: + log_info(processed_final_analysis['_raw']['text']) + # Remove _raw from returned dict - it's only for internal use + del processed_final_analysis['_raw'] + + # If processed_final_analysis is None, create empty dict for backward compatibility + if processed_final_analysis is None: + processed_final_analysis = {} + + # Create DataFrame with all input and output values + df_data = [] + for inp_dict, out_val in zip(all_input_vars, all_output_values): + row = inp_dict.copy() + row[output_expression] = out_val # Use output_expression as column name + df_data.append(row) + + data_df = pd.DataFrame(df_data) + + # Prepare return value + result = { + 'XY': data_df, # DataFrame with all X and Y values + 'analysis': processed_final_analysis, # Use processed analysis instead of raw + 'algorithm': algorithm, + 'iterations': iteration, + 'total_evaluations': len(all_input_vars), + } + + # Add summary + valid_count = sum(1 for v in all_output_values if v is not None) + summary = f"{algorithm} completed: {iteration} iterations, {len(all_input_vars)} evaluations ({valid_count} valid)" + result['summary'] = summary + + return result \ No newline at end of file diff --git a/fz/runners.py b/fz/runners.py index ccb9069..7a733aa 100644 --- a/fz/runners.py +++ b/fz/runners.py @@ -5,17 +5,13 @@ import os import subprocess import time -import re -import tarfile -import tempfile import hashlib import base64 -import threading -import queue import socket import platform -import shutil import uuid +import threading +from collections import defaultdict from .logging import log_error, log_warning, log_info, log_debug from .config import get_config @@ -178,6 +174,173 @@ def get_host_key_policy(password_provided: bool = False, auto_accept: bool = Fal return paramiko.AutoAddPolicy() +class CalculatorManager: + """Thread-safe calculator management for parallel execution""" + + def __init__(self): + self._lock = threading.Lock() + self._calculator_locks = defaultdict(threading.Lock) + self._calculator_owners = {} # calculator_id -> thread_id mapping + self._calculator_registry = {} # calculator_id -> original_uri mapping + + def register_calculator_instances(self, calculator_uris: List[str]) -> List[str]: + """ + Register calculator instances with unique IDs for each occurrence + + Args: + calculator_uris: List of calculator URIs (may contain duplicates) + + Returns: + List of unique calculator IDs + """ + calculator_ids = [] + with self._lock: + for uri in calculator_uris: + # Generate unique alphanumeric ID for tmux compatibility + unique_id = uuid.uuid4().hex[:8] + calc_id = f"{uri}#{unique_id}" + self._calculator_registry[calc_id] = uri + calculator_ids.append(calc_id) + return calculator_ids + + def get_original_uri(self, calculator_id: str) -> str: + """Get the original URI for a calculator ID""" + return self._calculator_registry.get(calculator_id, calculator_id) + + def acquire_calculator(self, calculator_id: str, thread_id: int) -> bool: + """ + Try to acquire exclusive access to a calculator + + Args: + calculator_id: Calculator ID to acquire + thread_id: Thread ID requesting the calculator + + Returns: + True if calculator was acquired, False if already in use + """ + calc_lock = self._calculator_locks[calculator_id] + + # Try to acquire the calculator lock (non-blocking) + acquired = calc_lock.acquire(blocking=False) + + if acquired: + with self._lock: + self._calculator_owners[calculator_id] = thread_id + original_uri = self.get_original_uri(calculator_id) + log_debug( + f"🔒 [Thread {thread_id}] Acquired calculator: {original_uri} (ID: {calculator_id})" + ) + return True + else: + current_owner = self._calculator_owners.get(calculator_id, "unknown") + original_uri = self.get_original_uri(calculator_id) + log_debug( + f"⏳ [Thread {thread_id}] Calculator {original_uri} (ID: {calculator_id}) is busy (owned by thread {current_owner})" + ) + return False + + def release_calculator(self, calculator_id: str, thread_id: int): + """ + Release exclusive access to a calculator + + Args: + calculator_id: Calculator ID to release + thread_id: Thread ID releasing the calculator + """ + try: + with self._lock: + if calculator_id in self._calculator_owners: + del self._calculator_owners[calculator_id] + + calc_lock = self._calculator_locks[calculator_id] + calc_lock.release() + original_uri = self.get_original_uri(calculator_id) + log_debug( + f"🔓 [Thread {thread_id}] Released calculator: {original_uri} (ID: {calculator_id})" + ) + except Exception as e: + original_uri = self.get_original_uri(calculator_id) + log_warning( + f"⚠️ [Thread {thread_id}] Error releasing calculator {original_uri} (ID: {calculator_id}): {e}" + ) + + def get_available_calculator( + self, calculator_ids: List[str], thread_id: int, case_index: int + ) -> Optional[str]: + """ + Get an available calculator from the list, preferring round-robin distribution + + Args: + calculator_ids: List of calculator IDs to choose from + thread_id: Thread ID requesting a calculator + case_index: Case index for round-robin distribution + + Returns: + Available calculator ID or None if all are busy + """ + if not calculator_ids: + return None + + # Try round-robin selection first + preferred_index = case_index % len(calculator_ids) + preferred_calc = calculator_ids[preferred_index] + + if self.acquire_calculator(preferred_calc, thread_id): + return preferred_calc + + # If preferred calculator is busy, try others + for calc in calculator_ids: + if calc != preferred_calc and self.acquire_calculator(calc, thread_id): + return calc + + # All calculators are busy + return None + + def cleanup_all_calculators(self): + """ + Release all calculator locks and clear internal state + + This should be called when fzr execution is complete to ensure + proper cleanup of resources. + """ + with self._lock: + # Force release all calculator locks + for calc_id, calc_lock in self._calculator_locks.items(): + try: + # Try to release the lock (may fail if not held) + if calc_id in self._calculator_owners: + thread_id = self._calculator_owners[calc_id] + log_debug( + f"🧹 Cleanup: Force-releasing calculator {calc_id} from thread {thread_id}" + ) + calc_lock.release() + except Exception as e: + # Lock might not be held, which is fine + pass + + # Clear all state + self._calculator_locks.clear() + self._calculator_owners.clear() + self._calculator_registry.clear() + self._next_id = 1 + + log_debug("🧹 CalculatorManager cleanup completed") + + def get_active_calculators(self) -> Dict[str, int]: + """ + Get currently active calculators and their owners + + Returns: + Dict mapping calculator ID to thread ID for active calculators + """ + with self._lock: + return dict(self._calculator_owners) + + +# Global instance +_calculator_manager = CalculatorManager() + + def validate_ssh_connection_security( host: str, username: str, password: Optional[str] ) -> Dict[str, Any]: @@ -867,7 +1030,7 @@ def run_local_calculation( # Construct command - resolve ALL file paths to absolute for reliable parallel execution if command: resolved_command, was_changed = resolve_all_paths_in_command( - command, original_cwd + command.replace("\\","/"), original_cwd ) # Apply shell path resolution to command if FZ_SHELL_PATH is set diff --git a/fz/shell.py b/fz/shell.py index 0a8851c..ca08832 100644 --- a/fz/shell.py +++ b/fz/shell.py @@ -407,7 +407,6 @@ def replace_commands_in_string(self, command_string: str) -> str: pattern = r'\b' + re.escape(cmd) + r'\b' # Use a lambda function to properly handle backslashes in the replacement modified = re.sub(pattern, lambda m: resolved_path, modified) - #log_debug(f"Replaced '{cmd}' with '{resolved_path}' in command string") return modified diff --git a/fz/spinner.py b/fz/spinner.py index 26dbdea..9db3823 100644 --- a/fz/spinner.py +++ b/fz/spinner.py @@ -76,6 +76,13 @@ def stop(self, clear: bool = False): if self.thread: self.thread.join(timeout=1.0) + # Render final status line to show "Total time:" + if not clear: + final_status = self._build_status_line() + sys.stdout.write('\r' + final_status) + sys.stdout.flush() + self.last_output = final_status + if clear and self.last_output: # Clear the line sys.stdout.write('\r' + ' ' * len(self.last_output) + '\r') @@ -153,7 +160,7 @@ def _build_status_line(self) -> str: completed = sum(1 for s in self.statuses if s in (CaseStatus.DONE, CaseStatus.FAILED)) remaining = self.num_cases - completed - # Calculate ETA + # Calculate ETA or Total time if remaining > 0 and self.case_durations: # Use average duration of completed cases avg_duration = sum(self.case_durations) / len(self.case_durations) @@ -163,8 +170,12 @@ def _build_status_line(self) -> str: # No completed cases yet, show calculating eta_text = "ETA: ..." else: - # All cases completed - eta_text = "Done" + # All cases completed - show total time + if self.start_time is not None: + total_time = time.time() - self.start_time + eta_text = f"Total time: {self._format_eta(total_time)}" + else: + eta_text = "Done" # Build final line status_line = f"[{''.join(chars)}] {eta_text}" @@ -220,6 +231,7 @@ def __enter__(self): def __exit__(self, exc_type, exc_val, exc_tb): """Context manager exit""" if self.enabled: - self.stop(clear=True) + # Stop but don't clear - keep the final status visible + self.stop(clear=False) # Print final newline to move to next line print() diff --git a/pyproject.toml b/pyproject.toml index a42a89d..561c949 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ classifiers = [ requires-python = ">=3.8" dependencies = [ "paramiko>=2.7.0", + "pandas>=1.0.0", ] [project.optional-dependencies] diff --git a/tests/pytest.ini b/pytest.ini similarity index 88% rename from tests/pytest.ini rename to pytest.ini index ef0781f..fe7b1a2 100644 --- a/tests/pytest.ini +++ b/pytest.ini @@ -1,4 +1,4 @@ -[tool:pytest] +[pytest] testpaths = tests python_files = test_*.py python_classes = Test* @@ -8,6 +8,7 @@ python_functions = test_* markers = slow: marks tests as slow (may require external tools) integration: marks tests as integration tests + manual: marks tests that require manual interaction (skipped by default) requires_docker: marks tests that require Docker requires_omc: marks tests that require OpenModelica requires_ssh: marks tests that require SSH server on localhost diff --git a/setup.py b/setup.py index e735b80..a97c59d 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ python_requires=">=3.8", install_requires=[ "paramiko>=2.7.0", + "pandas>=1.0.0", ], extras_require={ "dev": [ @@ -24,9 +25,6 @@ "black", "flake8", ], - "pandas": [ - "pandas>=1.0.0", - ], "r": [ "rpy2>=3.4.0", ], @@ -38,6 +36,7 @@ "fzc=fz.cli:fzc_main", "fzo=fz.cli:fzo_main", "fzr=fz.cli:fzr_main", + "fzd=fz.cli:fzd_main", ], }, classifiers=[ diff --git a/tests/test_algorithm_installation.py b/tests/test_algorithm_installation.py new file mode 100644 index 0000000..b4c28d9 --- /dev/null +++ b/tests/test_algorithm_installation.py @@ -0,0 +1,593 @@ +""" +Test algorithm installation functionality + +Tests installation, uninstallation, and listing of algorithms +from GitHub repositories, URLs, and local zip files. +""" +import json +import os +import platform +import shutil +import tempfile +import zipfile +from pathlib import Path + +import pytest + + +# Determine if we're running on Windows +IS_WINDOWS = platform.system() == "Windows" + + +@pytest.fixture +def temp_workspace(): + """Create a temporary workspace for tests""" + tmpdir = tempfile.mkdtemp() + yield Path(tmpdir) + shutil.rmtree(tmpdir, ignore_errors=True) + + +@pytest.fixture +def test_algorithm_zip_py(temp_workspace): + """Create a test Python algorithm zip file""" + # Create algorithm structure + algo_dir = temp_workspace / "fz-testalgo-main" + algo_dir.mkdir(exist_ok=True) + + # Create algorithm implementation + algo_code = ''' +class TestAlgo: + """Simple test algorithm""" + def __init__(self, **options): + self.n_samples = options.get("n_samples", 10) + + def get_initial_design(self, input_vars, output_vars): + import random + random.seed(42) + samples = [] + for _ in range(self.n_samples): + sample = {} + for var, (min_val, max_val) in input_vars.items(): + sample[var] = random.uniform(min_val, max_val) + samples.append(sample) + return samples + + def get_next_design(self, X, Y): + return [] # One-shot sampling + + def get_analysis(self, X, Y): + valid_Y = [y for y in Y if y is not None] + mean = sum(valid_Y) / len(valid_Y) if valid_Y else 0 + return {"text": f"Mean: {mean:.2f}", "data": {"mean": mean}} +''' + + algo_file = algo_dir / "testalgo.py" + algo_file.write_text(algo_code) + + # Create zip file + zip_path = temp_workspace / "fz-testalgo.zip" + with zipfile.ZipFile(zip_path, 'w') as zf: + zf.write(algo_file, arcname="fz-testalgo-main/testalgo.py") + + return zip_path + + +@pytest.fixture +def test_algorithm_zip_r(temp_workspace): + """Create a test R algorithm zip file""" + # Create algorithm structure + algo_dir = temp_workspace / "fz-testalgor-main" + algo_dir.mkdir(exist_ok=True) + + # Create R algorithm implementation + algo_code = ''' +TestAlgoR <- function(...) { + opts <- list(...) + state <- new.env(parent = emptyenv()) + state$n_samples <- 0 + + obj <- list( + options = list( + n_samples = as.integer(ifelse(is.null(opts$n_samples), 10, opts$n_samples)) + ), + state = state + ) + + class(obj) <- "TestAlgoR" + return(obj) +} + +get_initial_design.TestAlgoR <- function(obj, input_variables, output_variables) { + set.seed(42) + samples <- list() + for (i in 1:obj$options$n_samples) { + sample <- list() + for (var in names(input_variables)) { + bounds <- input_variables[[var]] + sample[[var]] <- runif(1, bounds[1], bounds[2]) + } + samples[[i]] <- sample + } + return(samples) +} + +get_next_design.TestAlgoR <- function(obj, X, Y) { + return(list()) +} + +get_analysis.TestAlgoR <- function(obj, X, Y) { + valid_Y <- Y[!sapply(Y, is.null)] + mean_val <- mean(unlist(valid_Y)) + return(list(text = paste0("Mean: ", round(mean_val, 2)), data = list(mean = mean_val))) +} +''' + + algo_file = algo_dir / "testalgor.R" + algo_file.write_text(algo_code) + + # Create zip file + zip_path = temp_workspace / "fz-testalgor.zip" + with zipfile.ZipFile(zip_path, 'w') as zf: + zf.write(algo_file, arcname="fz-testalgor-main/testalgor.R") + + return zip_path + + +@pytest.fixture +def test_algorithm_zip_fz_structure(temp_workspace): + """Create algorithm zip with .fz/algorithms/ structure""" + # Create algorithm structure matching fz repository structure + algo_dir = temp_workspace / "fz-advanced-main" + fz_dir = algo_dir / ".fz" / "algorithms" + fz_dir.mkdir(parents=True, exist_ok=True) + + # Create algorithm implementation + algo_code = ''' +class AdvancedAlgo: + """Advanced test algorithm""" + def __init__(self, **options): + self.batch_size = options.get("batch_size", 5) + + def get_initial_design(self, input_vars, output_vars): + return [{"x": 0.5}] * self.batch_size + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": "Analysis complete", "data": {"count": len(X)}} +''' + + algo_file = fz_dir / "advanced.py" + algo_file.write_text(algo_code) + + # Create zip file + zip_path = temp_workspace / "fz-advanced.zip" + with zipfile.ZipFile(zip_path, 'w') as zf: + zf.write(algo_file, arcname="fz-advanced-main/.fz/algorithms/advanced.py") + + return zip_path + + +@pytest.fixture +def install_workspace(temp_workspace): + """Create a workspace with .fz directories for installation""" + fz_dir = temp_workspace / ".fz" + algo_dir = fz_dir / "algorithms" + algo_dir.mkdir(parents=True, exist_ok=True) + + return temp_workspace + + +class TestAlgorithmInstallation: + """Test algorithm installation functions""" + + def test_install_algorithm_from_local_zip_py(self, test_algorithm_zip_py, install_workspace): + """Test installing Python algorithm from local zip file""" + from fz.installer import install_algorithm + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + result = install_algorithm(str(test_algorithm_zip_py), global_install=False) + + assert result['algorithm_name'] == 'testalgo' + assert 'install_path' in result + + # Verify algorithm file was created + algo_file = install_workspace / ".fz" / "algorithms" / "testalgo.py" + assert algo_file.exists() + + # Verify can load the algorithm + from fz.algorithms import load_algorithm + algo = load_algorithm("testalgo", n_samples=5) + assert algo is not None + finally: + os.chdir(original_cwd) + + def test_install_algorithm_from_local_zip_r(self, test_algorithm_zip_r, install_workspace): + """Test installing R algorithm from local zip file""" + from fz.installer import install_algorithm + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + result = install_algorithm(str(test_algorithm_zip_r), global_install=False) + + assert result['algorithm_name'] == 'testalgor' + assert 'install_path' in result + + # Verify algorithm file was created + algo_file = install_workspace / ".fz" / "algorithms" / "testalgor.R" + assert algo_file.exists() + finally: + os.chdir(original_cwd) + + def test_install_algorithm_fz_structure(self, test_algorithm_zip_fz_structure, install_workspace): + """Test installing algorithm from .fz/algorithms/ structure""" + from fz.installer import install_algorithm + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + result = install_algorithm(str(test_algorithm_zip_fz_structure), global_install=False) + + assert result['algorithm_name'] == 'advanced' + + # Verify algorithm file was created + algo_file = install_workspace / ".fz" / "algorithms" / "advanced.py" + assert algo_file.exists() + finally: + os.chdir(original_cwd) + + def test_install_global_algorithm(self, test_algorithm_zip_py): + """Test installing algorithm globally to ~/.fz/algorithms/""" + from fz.installer import install_algorithm, uninstall_algorithm + + try: + result = install_algorithm(str(test_algorithm_zip_py), global_install=True) + + assert result['algorithm_name'] == 'testalgo' + + # Verify in global location + global_algo = Path.home() / ".fz" / "algorithms" / "testalgo.py" + assert global_algo.exists() + + finally: + # Cleanup: remove global installation + uninstall_algorithm('testalgo', global_uninstall=True) + + def test_install_overwrites_existing(self, test_algorithm_zip_py, install_workspace): + """Test that installing same algorithm twice overwrites""" + from fz.installer import install_algorithm + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + + # Install first time + result1 = install_algorithm(str(test_algorithm_zip_py), global_install=False) + assert result1['algorithm_name'] == 'testalgo' + + # Install again (should overwrite) + result2 = install_algorithm(str(test_algorithm_zip_py), global_install=False) + assert result2['algorithm_name'] == 'testalgo' + + # Should still exist + algo_file = install_workspace / ".fz" / "algorithms" / "testalgo.py" + assert algo_file.exists() + finally: + os.chdir(original_cwd) + + def test_install_invalid_zip(self, temp_workspace, install_workspace): + """Test error handling for invalid zip file""" + from fz.installer import install_algorithm + + # Create an empty zip file + invalid_zip = temp_workspace / "invalid.zip" + with zipfile.ZipFile(invalid_zip, 'w') as zf: + pass # Empty zip + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + with pytest.raises(Exception, match="No algorithm files"): + install_algorithm(str(invalid_zip), global_install=False) + finally: + os.chdir(original_cwd) + + +class TestAlgorithmUninstallation: + """Test algorithm uninstallation functions""" + + def test_uninstall_algorithm(self, test_algorithm_zip_py, install_workspace): + """Test uninstalling an algorithm""" + from fz.installer import install_algorithm, uninstall_algorithm + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + + # Install algorithm first + install_algorithm(str(test_algorithm_zip_py), global_install=False) + + # Verify it's installed + algo_file = install_workspace / ".fz" / "algorithms" / "testalgo.py" + assert algo_file.exists() + + # Uninstall + success = uninstall_algorithm('testalgo', global_uninstall=False) + assert success is True + + # Verify it's removed + assert not algo_file.exists() + finally: + os.chdir(original_cwd) + + def test_uninstall_nonexistent_algorithm(self, install_workspace): + """Test uninstalling non-existent algorithm returns False""" + from fz.installer import uninstall_algorithm + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + success = uninstall_algorithm('nonexistent', global_uninstall=False) + assert success is False + finally: + os.chdir(original_cwd) + + def test_uninstall_removes_both_py_and_r(self, test_algorithm_zip_py, test_algorithm_zip_r, install_workspace): + """Test that uninstall removes both .py and .R files if present""" + from fz.installer import install_algorithm, uninstall_algorithm + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + + # Install Python algorithm + install_algorithm(str(test_algorithm_zip_py), global_install=False) + + # Manually create an R version with same name + r_algo = install_workspace / ".fz" / "algorithms" / "testalgo.R" + r_algo.write_text("# R version") + + # Both should exist + py_algo = install_workspace / ".fz" / "algorithms" / "testalgo.py" + assert py_algo.exists() + assert r_algo.exists() + + # Uninstall by name (should remove both) + success = uninstall_algorithm('testalgo', global_uninstall=False) + assert success is True + + # Both should be removed + assert not py_algo.exists() + assert not r_algo.exists() + finally: + os.chdir(original_cwd) + + +class TestAlgorithmListing: + """Test algorithm listing functions""" + + def test_list_installed_algorithms_empty(self, install_workspace): + """Test listing when no algorithms are installed""" + from fz.installer import list_installed_algorithms + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + algorithms = list_installed_algorithms(global_list=False) + # Should return empty dict or only global algorithms + assert isinstance(algorithms, dict) + finally: + os.chdir(original_cwd) + + def test_list_installed_algorithms(self, test_algorithm_zip_py, test_algorithm_zip_r, install_workspace): + """Test listing installed algorithms""" + from fz.installer import install_algorithm, list_installed_algorithms + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + + # Install both Python and R algorithms + install_algorithm(str(test_algorithm_zip_py), global_install=False) + install_algorithm(str(test_algorithm_zip_r), global_install=False) + + # List algorithms + algorithms = list_installed_algorithms(global_list=False) + + assert 'testalgo' in algorithms + assert 'testalgor' in algorithms + + # Check algorithm info + testalgo_info = algorithms['testalgo'] + assert testalgo_info['type'] == 'Python' + assert testalgo_info['global'] is False + + testalgor_info = algorithms['testalgor'] + assert testalgor_info['type'] == 'R' + assert testalgor_info['global'] is False + finally: + os.chdir(original_cwd) + + def test_list_shows_global_flag(self, test_algorithm_zip_py, install_workspace): + """Test that list shows correct global flag""" + from fz.installer import install_algorithm, list_installed_algorithms, uninstall_algorithm + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + + # Install locally + install_algorithm(str(test_algorithm_zip_py), global_install=False) + + # Install globally with different name (to avoid conflict) + # We'll use the same zip but it will show up with same name + # Just install globally and check the flag + install_algorithm(str(test_algorithm_zip_py), global_install=True) + + # List all + algorithms = list_installed_algorithms(global_list=False) + + # Local should have priority, so testalgo should be marked as local + if 'testalgo' in algorithms: + # The local one takes priority in listing + assert algorithms['testalgo']['global'] is False + + finally: + os.chdir(original_cwd) + # Cleanup global installation + uninstall_algorithm('testalgo', global_uninstall=True) + + def test_list_global_only(self, test_algorithm_zip_py, install_workspace): + """Test listing only global algorithms""" + from fz.installer import install_algorithm, list_installed_algorithms, uninstall_algorithm + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + + # Install locally + install_algorithm(str(test_algorithm_zip_py), global_install=False) + + # List only global (should not show local algorithm) + algorithms = list_installed_algorithms(global_list=True) + + # testalgo should not appear in global list + assert 'testalgo' not in algorithms + + finally: + os.chdir(original_cwd) + + +class TestAlgorithmCLIIntegration: + """Test CLI integration for algorithm installation""" + + def test_cli_install_algorithm_help(self): + """Test fz install algorithm --help""" + from fz.cli import main + import sys + from io import StringIO + + # Save original + original_argv = sys.argv + original_stdout = sys.stdout + original_stderr = sys.stderr + + # Redirect output + sys.stdout = StringIO() + sys.stderr = StringIO() + sys.argv = ['fz', 'install', 'algorithm', '--help'] + + returncode = 0 + try: + returncode = main() + except SystemExit as e: + returncode = e.code if e.code is not None else 0 + finally: + output = sys.stdout.getvalue() + sys.stderr.getvalue() + sys.stdout = original_stdout + sys.stderr = original_stderr + sys.argv = original_argv + + assert returncode == 0 + assert 'algorithm' in output.lower() + + def test_cli_list_algorithms_help(self): + """Test fz list algorithms --help""" + from fz.cli import main + import sys + from io import StringIO + + # Save original + original_argv = sys.argv + original_stdout = sys.stdout + original_stderr = sys.stderr + + # Redirect output + sys.stdout = StringIO() + sys.stderr = StringIO() + sys.argv = ['fz', 'list', 'algorithms', '--help'] + + returncode = 0 + try: + returncode = main() + except SystemExit as e: + returncode = e.code if e.code is not None else 0 + finally: + output = sys.stdout.getvalue() + sys.stderr.getvalue() + sys.stdout = original_stdout + sys.stderr = original_stderr + sys.argv = original_argv + + assert returncode == 0 + assert 'algorithm' in output.lower() + + +class TestAlgorithmPythonAPI: + """Test Python API for algorithm installation""" + + def test_install_algo_function(self, test_algorithm_zip_py, install_workspace): + """Test fz.install_algorithm() function""" + import fz + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + + result = fz.install_algorithm(str(test_algorithm_zip_py), global_install=False) + + assert result['algorithm_name'] == 'testalgo' + + # Verify file exists + algo_file = install_workspace / ".fz" / "algorithms" / "testalgo.py" + assert algo_file.exists() + finally: + os.chdir(original_cwd) + + def test_uninstall_algo_function(self, test_algorithm_zip_py, install_workspace): + """Test fz.uninstall_algo() function""" + import fz + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + + # Install first + fz.install_algorithm(str(test_algorithm_zip_py), global_install=False) + + # Uninstall + success = fz.uninstall_algorithm('testalgo', global_uninstall=False) + + assert success is True + + # Verify removed + algo_file = install_workspace / ".fz" / "algorithms" / "testalgo.py" + assert not algo_file.exists() + finally: + os.chdir(original_cwd) + + def test_list_algorithms_function(self, test_algorithm_zip_py, install_workspace): + """Test fz.list_algorithms() function""" + import fz + + original_cwd = os.getcwd() + try: + os.chdir(install_workspace) + + # Install an algorithm + fz.install_algorithm(str(test_algorithm_zip_py), global_install=False) + + # List algorithms + algorithms = fz.list_installed_algorithms(global_list=False) + + assert 'testalgo' in algorithms + assert algorithms['testalgo']['type'] == 'Python' + finally: + os.chdir(original_cwd) + + +if __name__ == "__main__": + pytest.main([__file__, "-v"]) diff --git a/tests/test_algorithm_montecarlo.py b/tests/test_algorithm_montecarlo.py new file mode 100644 index 0000000..9f35311 --- /dev/null +++ b/tests/test_algorithm_montecarlo.py @@ -0,0 +1,120 @@ +#title: Estimate mean with given confidence interval range using Monte Carlo +#author: Yann Richet +#type: sampling +#options: batch_sample_size=10;max_iterations=100;confidence=0.9;target_confidence_range=1.0;seed=42 +#require: numpy;scipy;matplotlib;base64 + +class MonteCarlo_Uniform: + + options = {} + samples = [] + n_samples = 0 + variables = {} + + def __init__(self, **options): + # parse (numeric) options + self.options["batch_sample_size"] = int(options.get("batch_sample_size", 10)) + self.options["max_iterations"] = int(options.get("max_iterations", 100)) + self.options["confidence"] = float(options.get("confidence", 0.9)) + self.options["target_confidence_range"] = float(options.get("target_confidence_range", 1.0)) + + import numpy as np + from scipy import stats + np.random.seed(int(options.get("seed", 42))) + + def get_initial_design(self, input_variables, output_variables): + for v, bounds in input_variables.items(): + # bounds is already a tuple (min, max) from parse_input_vars + if isinstance(bounds, tuple) and len(bounds) == 2: + min_val, max_val = bounds + else: + # Fallback: parse bounds string if needed : [min;max] + bounds_str = str(bounds).strip("[]").split(";") + if len(bounds_str) != 2: + raise Exception(f"Input variable {v} must be defined with min and max values for MonteCarlo_Uniform sampling") + min_val = float(bounds_str[0]) + max_val = float(bounds_str[1]) + self.variables[v] = (min_val, max_val) + return self._generate_samples(self.options["batch_sample_size"]) + + def get_next_design(self, X, Y): + # check max iterations + if self.n_samples >= self.options["max_iterations"] * self.options["batch_sample_size"]: + return [] + # check confidence interval: compute empirical confidence interval (using kernel density) on Y, compare with target_confidence_range + import numpy as np + from scipy import stats + Y_array = np.array([y for y in Y if y is not None]) + if len(Y_array) < 2: + return self._generate_samples(self.options["batch_sample_size"]) + kde = stats.gaussian_kde(Y_array) + mean = np.mean(Y_array) + conf_int = stats.t.interval(self.options["confidence"], len(Y_array)-1, loc=mean, scale=stats.sem(Y_array)) + conf_range = conf_int[1] - conf_int[0] + if conf_range <= self.options["target_confidence_range"]: + return [] + # else generate new samples + return self._generate_samples(self.options["batch_sample_size"]) + + def _generate_samples(self, n): + import numpy as np + samples = [] + for _ in range(n): + sample = {} + for v, (min_val, max_val) in self.variables.items(): + sample[v] = np.random.uniform(min_val, max_val) + samples.append(sample) + self.n_samples += n + return samples + + def get_analysis(self, X, Y): + analysis_dict = {"text": "", "data": {}} + html_output = "" + import numpy as np + from scipy import stats + Y_array = np.array([y for y in Y if y is not None]) + if len(Y_array) < 2: + analysis_dict["text"] = "Not enough valid results to analysis statistics" + return analysis_dict + mean = np.mean(Y_array) + conf_int = stats.t.interval(self.options["confidence"], len(Y_array)-1, loc=mean, scale=stats.sem(Y_array)) + html_output += f"

Estimated mean: {mean}

" + html_output += f"

{self.options['confidence']*100}% confidence interval: [{conf_int[0]}, {conf_int[1]}]

" + + # Store data + analysis_dict["data"]["mean"] = mean + analysis_dict["data"]["confidence_interval"] = conf_int + analysis_dict["data"]["n_samples"] = len(Y_array) + + # Text output + analysis_dict["text"] = ( + f"Estimated mean: {mean:.6f}\n" + f"{self.options['confidence']*100}% confidence interval: [{conf_int[0]:.6f}, {conf_int[1]:.6f}]\n" + f"Number of valid samples: {len(Y_array)}" + ) + + # Try to plot histogram if matplotlib is available + try: + import matplotlib.pyplot as plt + import base64 + from io import BytesIO + + plt.figure() + plt.hist(Y_array, bins=20, density=True, alpha=0.6, color='g') + plt.title("Output Y histogram") + plt.xlabel("Y") + plt.ylabel("Density") + plt.grid() + + # base64 in html + buffered = BytesIO() + plt.savefig(buffered, format="png") + plt.close() + img_str = base64.b64encode(buffered.getvalue()).decode() + html_output += f'Histogram' + analysis_dict["html"] = html_output + except Exception as e: + # If plotting fails, just skip it + pass + + return analysis_dict diff --git a/tests/test_algorithm_plugins.py b/tests/test_algorithm_plugins.py new file mode 100644 index 0000000..b024d56 --- /dev/null +++ b/tests/test_algorithm_plugins.py @@ -0,0 +1,452 @@ +#!/usr/bin/env python3 +""" +Test algorithm plugin system + +This test suite verifies that: +1. Algorithms can be loaded by name from .fz/algorithms/ directory +2. Project-level plugins take priority over global plugins +3. Both .py and .R algorithms work as plugins +4. Direct paths still work as before +5. Helpful error messages when plugins not found +""" + +import pytest +from pathlib import Path +import shutil + +from fz.algorithms import load_algorithm, resolve_algorithm_path + + +class TestAlgorithmPluginResolution: + """Test algorithm plugin path resolution""" + + def test_resolve_direct_path(self): + """Test that direct paths are not resolved as plugins""" + # Paths with / should not be resolved + assert resolve_algorithm_path("path/to/algo.py") is None + assert resolve_algorithm_path("../algo.py") is None + + # Paths with extension should not be resolved + assert resolve_algorithm_path("algo.py") is None + assert resolve_algorithm_path("algo.R") is None + + def test_resolve_plugin_name(self, temp_test_dir): + """Test resolving plugin name to path""" + # Create .fz/algorithms/ directory + algo_dir = Path(temp_test_dir) / ".fz" / "algorithms" + algo_dir.mkdir(parents=True) + + # Create a test algorithm + algo_file = algo_dir / "testalgo.py" + algo_file.write_text(""" +class TestAlgo: + def __init__(self, **options): + pass + + def get_initial_design(self, input_vars, output_vars): + return [{"x": 0.5}] + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": "test"} +""") + + # Resolve plugin name + resolved = resolve_algorithm_path("testalgo") + + # Verify it found the plugin + assert resolved is not None + assert resolved.exists() + assert resolved.name == "testalgo.py" + + def test_resolve_plugin_with_r_extension(self, temp_test_dir): + """Test resolving R algorithm plugin""" + # Create .fz/algorithms/ directory + algo_dir = Path(temp_test_dir) / ".fz" / "algorithms" + algo_dir.mkdir(parents=True) + + # Create a test R algorithm + algo_file = algo_dir / "testalgo.R" + algo_file.write_text(""" +TestAlgo <- function(...) { + obj <- list() + class(obj) <- "TestAlgo" + return(obj) +} +""") + + # Resolve plugin name + resolved = resolve_algorithm_path("testalgo") + + # Verify it found the R plugin + assert resolved is not None + assert resolved.exists() + assert resolved.name == "testalgo.R" + + def test_resolve_plugin_python_priority_over_r(self, temp_test_dir): + """Test that .py plugin has priority over .R when both exist""" + # Create .fz/algorithms/ directory + algo_dir = Path(temp_test_dir) / ".fz" / "algorithms" + algo_dir.mkdir(parents=True) + + # Create both .py and .R algorithms with same name + py_file = algo_dir / "testalgo.py" + py_file.write_text("class TestAlgo: pass") + + r_file = algo_dir / "testalgo.R" + r_file.write_text("TestAlgo <- function() {}") + + # Resolve plugin name - should get .py first + resolved = resolve_algorithm_path("testalgo") + + # Verify it found the Python plugin (priority) + assert resolved is not None + assert resolved.name == "testalgo.py" + + def test_resolve_plugin_not_found(self, temp_test_dir): + """Test resolving non-existent plugin returns None""" + # Try to resolve non-existent plugin + resolved = resolve_algorithm_path("nonexistent") + + # Should return None + assert resolved is None + + +class TestAlgorithmPluginLoading: + """Test loading algorithms via plugin system""" + + def test_load_plugin_by_name(self, temp_test_dir): + """Test loading algorithm by plugin name""" + # Create .fz/algorithms/ directory + algo_dir = Path(temp_test_dir) / ".fz" / "algorithms" + algo_dir.mkdir(parents=True) + + # Create a test algorithm + algo_file = algo_dir / "myalgorithm.py" + algo_file.write_text(""" +class MyAlgorithm: + def __init__(self, **options): + self.batch_size = options.get("batch_size", 5) + + def get_initial_design(self, input_vars, output_vars): + return [{"x": float(i)} for i in range(self.batch_size)] + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": "Analysis complete", "data": {"count": len(X)}} +""") + + # Load by plugin name + algo = load_algorithm("myalgorithm", batch_size=3) + + # Test the algorithm works + design = algo.get_initial_design({"x": (0, 10)}, ["result"]) + assert len(design) == 3 + assert design[0]["x"] == 0.0 + + def test_load_plugin_from_global_directory(self, temp_test_dir, monkeypatch): + """Test loading algorithm from global ~/.fz/algorithms/""" + # Mock home directory + fake_home = Path(temp_test_dir) / "home" + fake_home.mkdir() + monkeypatch.setenv("HOME", str(fake_home)) + + # Create global .fz/algorithms/ directory + algo_dir = fake_home / ".fz" / "algorithms" + algo_dir.mkdir(parents=True) + + # Create a test algorithm in global directory + algo_file = algo_dir / "globalalgo.py" + algo_file.write_text(""" +class GlobalAlgo: + def __init__(self, **options): + pass + + def get_initial_design(self, input_vars, output_vars): + return [{"x": 1.0}] + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": "global"} +""") + + # Load by plugin name + algo = load_algorithm("globalalgo") + + # Test the algorithm works + design = algo.get_initial_design({"x": (0, 10)}, ["result"]) + assert len(design) == 1 + assert design[0]["x"] == 1.0 + + def test_load_plugin_project_priority_over_global(self, temp_test_dir, monkeypatch): + """Test that project-level plugin takes priority over global""" + # Mock home directory + fake_home = Path(temp_test_dir) / "home" + fake_home.mkdir() + monkeypatch.setenv("HOME", str(fake_home)) + + # Create global plugin + global_algo_dir = fake_home / ".fz" / "algorithms" + global_algo_dir.mkdir(parents=True) + global_file = global_algo_dir / "samename.py" + global_file.write_text(""" +class SameName: + def __init__(self, **options): + self.source = "global" + + def get_initial_design(self, input_vars, output_vars): + return [{"x": 999.0}] + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": self.source} +""") + + # Create project-level plugin (should have priority) + project_algo_dir = Path(temp_test_dir) / ".fz" / "algorithms" + project_algo_dir.mkdir(parents=True) + project_file = project_algo_dir / "samename.py" + project_file.write_text(""" +class SameName: + def __init__(self, **options): + self.source = "project" + + def get_initial_design(self, input_vars, output_vars): + return [{"x": 1.0}] + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": self.source} +""") + + # Load by plugin name - should get project-level + algo = load_algorithm("samename") + + # Verify it loaded the project-level one + design = algo.get_initial_design({"x": (0, 10)}, ["result"]) + assert design[0]["x"] == 1.0 # Not 999.0 from global + + analysis = algo.get_analysis([], []) + assert analysis["text"] == "project" + + def test_load_direct_path_still_works(self, temp_test_dir): + """Test that direct paths still work (backward compatibility)""" + # Create algorithm file in arbitrary location + algo_file = Path(temp_test_dir) / "direct_algo.py" + algo_file.write_text(""" +class DirectAlgo: + def __init__(self, **options): + pass + + def get_initial_design(self, input_vars, output_vars): + return [{"x": 42.0}] + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": "direct"} +""") + + # Load by direct path + algo = load_algorithm(str(algo_file)) + + # Verify it works + design = algo.get_initial_design({"x": (0, 10)}, ["result"]) + assert design[0]["x"] == 42.0 + + def test_load_plugin_not_found_error(self, temp_test_dir): + """Test helpful error message when plugin not found""" + # Try to load non-existent plugin + with pytest.raises(ValueError) as exc_info: + load_algorithm("nonexistent") + + # Verify error message is helpful + error_msg = str(exc_info.value) + assert "Plugin 'nonexistent' not found" in error_msg + assert ".fz/algorithms/nonexistent.py" in error_msg + assert "~/.fz/algorithms/nonexistent.py" in error_msg + + def test_load_plugin_with_options(self, temp_test_dir): + """Test passing options to plugin algorithm""" + # Create .fz/algorithms/ directory + algo_dir = Path(temp_test_dir) / ".fz" / "algorithms" + algo_dir.mkdir(parents=True) + + # Create algorithm that uses options + algo_file = algo_dir / "optionalgo.py" + algo_file.write_text(""" +class OptAlgo: + def __init__(self, **options): + self.value = options.get("value", 10) + self.name = options.get("name", "default") + + def get_initial_design(self, input_vars, output_vars): + return [{"x": float(self.value)}] + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": self.name, "data": {"value": self.value}} +""") + + # Load with options + algo = load_algorithm("optionalgo", value=42, name="test") + + # Verify options were passed + design = algo.get_initial_design({"x": (0, 10)}, ["result"]) + assert design[0]["x"] == 42.0 + + analysis = algo.get_analysis([], []) + assert analysis["text"] == "test" + assert analysis["data"]["value"] == 42 + + +class TestAlgorithmPluginWithRAlgorithms: + """Test plugin system with R algorithms""" + + @pytest.mark.skipif( + True, # Skip for now unless rpy2 is available + reason="R plugin tests require rpy2" + ) + def test_load_r_plugin_by_name(self, temp_test_dir): + """Test loading R algorithm by plugin name""" + try: + import rpy2 + except ImportError: + pytest.skip("rpy2 not available") + + # Create .fz/algorithms/ directory + algo_dir = Path(temp_test_dir) / ".fz" / "algorithms" + algo_dir.mkdir(parents=True) + + # Create R algorithm + algo_file = algo_dir / "ralgo.R" + algo_file.write_text(""" +RAlgo <- function(...) { + obj <- list( + options = list(), + state = new.env(parent = emptyenv()) + ) + class(obj) <- "RAlgo" + return(obj) +} + +get_initial_design.RAlgo <- function(obj, input_variables, output_variables) { + return(list(list(x = 1.0))) +} + +get_next_design.RAlgo <- function(obj, X, Y) { + return(list()) +} + +get_analysis.RAlgo <- function(obj, X, Y) { + return(list(text = "R plugin")) +} +""") + + # Load by plugin name + algo = load_algorithm("ralgo") + + # Test it works + design = algo.get_initial_design({"x": (0, 10)}, ["result"]) + assert len(design) == 1 + + +class TestAlgorithmPluginIntegration: + """Test plugin system integration with fzd""" + + def test_fzd_with_plugin_algorithm(self, temp_test_dir): + """Test using plugin algorithm with fzd""" + try: + import pandas as pd + except ImportError: + pytest.skip("pandas required for fzd") + + import fz + + # Create .fz/algorithms/ directory + algo_dir = Path(temp_test_dir) / ".fz" / "algorithms" + algo_dir.mkdir(parents=True) + + # Create simple sampling algorithm + algo_file = algo_dir / "simplesampler.py" + algo_file.write_text(""" +class SimpleSampler: + def __init__(self, **options): + self.n_samples = options.get("n_samples", 5) + self.iteration = 0 + + def get_initial_design(self, input_vars, output_vars): + import random + random.seed(42) + samples = [] + for _ in range(self.n_samples): + sample = {} + for var, (min_val, max_val) in input_vars.items(): + sample[var] = random.uniform(min_val, max_val) + samples.append(sample) + return samples + + def get_next_design(self, X, Y): + self.iteration += 1 + if self.iteration >= 1: + return [] + return self.get_initial_design({"x": (0, 10)}, []) + + def get_analysis(self, X, Y): + valid_Y = [y for y in Y if y is not None] + mean_val = sum(valid_Y) / len(valid_Y) if valid_Y else 0 + return { + "text": f"Mean: {mean_val:.2f}", + "data": {"mean": mean_val, "n_samples": len(valid_Y)} + } +""") + + # Create input template + input_file = Path(temp_test_dir) / "input.txt" + input_file.write_text("x=$x") + + # Create calculation script + calc_script = Path(temp_test_dir) / "calc.sh" + calc_script.write_text("""#!/bin/bash +source $1 +echo "result=$x" > output.txt +""") + calc_script.chmod(0o755) + + # Define model + model = { + "varprefix": "$", + "output": {"result": "grep result output.txt | cut -d= -f2"} + } + + # Run fzd with plugin algorithm + results = fz.fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm="simplesampler", # Plugin name! + calculators=[f"sh://bash {calc_script}"], + algorithm_options={"n_samples": 3}, + analysis_dir=str(Path(temp_test_dir) / "fzd_results") + ) + + # Verify results + assert "XY" in results + assert isinstance(results["XY"], pd.DataFrame) + assert len(results["XY"]) >= 3 + assert "x" in results["XY"].columns + assert "result" in results["XY"].columns diff --git a/tests/test_cli_commands.py b/tests/test_cli_commands.py index 6e320ba..6d18628 100644 --- a/tests/test_cli_commands.py +++ b/tests/test_cli_commands.py @@ -131,7 +131,10 @@ def temp_workspace(): def sample_input_file(temp_workspace): """Create a sample input file with variables""" input_file = temp_workspace / "input.txt" - input_file.write_text("x = ${var1}\ny = ${var2}\nz = ${var3}") + with input_file.open('w',newline='\n') as f: + f.write("x = ${var1}\n") + f.write("y = ${var2}\n") + f.write("z = ${var3}\n") return input_file @@ -270,7 +273,9 @@ def test_fzo_json_format(self, temp_workspace, sample_model): """Test fzo with JSON format""" # Create a simple output file output_file = temp_workspace / "output.txt" - output_file.write_text("x = 1.0\ny = 2.0") + with output_file.open('w',newline='\n') as f: + f.write("x = 1.0\n") + f.write("y = 2.0\n") # Use a simple model (same as input model for consistency) result = run_fz_cli_function('fzo_main', [ @@ -579,7 +584,7 @@ def test_install_from_local_zip(self, test_model_zip, install_workspace): try: os.chdir(install_workspace) result = run_fz_cli_function('main', [ - 'install', + 'install', 'model', str(test_model_zip) ]) @@ -604,7 +609,7 @@ def test_install_with_calculators(self, test_model_with_calculators, install_wor try: os.chdir(install_workspace) result = run_fz_cli_function('main', [ - 'install', + 'install', 'model', str(test_model_with_calculators) ]) @@ -637,13 +642,13 @@ def test_list_installed_models(self, test_model_zip, install_workspace): os.chdir(install_workspace) # Install a model first install_result = run_fz_cli_function('main', [ - 'install', + 'install', 'model', str(test_model_zip) ]) assert install_result.returncode == 0 # List models - result = run_fz_cli_function('main', ['list']) + result = run_fz_cli_function('main', ['list', 'models']) assert result.returncode == 0 assert "testmodel" in result.stdout @@ -661,7 +666,7 @@ def test_list_empty_models(self, temp_workspace): original_cwd = os.getcwd() try: os.chdir(empty_workspace) - result = run_fz_cli_function('main', ['list']) + result = run_fz_cli_function('main', ['list', 'models']) assert result.returncode == 0 # May show global models, just verify it runs without error @@ -679,7 +684,7 @@ def test_list_empty_models(self, temp_workspace): def test_install_invalid_source(self, temp_workspace): """Test error handling for invalid source""" result = run_fz_cli_function('main', [ - 'install', + 'install', 'model', str(temp_workspace / "nonexistent.zip") ]) @@ -690,7 +695,7 @@ def test_install_invalid_source(self, temp_workspace): def test_install_from_github_name(self, install_workspace): """Test installing from GitHub shortname (requires network)""" result = run_fz_cli_function('main', [ - 'install', + 'install', 'model', 'moret' ]) @@ -704,7 +709,7 @@ def test_install_from_github_name(self, install_workspace): def test_install_from_github_url(self, install_workspace): """Test installing from full GitHub URL (requires network)""" result = run_fz_cli_function('main', [ - 'install', + 'install', 'model', 'https://github.com/Funz/fz-moret' ]) @@ -720,14 +725,14 @@ def test_install_overwrites_existing(self, test_model_zip, install_workspace): os.chdir(install_workspace) # Install first time result1 = run_fz_cli_function('main', [ - 'install', + 'install', 'model', str(test_model_zip) ]) assert result1.returncode == 0 # Install again (should overwrite) result2 = run_fz_cli_function('main', [ - 'install', + 'install', 'model', str(test_model_zip) ]) assert result2.returncode == 0 @@ -749,7 +754,7 @@ def test_uninstall_model(self, test_model_zip, install_workspace): os.chdir(install_workspace) # Install model first install_result = run_fz_cli_function('main', [ - 'install', + 'install', 'model', str(test_model_zip) ]) assert install_result.returncode == 0 @@ -760,7 +765,7 @@ def test_uninstall_model(self, test_model_zip, install_workspace): # Uninstall result = run_fz_cli_function('main', [ - 'uninstall', + 'uninstall', 'model', 'testmodel' ]) @@ -778,7 +783,7 @@ def test_uninstall_nonexistent_model(self, install_workspace): try: os.chdir(install_workspace) result = run_fz_cli_function('main', [ - 'uninstall', + 'uninstall', 'model', 'nonexistent_model' ]) @@ -794,13 +799,13 @@ def test_list_shows_global_flag(self, test_model_zip, install_workspace): os.chdir(install_workspace) # Install a local model install_result = run_fz_cli_function('main', [ - 'install', + 'install', 'model', str(test_model_zip) ]) assert install_result.returncode == 0 # List models - result = run_fz_cli_function('main', ['list']) + result = run_fz_cli_function('main', ['list', 'models']) assert result.returncode == 0 # Should show local flag for installed model @@ -812,7 +817,7 @@ def test_global_install_and_uninstall(self, test_model_zip): """Test installing and uninstalling globally""" # Install globally result1 = run_fz_cli_function('main', [ - 'install', + 'install', 'model', str(test_model_zip), '--global' ]) @@ -825,7 +830,7 @@ def test_global_install_and_uninstall(self, test_model_zip): # Uninstall globally result2 = run_fz_cli_function('main', [ - 'uninstall', + 'uninstall', 'model', 'testmodel', '--global' ]) @@ -842,12 +847,12 @@ def test_list_global_only(self, test_model_zip, install_workspace): os.chdir(install_workspace) # Install locally run_fz_cli_function('main', [ - 'install', + 'install', 'model', str(test_model_zip) ]) # List only global (should not show local model) - result = run_fz_cli_function('main', ['list', '--global']) + result = run_fz_cli_function('main', ['list', 'models', '--global']) assert result.returncode == 0 # Local testmodel should not appear diff --git a/tests/test_current_dir_fix.py b/tests/test_current_dir_fix.py index a77d323..866bd4a 100644 --- a/tests/test_current_dir_fix.py +++ b/tests/test_current_dir_fix.py @@ -73,4 +73,4 @@ def test_current_dir_fix(): f"Path resolution incorrect: expected '{expected_path_normalized}' in command '{resolved_cmd_normalized}'" if __name__ == "__main__": - test_current_dir_fix() \ No newline at end of file + test_current_dir_fix() diff --git a/tests/test_dataframe_input.py b/tests/test_dataframe_input.py new file mode 100644 index 0000000..8a94677 --- /dev/null +++ b/tests/test_dataframe_input.py @@ -0,0 +1,345 @@ +""" +Test DataFrame input support for non-factorial designs + +Tests the ability to use pandas DataFrames as input_variables, +where each row represents one case (non-factorial design). +""" +import pytest +import tempfile +import shutil +from pathlib import Path +import pandas as pd + +from fz.helpers import generate_variable_combinations +import fz + + +class TestDataFrameInput: + """Test DataFrame input for non-factorial designs""" + + def test_dataframe_basic(self): + """Test basic DataFrame input with 3 cases""" + df = pd.DataFrame({ + "x": [1, 2, 3], + "y": [10, 20, 30] + }) + + var_combinations = generate_variable_combinations(df) + + assert len(var_combinations) == 3 + assert var_combinations[0] == {"x": 1, "y": 10} + assert var_combinations[1] == {"x": 2, "y": 20} + assert var_combinations[2] == {"x": 3, "y": 30} + + def test_dataframe_non_factorial(self): + """Test that DataFrame allows non-factorial combinations""" + # Non-factorial: only specific combinations + df = pd.DataFrame({ + "temp": [100, 200, 100, 300], + "pressure": [1.0, 1.0, 2.0, 1.5] + }) + + var_combinations = generate_variable_combinations(df) + + assert len(var_combinations) == 4 + assert var_combinations[0] == {"temp": 100, "pressure": 1.0} + assert var_combinations[1] == {"temp": 200, "pressure": 1.0} + assert var_combinations[2] == {"temp": 100, "pressure": 2.0} + assert var_combinations[3] == {"temp": 300, "pressure": 1.5} + + def test_dataframe_vs_dict_factorial(self): + """Test that dict creates factorial design while DataFrame doesn't""" + # Dict with lists creates Cartesian product (factorial) + dict_input = {"x": [1, 2], "y": [10, 20]} + dict_combinations = generate_variable_combinations(dict_input) + assert len(dict_combinations) == 4 # 2 x 2 = 4 cases + + # DataFrame with same values creates only specified combinations + df = pd.DataFrame({ + "x": [1, 2], + "y": [10, 20] + }) + df_combinations = generate_variable_combinations(df) + assert len(df_combinations) == 2 # Only 2 cases (rows) + + assert df_combinations[0] == {"x": 1, "y": 10} + assert df_combinations[1] == {"x": 2, "y": 20} + + def test_dataframe_single_row(self): + """Test DataFrame with single row""" + df = pd.DataFrame({ + "a": [42], + "b": [99] + }) + + var_combinations = generate_variable_combinations(df) + + assert len(var_combinations) == 1 + assert var_combinations[0] == {"a": 42, "b": 99} + + def test_dataframe_many_columns(self): + """Test DataFrame with many variables""" + df = pd.DataFrame({ + "var1": [1, 2], + "var2": [10, 20], + "var3": [100, 200], + "var4": [1000, 2000], + "var5": [10000, 20000] + }) + + var_combinations = generate_variable_combinations(df) + + assert len(var_combinations) == 2 + assert var_combinations[0] == {"var1": 1, "var2": 10, "var3": 100, "var4": 1000, "var5": 10000} + assert var_combinations[1] == {"var1": 2, "var2": 20, "var3": 200, "var4": 2000, "var5": 20000} + + def test_dataframe_mixed_types(self): + """Test DataFrame with mixed data types""" + df = pd.DataFrame({ + "int_var": [1, 2, 3], + "float_var": [1.5, 2.5, 3.5], + "str_var": ["a", "b", "c"] + }) + + var_combinations = generate_variable_combinations(df) + + assert len(var_combinations) == 3 + assert var_combinations[0] == {"int_var": 1, "float_var": 1.5, "str_var": "a"} + assert var_combinations[1] == {"int_var": 2, "float_var": 2.5, "str_var": "b"} + assert var_combinations[2] == {"int_var": 3, "float_var": 3.5, "str_var": "c"} + + def test_dataframe_with_repeated_values(self): + """Test DataFrame where same value appears multiple times""" + df = pd.DataFrame({ + "x": [1, 1, 2, 2, 2], + "y": [10, 20, 10, 20, 30] + }) + + var_combinations = generate_variable_combinations(df) + + assert len(var_combinations) == 5 + assert var_combinations[0] == {"x": 1, "y": 10} + assert var_combinations[1] == {"x": 1, "y": 20} + assert var_combinations[2] == {"x": 2, "y": 10} + assert var_combinations[3] == {"x": 2, "y": 20} + assert var_combinations[4] == {"x": 2, "y": 30} + + +class TestDataFrameWithFzr: + """Integration tests using DataFrame with fzr()""" + + def setup_method(self): + """Create temporary directory and test files for each test""" + self.test_dir = tempfile.mkdtemp() + self.test_path = Path(self.test_dir) + + # Create input template + # The sum formula will be evaluated by fz, so the result is already in input.txt + self.input_file = self.test_path / "input.txt" + with open(self.input_file, "w", newline='\n') as f: + f.write("x=$x\n") + f.write("y=$y\n") + f.write("sum=@{$x + $y}\n") + + # Create simple calculator script that reads from input.txt and computes result + # Use source and bash arithmetic like test_fzo_fzr_coherence.py does + self.calc_script = self.test_path / "calc.sh" + with open(self.calc_script, "w", newline='\n') as f: + f.write('#!/bin/bash\n') + f.write('source input.txt\n') + f.write('result=$((x + y))\n') + f.write('echo "result = $result" > output.txt\n') + self.calc_script.chmod(0o755) + + def teardown_method(self): + """Clean up temporary directory after each test""" + if self.test_path.exists(): + shutil.rmtree(self.test_path) + + def test_fzr_with_dataframe_basic(self): + """Test fzr() with DataFrame input""" + df = pd.DataFrame({ + "x": [1, 2, 3], + "y": [10, 20, 30] + }) + + model = { + "formulaprefix": "@", + "delim": "{}", + "commentline": "#", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2" + } + } + + results = fz.fzr( + str(self.input_file), + df, + model, + calculators=f"sh://bash {self.calc_script}", + results_dir=str(self.test_path / "results") + ) + + # Should have 3 cases from DataFrame + assert len(results) == 3 + + # Check that we got the expected x, y combinations (not factorial) + results_sorted = results.sort_values("x").reset_index(drop=True) + assert results_sorted["x"].tolist() == [1, 2, 3] + assert results_sorted["y"].tolist() == [10, 20, 30] + + # Results should be x + y + assert results_sorted["result"].tolist() == [11, 22, 33] + + def test_fzr_dataframe_vs_dict(self): + """Compare DataFrame (non-factorial) vs dict (factorial) behavior""" + model = { + "formulaprefix": "@", + "delim": "{}", + "commentline": "#", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2" + } + } + + # DataFrame: only 2 specific combinations + df = pd.DataFrame({ + "x": [1, 2], + "y": [10, 20] + }) + + results_df = fz.fzr( + str(self.input_file), + df, + model, + calculators=f"sh://bash {self.calc_script}", + results_dir=str(self.test_path / "results_df") + ) + + # Dict: 2x2 = 4 combinations (factorial) + dict_input = {"x": [1, 2], "y": [10, 20]} + + results_dict = fz.fzr( + str(self.input_file), + dict_input, + model, + calculators=f"sh://bash {self.calc_script}", + results_dir=str(self.test_path / "results_dict") + ) + + # DataFrame gives 2 cases + assert len(results_df) == 2 + assert results_df["x"].tolist() == [1, 2] + assert results_df["y"].tolist() == [10, 20] + assert results_df["result"].tolist() == [11, 22] + + # Dict gives 4 cases (factorial) + assert len(results_dict) == 4 + results_dict_sorted = results_dict.sort_values(["x", "y"]).reset_index(drop=True) + assert results_dict_sorted["x"].tolist() == [1, 1, 2, 2] + assert results_dict_sorted["y"].tolist() == [10, 20, 10, 20] + assert results_dict_sorted["result"].tolist() == [11, 21, 12, 22] + + def test_fzr_dataframe_non_factorial_pattern(self): + """Test DataFrame with non-factorial pattern (can't be created with dict)""" + # This pattern can't be created with a dict: + # x=1,y=10 and x=1,y=20 and x=2,y=20 (but NOT x=2,y=10) + df = pd.DataFrame({ + "x": [1, 1, 2], + "y": [10, 20, 20] + }) + + model = { + "formulaprefix": "@", + "delim": "{}", + "commentline": "#", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2" + } + } + + results = fz.fzr( + str(self.input_file), + df, + model, + calculators=f"sh://bash {self.calc_script}", + results_dir=str(self.test_path / "results") + ) + + assert len(results) == 3 + results_sorted = results.sort_values(["x", "y"]).reset_index(drop=True) + assert results_sorted["x"].tolist() == [1, 1, 2] + assert results_sorted["y"].tolist() == [10, 20, 20] + assert results_sorted["result"].tolist() == [11, 21, 22] + + +class TestInputValidation: + """Test input validation for input_variables""" + + def test_dict_input_still_works(self): + """Test that dict input still works as before""" + dict_input = {"x": [1, 2], "y": 3} + var_combinations = generate_variable_combinations(dict_input) + + assert len(var_combinations) == 2 + assert var_combinations[0] == {"x": 1, "y": 3} + assert var_combinations[1] == {"x": 2, "y": 3} + + def test_invalid_input_type(self): + """Test that invalid input type raises error""" + with pytest.raises(TypeError, match="input_variables must be a dict or pandas DataFrame"): + generate_variable_combinations([1, 2, 3]) + + with pytest.raises(TypeError, match="input_variables must be a dict or pandas DataFrame"): + generate_variable_combinations("invalid") + + with pytest.raises(TypeError, match="input_variables must be a dict or pandas DataFrame"): + generate_variable_combinations(42) + + +if __name__ == "__main__": + # Run tests + print("=" * 70) + print("Testing DataFrame Input Support") + print("=" * 70) + + test_df = TestDataFrameInput() + + print("\n1. Testing basic DataFrame input...") + test_df.test_dataframe_basic() + print("✓ Passed") + + print("\n2. Testing non-factorial combinations...") + test_df.test_dataframe_non_factorial() + print("✓ Passed") + + print("\n3. Testing DataFrame vs dict factorial...") + test_df.test_dataframe_vs_dict_factorial() + print("✓ Passed") + + print("\n4. Testing single row DataFrame...") + test_df.test_dataframe_single_row() + print("✓ Passed") + + print("\n5. Testing mixed data types...") + test_df.test_dataframe_mixed_types() + print("✓ Passed") + + print("\n6. Testing repeated values...") + test_df.test_dataframe_with_repeated_values() + print("✓ Passed") + + # Test input validation (doesn't require pandas) + test_validation = TestInputValidation() + + print("\n7. Testing dict input still works...") + test_validation.test_dict_input_still_works() + print("✓ Passed") + + print("\n8. Testing invalid input type...") + test_validation.test_invalid_input_type() + print("✓ Passed") + + print("\n" + "=" * 70) + print("ALL TESTS PASSED!") + print("=" * 70) diff --git a/tests/test_demos.py b/tests/test_demos.py new file mode 100644 index 0000000..ddd95d6 --- /dev/null +++ b/tests/test_demos.py @@ -0,0 +1,367 @@ +""" +Demo tests for fzd features + +These tests verify various fzd features work correctly by running +demonstrations that were previously standalone scripts. +""" + +import pytest +import fz +import tempfile +from pathlib import Path +import shutil +import logging + + +class TestAlgorithmAutoInstall: + """Test automatic package installation for algorithm requirements""" + + def test_load_algorithm_with_auto_install(self): + """Test that packages are automatically installed when loading an algorithm""" + # Create a test algorithm that requires a package + # We'll use 'six' as it's small and commonly used + test_algo_content = """ +#title: Test Algorithm with Package Requirement +#author: Test +#type: test +#require: six + +class TestAlgorithm: + def __init__(self, **options): + # Import the required package to verify it's installed + import six + self.options = options + + def get_initial_design(self, input_vars, output_vars): + return [{"x": 0.5}] + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": "Test", "data": {}} +""" + + # Create temporary file + with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f: + f.write(test_algo_content) + algo_file = f.name + + try: + # Load the algorithm - this should auto-install 'six' if not present + from fz.algorithms import load_algorithm + algo = load_algorithm(algo_file) + + # Verify the algorithm loaded successfully + assert algo is not None + + # Verify we can now import six + import six + assert six is not None + + finally: + # Clean up temporary file + Path(algo_file).unlink() + + +class TestDisplayResultsTmp: + """Test intermediate progress display using get_analysis_tmp""" + + def test_get_analysis_tmp_is_called(self): + """Test that get_analysis_tmp is called during fzd iterations""" + # Create temporary directory + tmpdir = Path(tempfile.mkdtemp()) + + try: + # Create input directory + input_dir = tmpdir / "input" + input_dir.mkdir() + + # Create input file + (input_dir / "input.txt").write_text("x = $x\ny = $y\n") + + # Define simple model + model = { + "varprefix": "$", + "delim": "()", + "run": "echo 'result = 1.0' > output.txt", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2 | tr -d ' '" + } + } + + # Path to montecarlo_uniform algorithm (has get_analysis_tmp) + import os + repo_root = Path(__file__).parent.parent + algo_path = str(repo_root / "examples" / "algorithms" / "montecarlo_uniform.py") + + # Run fzd with small batch to see multiple iterations + result = fz.fzd( + input_path=str(input_dir), + input_variables={"x": "[0;1]", "y": "[0;1]"}, + model=model, + output_expression="result", + algorithm=algo_path, + algorithm_options={ + "batch_sample_size": 3, # Small batches to see more iterations + "max_iterations": 5, + "target_confidence_range": 0.01, + "seed": 42 + } + ) + + # Verify result structure + assert 'XY' in result + assert 'analysis' in result + assert 'iterations' in result + assert result['iterations'] > 0 + + finally: + # Cleanup + shutil.rmtree(tmpdir) + + +class TestContentDetection: + """Test intelligent content detection and file saving""" + + def test_content_detection_with_different_formats(self): + """Test that fzd detects and processes different content types""" + # Create temporary directory + tmpdir = Path(tempfile.mkdtemp()) + + try: + # Create input directory + input_dir = tmpdir / "input" + input_dir.mkdir() + + # Create input file + (input_dir / "input.txt").write_text("x = $x\n") + + # Define simple model + model = { + "varprefix": "$", + "delim": "()", + "run": "echo 'result = 1.5' > output.txt", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2 | tr -d ' '" + } + } + + # Create algorithm with different content types in get_analysis + algo_file = tmpdir / "test_algo.py" + algo_file.write_text(""" +class TestContentAlgorithm: + def __init__(self, **options): + self.iteration = 0 + + def get_initial_design(self, input_vars, output_vars): + return [{"x": 0.5}] + + def get_next_design(self, X, Y): + self.iteration += 1 + if self.iteration < 2: + return [{"x": 0.7}] + return [] + + def get_analysis(self, X, Y): + # Return different content types based on iteration + if self.iteration == 0: + # First iteration: JSON content + return { + "text": '{"mean": 1.234, "std": 0.567, "samples": 1}', + "data": {"iteration": 0} + } + elif self.iteration == 1: + # Second iteration: Key=Value content + return { + "text": "mean = 1.345\\nstd = 0.432\\nsamples = 2", + "data": {"iteration": 1} + } + else: + # Final iteration: Markdown content + return { + "text": '# Final Results\\n\\nMean: 1.456', + "data": {"iteration": 2} + } + + def get_analysis_tmp(self, X, Y): + return {"text": f"Progress: {len(X)} samples", "data": {}} +""") + + # Run fzd + result = fz.fzd( + input_path=str(input_dir), + input_variables={"x": "[0;1]"}, + model=model, + output_expression="result", + algorithm=str(algo_file) + ) + + # Verify result structure + assert 'XY' in result + assert 'analysis' in result + + finally: + # Cleanup + shutil.rmtree(tmpdir) + + +class TestDataFrame: + """Test XY DataFrame returned by fzd""" + + def test_xy_dataframe_structure(self): + """Test that fzd returns XY DataFrame with correct structure""" + # Create temporary directory + tmpdir = Path(tempfile.mkdtemp()) + + try: + # Create input directory + input_dir = tmpdir / "input" + input_dir.mkdir() + + # Create input file + (input_dir / "input.txt").write_text("x = $x\ny = $y\n") + + # Define simple model + model = { + "varprefix": "$", + "delim": "()", + "run": "echo 'result = 1.0' > output.txt", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2 | tr -d ' '" + } + } + + # Use randomsampling algorithm + repo_root = Path(__file__).parent.parent + algo_path = str(repo_root / "examples" / "algorithms" / "randomsampling.py") + + # Run fzd + result = fz.fzd( + input_path=str(input_dir), + input_variables={"x": "[0;1]", "y": "[0;1]"}, + model=model, + output_expression="result", + algorithm=algo_path, + algorithm_options={"nvalues": 5, "seed": 42} + ) + + # Access the XY DataFrame + df = result['XY'] + + # Verify structure + assert df is not None + assert 'x' in df.columns + assert 'y' in df.columns + assert 'result' in df.columns # Output column named with output_expression + assert len(df) == 5 + + # Verify old keys are not present + assert 'input_vars' not in result + assert 'output_values' not in result + + # Verify new key is present + assert 'XY' in result + + finally: + # Cleanup + shutil.rmtree(tmpdir) + + +class TestProgressBar: + """Test progress bar with total time display""" + + def test_progress_bar_shows_total_time(self): + """Test that progress bar shows total time after completion""" + # Create temporary directory + tmpdir = Path(tempfile.mkdtemp()) + + try: + # Create input directory + input_dir = tmpdir / "input" + input_dir.mkdir() + + # Create input file + (input_dir / "input.txt").write_text("x = $x\ny = $y\n") + + # Define simple model + model = { + "varprefix": "$", + "delim": "()", + "run": "echo 'result = 1.0' > output.txt", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2 | tr -d ' '" + } + } + + # Use randomsampling algorithm + repo_root = Path(__file__).parent.parent + algo_path = str(repo_root / "examples" / "algorithms" / "randomsampling.py") + + # Run fzd + result = fz.fzd( + input_path=str(input_dir), + input_variables={"x": "[0;1]", "y": "[0;1]"}, + model=model, + output_expression="result", + algorithm=algo_path, + algorithm_options={"nvalues": 5, "seed": 42} + ) + + # Verify result was returned (progress bar didn't block) + assert result is not None + assert 'XY' in result + + finally: + # Cleanup + shutil.rmtree(tmpdir) + + +class TestParallelExecution: + """Test parallel calculator execution in fzd""" + + def test_parallel_execution_structure(self): + """Test that fzd executes cases in batches enabling parallelization""" + # Create temporary directory + tmpdir = Path(tempfile.mkdtemp()) + + try: + # Create input directory + input_dir = tmpdir / "input" + input_dir.mkdir() + + # Create input file + (input_dir / "input.txt").write_text("x = $x\ny = $y\n") + + # Define simple model + model = { + "varprefix": "$", + "delim": "()", + "run": "echo 'result = 1.0' > output.txt", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2 | tr -d ' '" + } + } + + # Path to randomsampling algorithm + repo_root = Path(__file__).parent.parent + algo_path = str(repo_root / "examples" / "algorithms" / "randomsampling.py") + + # Run fzd + result = fz.fzd( + input_path=str(input_dir), + input_variables={"x": "[0;1]", "y": "[0;1]"}, + model=model, + output_expression="result", + algorithm=algo_path, + algorithm_options={"nvalues": 5, "seed": 42} + ) + + # Verify result structure + assert 'total_evaluations' in result + assert result['total_evaluations'] > 0 + assert 'XY' in result + + finally: + # Cleanup + shutil.rmtree(tmpdir) diff --git a/tests/test_dict_flattening.py b/tests/test_dict_flattening.py new file mode 100644 index 0000000..9bad7bf --- /dev/null +++ b/tests/test_dict_flattening.py @@ -0,0 +1,536 @@ +""" +Test dict flattening functionality in fzo and fzr + +Tests the automatic recursive flattening of dictionary-valued outputs +into separate columns with keys joined by underscores. +""" +import json +import os +import platform +import shutil +import tempfile +from pathlib import Path + +import pytest +import pandas as pd + +import fz +from fz.io import flatten_dict_recursive, flatten_dict_columns + + +class TestFlattenDictRecursive: + """Test the flatten_dict_recursive helper function""" + + def test_simple_dict(self): + """Test flattening a simple flat dict""" + d = {'a': 1, 'b': 2, 'c': 3} + result = flatten_dict_recursive(d) + assert result == {'a': 1, 'b': 2, 'c': 3} + + def test_nested_dict_one_level(self): + """Test flattening a dict with one level of nesting""" + d = {'stats': {'min': 1, 'max': 4}} + result = flatten_dict_recursive(d, parent_key='data', sep='_') + assert result == {'data_stats_min': 1, 'data_stats_max': 4} + + def test_nested_dict_two_levels(self): + """Test flattening a dict with two levels of nesting""" + d = {'level1': {'level2': {'a': 1, 'b': 2}}} + result = flatten_dict_recursive(d, sep='_') + assert result == {'level1_level2_a': 1, 'level1_level2_b': 2} + + def test_nested_dict_three_levels(self): + """Test flattening a deeply nested dict (3 levels)""" + d = {'l1': {'l2': {'l3': {'value': 42}}}} + result = flatten_dict_recursive(d, sep='_') + assert result == {'l1_l2_l3_value': 42} + + def test_mixed_nesting(self): + """Test flattening a dict with mixed nested and flat values""" + d = { + 'flat': 100, + 'nested': {'a': 1, 'b': 2}, + 'deep': {'level2': {'value': 3}} + } + result = flatten_dict_recursive(d, sep='_') + assert result == { + 'flat': 100, + 'nested_a': 1, + 'nested_b': 2, + 'deep_level2_value': 3 + } + + def test_custom_separator(self): + """Test flattening with a custom separator""" + d = {'a': {'b': 1}} + result = flatten_dict_recursive(d, sep='.') + assert result == {'a.b': 1} + + def test_empty_dict(self): + """Test flattening an empty dict""" + d = {} + result = flatten_dict_recursive(d) + assert result == {} + + +class TestFlattenDictColumns: + """Test the flatten_dict_columns function on DataFrames""" + + def test_no_dict_columns(self): + """Test DataFrame with no dict columns remains unchanged""" + df = pd.DataFrame({'x': [1, 2, 3], 'y': [4, 5, 6]}) + result = flatten_dict_columns(df) + assert list(result.columns) == ['x', 'y'] + assert result.equals(df) + + def test_simple_dict_column(self): + """Test flattening a simple dict column""" + df = pd.DataFrame({ + 'x': [1, 2, 3], + 'stats': [ + {'min': 1, 'max': 4}, + {'min': 2, 'max': 5}, + {'min': 3, 'max': 6} + ] + }) + result = flatten_dict_columns(df) + print(result) + + # Original dict column should be removed + assert 'stats' not in result.columns + + # Flattened columns should exist + assert 'stats_min' in result.columns + assert 'stats_max' in result.columns + + # Values should be correct + assert list(result['stats_min']) == [1, 2, 3] + assert list(result['stats_max']) == [4, 5, 6] + + # Original column should remain + assert list(result['x']) == [1, 2, 3] + + def test_nested_dict_column(self): + """Test flattening a nested dict column""" + df = pd.DataFrame({ + 'x': [1, 2], + 'data': [ + {'level1': {'level2': {'value': 10}}}, + {'level1': {'level2': {'value': 20}}} + ] + }) + result = flatten_dict_columns(df) + + assert 'data' not in result.columns + assert 'data_level1_level2_value' in result.columns + assert list(result['data_level1_level2_value']) == [10, 20] + + def test_deeply_nested_dict_column(self): + """Test flattening a deeply nested dict column (3 levels)""" + df = pd.DataFrame({ + 'x': [1, 2], + 'deep': [ + {'a': {'b': {'c': {'d': 100}}}}, + {'a': {'b': {'c': {'d': 200}}}} + ] + }) + result = flatten_dict_columns(df) + + assert 'deep_a_b_c_d' in result.columns + assert list(result['deep_a_b_c_d']) == [100, 200] + + def test_multiple_dict_columns(self): + """Test flattening multiple dict columns""" + df = pd.DataFrame({ + 'x': [1, 2], + 'stats': [ + {'min': 1, 'max': 4}, + {'min': 2, 'max': 5} + ], + 'info': [ + {'name': 'a', 'id': 100}, + {'name': 'b', 'id': 200} + ] + }) + result = flatten_dict_columns(df) + + # Both dict columns should be flattened + assert 'stats' not in result.columns + assert 'info' not in result.columns + assert 'stats_min' in result.columns + assert 'stats_max' in result.columns + assert 'info_name' in result.columns + assert 'info_id' in result.columns + + def test_dict_with_none_values(self): + """Test flattening dict column with None values""" + df = pd.DataFrame({ + 'x': [1, 2, 3], + 'stats': [ + {'min': 1, 'max': 4}, + None, + {'min': 3, 'max': 6} + ] + }) + result = flatten_dict_columns(df) + + assert 'stats_min' in result.columns + assert result['stats_min'].iloc[0] == 1.0 + assert pd.isna(result['stats_min'].iloc[1]) + assert result['stats_min'].iloc[2] == 3.0 + + def test_mixed_nested_and_flat_values(self): + """Test flattening dict with both nested and flat values""" + df = pd.DataFrame({ + 'x': [1, 2], + 'data': [ + {'nested': {'a': 1, 'b': 2}, 'flat': 99}, + {'nested': {'a': 3, 'b': 4}, 'flat': 88} + ] + }) + result = flatten_dict_columns(df) + + assert 'data_nested_a' in result.columns + assert 'data_nested_b' in result.columns + assert 'data_flat' in result.columns + assert list(result['data_flat']) == [99, 88] + + def test_empty_dataframe(self): + """Test flattening an empty DataFrame""" + df = pd.DataFrame() + result = flatten_dict_columns(df) + assert result.empty + + +class TestFzoWithDictFlattening: + """Test fzo with dict-valued outputs""" + + def test_fzo_with_dict_output(self): + """Test fzo automatically flattens dict outputs""" + with tempfile.TemporaryDirectory() as tmpdir: + # Save original directory to avoid Windows file deletion issues + original_cwd = os.getcwd() + try: + # Create result directory with dict output + result_dir = Path(tmpdir) / "results" / "x=5,y=10" + result_dir.mkdir(parents=True) + + # Write output file with JSON dict + with open(result_dir / "output.txt", "w") as f: + f.write("sum=15\n") + f.write('stats={"min": 5, "max": 10, "diff": 5}\n') + + # Define model + model = { + "varprefix": "$", + "delim": "{}", + "output": { + "sum": "grep 'sum=' output.txt | cut -d'=' -f2", + "stats": "grep 'stats=' output.txt | cut -d'=' -f2" + } + } + + # Run fzo + os.chdir(tmpdir) + results = fz.fzo("results/*", model) + + # Check flattening occurred + assert 'stats' not in results.columns + assert 'stats_min' in results.columns + assert 'stats_max' in results.columns + assert 'stats_diff' in results.columns + + # Check values + assert results['sum'].iloc[0] == 15 + assert results['stats_min'].iloc[0] == 5 + assert results['stats_max'].iloc[0] == 10 + assert results['stats_diff'].iloc[0] == 5 + finally: + # Restore original directory to allow cleanup on Windows + os.chdir(original_cwd) + + def test_fzo_with_nested_dict_output(self): + """Test fzo with nested dict outputs""" + with tempfile.TemporaryDirectory() as tmpdir: + # Save original directory to avoid Windows file deletion issues + original_cwd = os.getcwd() + try: + result_dir = Path(tmpdir) / "results" / "case1" + result_dir.mkdir(parents=True) + + # Write output with nested dict + nested_dict = { + 'basic': {'min': 1, 'max': 10}, + 'advanced': {'mean': 5.5, 'std': 2.5} + } + with open(result_dir / "output.txt", "w") as f: + f.write(f"data={json.dumps(nested_dict)}\n") + + model = { + "output": { + "data": "grep 'data=' output.txt | cut -d'=' -f2" + } + } + + os.chdir(tmpdir) + results = fz.fzo("results/*", model) + + # Check nested flattening + assert 'data_basic_min' in results.columns + assert 'data_basic_max' in results.columns + assert 'data_advanced_mean' in results.columns + assert 'data_advanced_std' in results.columns + finally: + # Restore original directory to allow cleanup on Windows + os.chdir(original_cwd) + + +class TestFzrWithDictFlattening: + """Test fzr with dict-valued outputs""" + + def test_fzr_with_dict_output(self): + """Test fzr automatically flattens dict outputs""" + with tempfile.TemporaryDirectory() as tmpdir: + # Save original directory to avoid Windows file deletion issues + original_cwd = os.getcwd() + try: + os.chdir(tmpdir) + + # Create input template + with open("input.txt", "w") as f: + f.write("x = ${x}\n") + + # Create calculator script that produces dict output + calc_script = Path(tmpdir) / "calc.py" + with open(calc_script, "w") as f: + f.write("""#!/usr/bin/env python3 +import json + +# Read input +with open('input.txt', 'r') as f: + content = f.read() + x = int([line for line in content.split('\\n') if 'x =' in line][0].split('=')[1].strip()) + +# Create dict output +stats = {'min': x - 1, 'max': x + 1, 'mean': x} + +# Write output +with open('output.txt', 'w') as f: + f.write(f"value={x}\\n") + f.write(f"stats={json.dumps(stats)}\\n") +""") + os.chmod(calc_script, 0o755) + + # Define model + model = { + "varprefix": "$", + "delim": "{}", + "output": { + "value": "grep 'value=' output.txt | cut -d'=' -f2", + "stats": "grep 'stats=' output.txt | cut -d'=' -f2" + } + } + + # Run fzr + results = fz.fzr( + input_path="input.txt", + input_variables={"x": [5, 10, 15]}, + model=model, + calculators=f"sh://python3 {calc_script}" + ) + + # Check flattening occurred + assert 'stats' not in results.columns + assert 'stats_min' in results.columns + assert 'stats_max' in results.columns + assert 'stats_mean' in results.columns + + # Check values for first row + assert results['x'].iloc[0] == 5 + assert results['value'].iloc[0] == 5 + assert results['stats_min'].iloc[0] == 4 + assert results['stats_max'].iloc[0] == 6 + assert results['stats_mean'].iloc[0] == 5 + + # Check all rows + assert len(results) == 3 + finally: + # Restore original directory to allow cleanup on Windows + os.chdir(original_cwd) + + def test_fzr_with_deeply_nested_dict(self): + """Test fzr with deeply nested dict outputs (3 levels)""" + with tempfile.TemporaryDirectory() as tmpdir: + # Save original directory to avoid Windows file deletion issues + original_cwd = os.getcwd() + try: + os.chdir(tmpdir) + + with open("input.txt", "w") as f: + f.write("x = ${x}\n") + + calc_script = Path(tmpdir) / "calc.py" + with open(calc_script, "w") as f: + f.write("""#!/usr/bin/env python3 +import json + +with open('input.txt', 'r') as f: + content = f.read() + x = int([line for line in content.split('\\n') if 'x =' in line][0].split('=')[1].strip()) + +# Create deeply nested output +result = { + 'level1': { + 'level2': { + 'level3': { + 'value': x * 2, + 'squared': x * x + } + } + } +} + +with open('output.txt', 'w') as f: + f.write(f"result={json.dumps(result)}\\n") +""") + os.chmod(calc_script, 0o755) + + model = { + "varprefix": "$", + "delim": "{}", + "output": { + "result": "grep 'result=' output.txt | cut -d'=' -f2" + } + } + + results = fz.fzr( + input_path="input.txt", + input_variables={"x": [3, 5]}, + model=model, + calculators=f"sh://python3 {calc_script}" + ) + + # Check deep nesting flattened correctly + assert 'result_level1_level2_level3_value' in results.columns + assert 'result_level1_level2_level3_squared' in results.columns + + # Check values + assert results['result_level1_level2_level3_value'].iloc[0] == 6 + assert results['result_level1_level2_level3_squared'].iloc[0] == 9 + assert results['result_level1_level2_level3_value'].iloc[1] == 10 + assert results['result_level1_level2_level3_squared'].iloc[1] == 25 + finally: + # Restore original directory to allow cleanup on Windows + os.chdir(original_cwd) + + def test_fzr_with_multiple_dict_outputs(self): + """Test fzr with multiple dict-valued outputs""" + with tempfile.TemporaryDirectory() as tmpdir: + # Save original directory to avoid Windows file deletion issues + original_cwd = os.getcwd() + try: + os.chdir(tmpdir) + + with open("input.txt", "w") as f: + f.write("x = ${x}\n") + + calc_script = Path(tmpdir) / "calc.py" + with open(calc_script, "w") as f: + f.write("""#!/usr/bin/env python3 +import json + +with open('input.txt', 'r') as f: + content = f.read() + x = int([line for line in content.split('\\n') if 'x =' in line][0].split('=')[1].strip()) + +stats = {'min': x - 1, 'max': x + 1} +meta = {'name': f'case{x}', 'id': x * 100} + +with open('output.txt', 'w') as f: + f.write(f"stats={json.dumps(stats)}\\n") + f.write(f"meta={json.dumps(meta)}\\n") +""") + os.chmod(calc_script, 0o755) + + model = { + "varprefix": "$", + "delim": "{}", + "output": { + "stats": "grep 'stats=' output.txt | cut -d'=' -f2", + "meta": "grep 'meta=' output.txt | cut -d'=' -f2" + } + } + + results = fz.fzr( + input_path="input.txt", + input_variables={"x": [5, 10]}, + model=model, + calculators=f"sh://python3 {calc_script}" + ) + + # Check both dicts flattened + assert 'stats_min' in results.columns + assert 'stats_max' in results.columns + assert 'meta_name' in results.columns + assert 'meta_id' in results.columns + + # Verify values + assert results['meta_name'].iloc[0] == 'case5' + assert results['meta_id'].iloc[0] == 500 + finally: + # Restore original directory to allow cleanup on Windows + os.chdir(original_cwd) + + +class TestEdgeCases: + """Test edge cases and error handling""" + + def test_dict_with_list_values(self): + """Test that dicts with list values are handled (lists not flattened further)""" + df = pd.DataFrame({ + 'x': [1], + 'data': [{'values': [1, 2, 3], 'count': 3}] + }) + result = flatten_dict_columns(df) + + assert 'data_values' in result.columns + assert 'data_count' in result.columns + # List should remain as list + assert result['data_values'].iloc[0] == [1, 2, 3] + + def test_inconsistent_dict_keys_across_rows(self): + """Test handling of dicts with different keys in different rows""" + df = pd.DataFrame({ + 'x': [1, 2, 3], + 'data': [ + {'a': 1, 'b': 2}, + {'a': 3, 'c': 4}, # Different key 'c' instead of 'b' + {'b': 5, 'c': 6} # Missing 'a' + ] + }) + result = flatten_dict_columns(df) + + # All keys should become columns + assert 'data_a' in result.columns + assert 'data_b' in result.columns + assert 'data_c' in result.columns + + # Missing values should be None/NaN + assert result['data_a'].iloc[0] == 1 + assert pd.isna(result['data_a'].iloc[2]) # Row 2 doesn't have 'a' + assert pd.isna(result['data_c'].iloc[0]) # Row 0 doesn't have 'c' + + def test_max_iterations_prevents_infinite_loop(self): + """Test that max iterations prevents infinite loops""" + # This is a safety check - normal dicts should never hit this limit + df = pd.DataFrame({ + 'x': [1], + 'data': [{'a': 1}] + }) + # Should complete without error even with iteration limit + result = flatten_dict_columns(df) + assert 'data_a' in result.columns + + +if __name__ == "__main__": + pytest.main([__file__, "-v"]) diff --git a/tests/test_fzd.py b/tests/test_fzd.py new file mode 100644 index 0000000..5d875bf --- /dev/null +++ b/tests/test_fzd.py @@ -0,0 +1,597 @@ +""" +Tests for fzd (iterative design of experiments with algorithms) +""" + +import os +import sys +import tempfile +import shutil +import pytest +from pathlib import Path + +# Add parent directory to path for importing fz +sys.path.insert(0, str(Path(__file__).parent.parent)) + +import fz +from fz.algorithms import parse_input_vars, evaluate_output_expression, load_algorithm + + +class TestParseInputVars: + """Test input variable range parsing""" + + def test_parse_simple_range(self): + """Test parsing simple ranges""" + result = parse_input_vars({"x": "[0;1]", "y": "[-5;5]"}) + assert result == {"x": (0.0, 1.0), "y": (-5.0, 5.0)} + + def test_parse_mixed_range_and_fixed(self): + """Test parsing mix of ranges and fixed values""" + from fz.algorithms import parse_fixed_vars + + input_vars = {"x": "[0;1]", "y": "0.5", "z": "[-2;2]"} + + # Variable ranges + ranges = parse_input_vars(input_vars) + assert ranges == {"x": (0.0, 1.0), "z": (-2.0, 2.0)} + + # Fixed values + fixed = parse_fixed_vars(input_vars) + assert fixed == {"y": 0.5} + + def test_parse_comma_delimiter(self): + """Test parsing with comma delimiter""" + result = parse_input_vars({"x": "[0,1]"}) + assert result == {"x": (0.0, 1.0)} + + def test_parse_float_range(self): + """Test parsing float ranges""" + result = parse_input_vars({"x": "[0.5;1.5]"}) + assert result == {"x": (0.5, 1.5)} + + def test_parse_invalid_format(self): + """Test parsing invalid format raises error""" + with pytest.raises(ValueError, match="Invalid format"): + parse_input_vars({"x": "0;1"}) # Missing brackets - not a valid range or fixed value + + def test_parse_invalid_order(self): + """Test parsing invalid order raises error""" + with pytest.raises(ValueError, match="min .* must be < max"): + parse_input_vars({"x": "[1;0]"}) # min > max + + +class TestEvaluateOutputExpression: + """Test output expression evaluation""" + + def test_simple_addition(self): + """Test simple addition""" + result = evaluate_output_expression("x + y", {"x": 1.0, "y": 2.0}) + assert result == 3.0 + + def test_multiplication(self): + """Test multiplication""" + result = evaluate_output_expression("x * 2", {"x": 3.0}) + assert result == 6.0 + + def test_complex_expression(self): + """Test complex expression""" + result = evaluate_output_expression("x + y * 2", {"x": 1.0, "y": 3.0}) + assert result == 7.0 + + def test_math_functions(self): + """Test math functions""" + result = evaluate_output_expression("sqrt(x)", {"x": 4.0}) + assert result == 2.0 + + def test_invalid_expression(self): + """Test invalid expression raises error""" + with pytest.raises(ValueError): + evaluate_output_expression("x + z", {"x": 1.0}) # z not defined + +class TestFzdIntegration: + """Integration tests for fzd function""" + + @pytest.fixture + def temp_dir(self): + """Create temporary directory for tests""" + tmpdir = tempfile.mkdtemp() + yield tmpdir + shutil.rmtree(tmpdir) + + @pytest.fixture + def simple_model(self, temp_dir): + """Create a simple test model""" + # Create input file + input_dir = Path(temp_dir) / "input" + input_dir.mkdir() + + input_file = input_dir / "input.txt" + input_file.write_text("x = $x\ny = $y\n") + + # Create model + model = { + "varprefix": "$", + "delim": "()", + "run": "bash -c 'source input.txt && result=$(echo \"scale=6; $x * $x + $y * $y\" | bc) && echo \"result = $result\" > output.txt'", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2 | tr -d ' '" + } + } + + return input_dir, model + + def test_fzd_randomsampling(self, simple_model): + """Test fzd with randomsampling""" + input_dir, model = simple_model + + # Skip if bc is not available (used in model) + if shutil.which("bc") is None: + pytest.skip("bc command not available") + + # Path to randomsampling algorithm + algo_path = str(Path(__file__).parent.parent / "examples" / "algorithms" / "randomsampling.py") + + # Run fzd with randomsampling + result = fz.fzd( + input_path=str(input_dir), + input_variables={"x": "[0;1]", "y": "[0;1]"}, + model=model, + output_expression="result", + algorithm=algo_path, + algorithm_options={"nvalues": 3, "seed": 42} + ) + + assert result is not None + assert "XY" in result + assert len(result["XY"]) == 3 + assert "x" in result["XY"].columns + assert "y" in result["XY"].columns + assert "result" in result["XY"].columns # output_expression as column name + assert algo_path in result["algorithm"] # algorithm field contains the path + + # Removed test_fzd_requires_pandas - pandas is now a required dependency + + def test_fzd_returns_dataframe(self, simple_model): + """Test that fzd returns XY DataFrame with all X and Y values""" + input_dir, model = simple_model + + # Skip if bc is not available (used in model) + if shutil.which("bc") is None: + pytest.skip("bc command not available") + + # Path to randomsampling algorithm + algo_path = str(Path(__file__).parent.parent / "examples" / "algorithms" / "randomsampling.py") + + # Run fzd + result = fz.fzd( + input_path=str(input_dir), + input_variables={"x": "[0;1]", "y": "[0;1]"}, + model=model, + output_expression="result", # This becomes the column name + algorithm=algo_path, + algorithm_options={"nvalues": 3, "seed": 42} + ) + + # Check that XY DataFrame is included + assert 'XY' in result + assert result['XY'] is not None + + # Check DataFrame structure + df = result['XY'] + assert len(df) == 3 # 3 evaluations + assert 'x' in df.columns + assert 'y' in df.columns + assert 'result' in df.columns # Output column named with output_expression + + # Check that input_vars and output_values are not in result + assert 'input_vars' not in result + assert 'output_values' not in result + + # Verify data types and structure + assert df['x'].dtype == 'float64' + assert df['y'].dtype == 'float64' + # result column may have None values, so check object type + assert df['result'].dtype in ['float64', 'object'] + + def test_fzd_with_fixed_variables(self, simple_model): + """Test that fzd only varies non-fixed variables""" + input_dir, model = simple_model + + # Skip if bc is not available (used in model) + if shutil.which("bc") is None: + pytest.skip("bc command not available") + + # Path to randomsampling algorithm + algo_path = str(Path(__file__).parent.parent / "examples" / "algorithms" / "randomsampling.py") + + # Run fzd with one variable range and one fixed value + result = fz.fzd( + input_path=str(input_dir), + input_variables={ + "x": "[0;1]", # Variable - will be varied by algorithm + "y": "0.5" # Fixed - will NOT be varied + }, + model=model, + output_expression="result", + algorithm=algo_path, + algorithm_options={"nvalues": 3, "seed": 42} + ) + + # Check that XY DataFrame has both columns + assert 'XY' in result + df = result['XY'] + assert 'x' in df.columns + assert 'y' in df.columns + assert 'result' in df.columns + + # Check that y is fixed at 0.5 for all rows + assert len(df) == 3 + assert all(df['y'] == 0.5), "y should be fixed at 0.5 for all evaluations" + + # Check that x varies + assert len(df['x'].unique()) > 1, "x should vary across evaluations" + + def test_fzd_get_analysis_tmp(self, temp_dir): + """Test that get_analysis_tmp is called at each iteration if it exists""" + from unittest.mock import Mock, patch + + # Create a simple model + input_dir = Path(temp_dir) / "input" + input_dir.mkdir() + (input_dir / "input.txt").write_text("x = $x\n") + + model = { + "varprefix": "$", + "delim": "()", + "run": "echo 'result = 1.0' > output.txt", + "output": {"result": "grep 'result = ' output.txt | cut -d '=' -f2"} + } + + # Create algorithm with get_analysis_tmp + algo_file = Path(temp_dir) / "algo_with_tmp.py" + algo_file.write_text(""" +class TestAlgorithm: + def __init__(self, **options): + self.call_count = 0 + + def get_initial_design(self, input_vars, output_vars): + return [{"x": 0.5}] + + def get_next_design(self, X, Y): + # Run 2 iterations + self.call_count += 1 + if self.call_count < 2: + return [{"x": 0.7}] + return [] + + def get_analysis(self, X, Y): + return {"text": "Final", "data": {}} + + def get_analysis_tmp(self, X, Y): + return {"text": f"Iteration progress: {len(X)} samples", "data": {}} +""") + + # Mock logging to capture calls + with patch('fz.core.log_info') as mock_log: + result = fz.fzd( + input_path=str(input_dir), + input_variables={"x": "[0;1]"}, + model=model, + output_expression="result", + algorithm=str(algo_file) + ) + + # Verify get_analysis_tmp was called + # Should be called twice (once after each iteration) + tmp_calls = [call for call in mock_log.call_args_list + if 'intermediate results' in str(call)] + assert len(tmp_calls) >= 2, "get_analysis_tmp should be called at each iteration" + + +class TestLoadAlgorithmFromFile: + """Test loading algorithms from Python files""" + + @pytest.fixture + def temp_dir(self): + """Create temporary directory for tests""" + tmpdir = tempfile.mkdtemp() + yield tmpdir + shutil.rmtree(tmpdir) + + def test_load_algorithm_from_file(self, temp_dir): + """Test loading an algorithm from a Python file""" + # Create a simple algorithm file + algo_file = Path(temp_dir) / "simple_algo.py" + algo_file.write_text(""" +class SimpleAlgorithm: + def __init__(self, **options): + self.options = options + self.nvalues = options.get("nvalues", 5) + + def get_initial_design(self, input_vars, output_vars): + # Return center point + return [{var: (bounds[0] + bounds[1]) / 2 for var, bounds in input_vars.items()}] + + def get_next_design(self, X, Y): + # No next design + return [] + + def get_analysis(self, X, Y): + return {"text": "Test results", "data": {}} +""") + + # Load algorithm from file + algo = load_algorithm(str(algo_file), nvalues=10) + assert algo is not None + assert algo.nvalues == 10 + + # Test initial design + input_vars = {"x": (0.0, 1.0), "y": (-5.0, 5.0)} + design = algo.get_initial_design(input_vars, ["output"]) + assert len(design) == 1 + assert design[0]["x"] == 0.5 + assert design[0]["y"] == 0.0 + + def test_load_montecarlo_algorithm(self): + """Test loading the MonteCarlo_Uniform algorithm from file""" + # Use the test_algorithm_montecarlo.py file we just created + algo_file = Path(__file__).parent / "test_algorithm_montecarlo.py" + + # Load algorithm from file + algo = load_algorithm(str(algo_file), batch_sample_size=5, seed=42) + assert algo is not None + + # Test initial design + input_vars = {"x": (0.0, 1.0), "y": (-5.0, 5.0)} + design = algo.get_initial_design(input_vars, ["output"]) + assert len(design) == 5 + + # Check that all points are within bounds + for point in design: + assert 0.0 <= point["x"] <= 1.0 + assert -5.0 <= point["y"] <= 5.0 + + def test_load_algorithm_with_metadata(self, temp_dir): + """Test loading algorithm with metadata comments""" + algo_file = Path(temp_dir) / "algo_with_metadata.py" + algo_file.write_text("""#title: Test Algorithm +#author: Test Author +#type: optimization +#options: param1=10;param2=0.5 +#require: numpy + +class TestAlgo: + def __init__(self, **options): + self.options = options + self.param1 = int(options.get("param1", 5)) + self.param2 = float(options.get("param2", 0.1)) + + def get_initial_design(self, input_vars, output_vars): + return [] + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": "Test", "data": {}} +""") + + # Load algorithm (should use default options from metadata) + algo = load_algorithm(str(algo_file)) + assert algo.param1 == 10 + assert algo.param2 == 0.5 + + # Load with explicit options (should override metadata) + algo2 = load_algorithm(str(algo_file), param1=20) + assert algo2.param1 == 20 + assert algo2.param2 == 0.5 # Still from metadata + + def test_load_algorithm_invalid_file(self): + """Test loading from non-existent file""" + with pytest.raises(ValueError, match="Algorithm file not found"): + load_algorithm("nonexistent_algo.py") + + def test_load_algorithm_non_python_file(self, temp_dir): + """Test loading from non-.py/.R file""" + txt_file = Path(temp_dir) / "not_python.txt" + txt_file.write_text("Not a Python file") + + with pytest.raises(ValueError, match="must be a Python \\(\\.py\\) or R \\(\\.R\\) file"): + load_algorithm(str(txt_file)) + + def test_load_algorithm_no_class(self, temp_dir): + """Test loading from file with no algorithm class""" + algo_file = Path(temp_dir) / "no_class.py" + algo_file.write_text(""" +# This file has no algorithm class +def some_function(): + pass +""") + + with pytest.raises(ValueError, match="No valid algorithm class found"): + load_algorithm(str(algo_file)) + + def test_load_algorithm_with_require_installed(self, temp_dir): + """Test loading algorithm with #require: header for already installed packages""" + algo_file = Path(temp_dir) / "algo_with_require.py" + algo_file.write_text(""" +#title: Test Algorithm +#require: sys;os + +class TestAlgorithm: + def __init__(self, **options): + import sys + import os + self.options = options + + def get_initial_design(self, input_vars, output_vars): + return [{"x": 0.5}] + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": "Test", "data": {}} +""") + + # Should load successfully without trying to install sys/os (they're built-in) + algo = load_algorithm(str(algo_file)) + assert algo is not None + + def test_load_algorithm_with_require_missing(self, temp_dir): + """Test that missing packages trigger installation attempt""" + from unittest.mock import patch, MagicMock + import fz.algorithms + + algo_file = Path(temp_dir) / "algo_missing_pkg.py" + algo_file.write_text(""" +#require: nonexistent_test_package_12345 + +class TestAlgorithm: + def __init__(self, **options): + self.options = options + + def get_initial_design(self, input_vars, output_vars): + return [{"x": 0.5}] + + def get_next_design(self, X, Y): + return [] + + def get_analysis(self, X, Y): + return {"text": "Test", "data": {}} +""") + + # Mock subprocess.check_call to fail (package doesn't exist) + with patch('fz.algorithms.subprocess.check_call') as mock_call: + mock_call.side_effect = fz.algorithms.subprocess.CalledProcessError(1, 'pip') + + # Should raise RuntimeError about failed installation + with pytest.raises(RuntimeError, match="Failed to install required package"): + load_algorithm(str(algo_file)) + + +class TestContentDetection: + """Test content type detection and processing""" + + @pytest.fixture + def temp_dir(self): + """Create temporary directory for tests""" + tmpdir = tempfile.mkdtemp() + yield tmpdir + shutil.rmtree(tmpdir) + + def test_detect_html_content(self): + """Test HTML content detection""" + from fz.io import detect_content_type + + html_text = "

Hello

" + assert detect_content_type(html_text) == 'html' + + html_text2 = "Test" + assert detect_content_type(html_text2) == 'html' + + def test_detect_json_content(self): + """Test JSON content detection""" + from fz.io import detect_content_type + + json_text = '{"key": "value", "number": 42}' + assert detect_content_type(json_text) == 'json' + + json_array = '[1, 2, 3, 4]' + assert detect_content_type(json_array) == 'json' + + def test_detect_keyvalue_content(self): + """Test key=value content detection""" + from fz.io import detect_content_type + + kv_text = """name = John +age = 30 +city = Paris""" + assert detect_content_type(kv_text) == 'keyvalue' + + def test_detect_markdown_content(self): + """Test markdown content detection""" + from fz.io import detect_content_type + + md_text = """# Header +## Subheader +* Item 1 +* Item 2""" + assert detect_content_type(md_text) == 'markdown' + + def test_parse_keyvalue(self): + """Test parsing key=value text""" + from fz.io import parse_keyvalue_text + + kv_text = """name = John Doe +age = 30 +city = Paris""" + result = parse_keyvalue_text(kv_text) + assert result == {'name': 'John Doe', 'age': '30', 'city': 'Paris'} + + def test_process_analysis_content_with_json(self, temp_dir): + """Test processing analysis content with JSON""" + from fz.io import process_analysis_content + + results_dir = Path(temp_dir) + analysis_dict = { + 'text': '{"mean": 1.5, "std": 0.3}', + 'data': {'samples': 10} + } + + processed = process_analysis_content(analysis_dict, 1, results_dir) + + assert 'json_data' in processed + assert processed['json_data']['mean'] == 1.5 + assert 'json_file' in processed + assert (results_dir / processed['json_file']).exists() + + def test_process_analysis_content_with_html(self, temp_dir): + """Test processing analysis content with HTML""" + from fz.io import process_analysis_content + + results_dir = Path(temp_dir) + analysis_dict = { + 'html': '

Results

Test

', + 'data': {} + } + + processed = process_analysis_content(analysis_dict, 1, results_dir) + + assert 'html_file' in processed + assert (results_dir / processed['html_file']).exists() + + def test_process_analysis_content_with_markdown(self, temp_dir): + """Test processing analysis content with markdown""" + from fz.io import process_analysis_content + + results_dir = Path(temp_dir) + analysis_dict = { + 'text': '# Results\n\n* Item 1\n* Item 2', + 'data': {} + } + + processed = process_analysis_content(analysis_dict, 1, results_dir) + + assert 'md_file' in processed + assert (results_dir / processed['md_file']).exists() + + def test_process_analysis_content_with_keyvalue(self, temp_dir): + """Test processing analysis content with key=value""" + from fz.io import process_analysis_content + + results_dir = Path(temp_dir) + analysis_dict = { + 'text': 'mean = 1.5\nstd = 0.3\nsamples = 100', + 'data': {} + } + + processed = process_analysis_content(analysis_dict, 1, results_dir) + + assert 'keyvalue_data' in processed + assert processed['keyvalue_data']['mean'] == '1.5' + assert 'txt_file' in processed + assert (results_dir / processed['txt_file']).exists() + + +if __name__ == "__main__": + pytest.main([__file__, "-v"]) diff --git a/tests/test_fzo_fzr_coherence.py b/tests/test_fzo_fzr_coherence.py index a029e77..0f877ec 100644 --- a/tests/test_fzo_fzr_coherence.py +++ b/tests/test_fzo_fzr_coherence.py @@ -13,17 +13,12 @@ import platform import fz - -try: - import pandas as pd - PANDAS_AVAILABLE = True -except ImportError: - PANDAS_AVAILABLE = False +import pandas as pd def _get_value(result, key, index): """Helper to get value from DataFrame or dict""" - if PANDAS_AVAILABLE and isinstance(result, pd.DataFrame): + if isinstance(result, pd.DataFrame): value = result[key].iloc[index] # Convert numpy types to native Python types if hasattr(value, 'item'): @@ -35,7 +30,7 @@ def _get_value(result, key, index): def _get_length(result, key): """Helper to get length from DataFrame or dict""" - if PANDAS_AVAILABLE and isinstance(result, pd.DataFrame): + if isinstance(result, pd.DataFrame): return len(result[key]) else: return len(result[key]) diff --git a/tests/test_interrupt_handling.py b/tests/test_interrupt_handling.py index cb11e08..baa5bcf 100644 --- a/tests/test_interrupt_handling.py +++ b/tests/test_interrupt_handling.py @@ -32,7 +32,10 @@ def test_interrupt_sequential_execution(tmp_path): script_file = tmp_path / "script.sh" # Each case takes 3 seconds - script_file.write_text("#!/bin/bash\nsleep 3\necho 'done' > output.txt\n") + with open(script_file, 'w', newline='\n') as f: + f.write("#!/bin/bash\n") + f.write("sleep 3\n") + f.write("echo 'done' > output.txt\n") script_file.chmod(0o755) # Create multiple cases @@ -100,7 +103,10 @@ def test_interrupt_parallel_execution(tmp_path): script_file = tmp_path / "script.sh" # Each case takes 3 seconds - script_file.write_text("#!/bin/bash\nsleep 3\necho 'done' > output.txt\n") + with open(script_file, 'w', newline='\n') as f: + f.write("#!/bin/bash\n") + f.write("sleep 3\n") + f.write("echo 'done' > output.txt\n") script_file.chmod(0o755) # Create multiple cases @@ -165,7 +171,10 @@ def test_graceful_cleanup_on_interrupt(tmp_path): script_file = tmp_path / "script.sh" # Each case takes 3 seconds - script_file.write_text("#!/bin/bash\nsleep 3\necho 'done' > output.txt\n") + with open(script_file, 'w', newline='\n') as f: + f.write("#!/bin/bash\n") + f.write("sleep 3\n") + f.write("echo 'done' > output.txt\n") script_file.chmod(0o755) input_variables = {"x": [1, 2, 3]} diff --git a/tests/test_no_algorithms.py b/tests/test_no_algorithms.py new file mode 100644 index 0000000..c1037bc --- /dev/null +++ b/tests/test_no_algorithms.py @@ -0,0 +1,476 @@ +""" +Negative tests for algorithms +Tests error handling for invalid algorithms, missing algorithm files, bad algorithm options, etc. +""" + +import os +import tempfile +from pathlib import Path +import pytest +import pandas as pd + +from fz import fzd + + +def test_algorithm_nonexistent_file(): + """Test fzd with a non-existent algorithm file""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + # Create input file + input_file = tmpdir / "input.txt" + input_file.write_text("x = ${x}\n") + + # Create calculator script + calc_script = tmpdir / "calc.sh" + calc_script.write_text("#!/bin/bash\necho 'result = 42' > output.txt\n") + calc_script.chmod(0o755) + + model = { + "varprefix": "$", + "delim": "{}", + "output": { + "result": "grep 'result = ' output.txt | cut -d '=' -f2" + } + } + + analysis_dir = tmpdir / "analysis" + + # Use non-existent algorithm file + nonexistent_algo = tmpdir / "does_not_exist.py" + + # Should raise FileNotFoundError or ValueError + with pytest.raises((FileNotFoundError, ValueError, Exception)): + fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm=str(nonexistent_algo), + calculators=f"sh://bash {calc_script}", + analysis_dir=str(analysis_dir) + ) + + +def test_algorithm_invalid_python_syntax(): + """Test algorithm file with invalid Python syntax""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + input_file = tmpdir / "input.txt" + input_file.write_text("x = ${x}\n") + + calc_script = tmpdir / "calc.sh" + calc_script.write_text("#!/bin/bash\necho 'result = 42' > output.txt\n") + calc_script.chmod(0o755) + + # Create algorithm file with syntax error + algo_file = tmpdir / "bad_syntax.py" + algo_file.write_text("class MyAlgo\n def invalid syntax here\n") + + model = { + "varprefix": "$", + "delim": "{}", + "output": {"result": "echo 42"} + } + + analysis_dir = tmpdir / "analysis" + + # Should raise SyntaxError or ImportError + with pytest.raises((SyntaxError, ImportError, Exception)): + fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm=str(algo_file), + calculators=f"sh://bash {calc_script}", + analysis_dir=str(analysis_dir) + ) + + +def test_algorithm_missing_required_methods(): + """Test algorithm missing required methods""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + input_file = tmpdir / "input.txt" + input_file.write_text("x = ${x}\n") + + calc_script = tmpdir / "calc.sh" + calc_script.write_text("#!/bin/bash\necho 'result = 42' > output.txt\n") + calc_script.chmod(0o755) + + # Algorithm without required methods + algo_file = tmpdir / "incomplete.py" + algo_file.write_text(""" +class IncompleteAlgorithm: + def __init__(self, **options): + pass + # Missing get_initial_design, get_next_design, get_analysis +""") + + model = { + "varprefix": "$", + "delim": "{}", + "output": {"result": "echo 42"} + } + + analysis_dir = tmpdir / "analysis" + + # Should raise AttributeError when trying to call missing methods + with pytest.raises((AttributeError, TypeError, Exception)): + fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm=str(algo_file), + calculators=f"sh://bash {calc_script}", + analysis_dir=str(analysis_dir) + ) + + +def test_algorithm_empty_file(): + """Test algorithm with empty file""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + input_file = tmpdir / "input.txt" + input_file.write_text("x = ${x}\n") + + calc_script = tmpdir / "calc.sh" + calc_script.write_text("#!/bin/bash\necho 'result = 42' > output.txt\n") + calc_script.chmod(0o755) + + # Empty algorithm file + algo_file = tmpdir / "empty.py" + algo_file.write_text("") + + model = { + "varprefix": "$", + "delim": "{}", + "output": {"result": "echo 42"} + } + + analysis_dir = tmpdir / "analysis" + + # Should raise error (no algorithm class found) + with pytest.raises((ValueError, AttributeError, ImportError, Exception)): + fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm=str(algo_file), + calculators=f"sh://bash {calc_script}", + analysis_dir=str(analysis_dir) + ) + + +def test_algorithm_with_none_value(): + """Test fzd when algorithm is None""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + input_file = tmpdir / "input.txt" + input_file.write_text("x = ${x}\n") + + calc_script = tmpdir / "calc.sh" + calc_script.write_text("#!/bin/bash\necho 'result = 42' > output.txt\n") + calc_script.chmod(0o755) + + model = { + "varprefix": "$", + "delim": "{}", + "output": {"result": "echo 42"} + } + + analysis_dir = tmpdir / "analysis" + + # algorithm is None + with pytest.raises((TypeError, ValueError, AttributeError)): + fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm=None, + calculators=f"sh://bash {calc_script}", + analysis_dir=str(analysis_dir) + ) + + +def test_algorithm_invalid_type(): + """Test fzd with non-string algorithm parameter""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + input_file = tmpdir / "input.txt" + input_file.write_text("x = ${x}\n") + + calc_script = tmpdir / "calc.sh" + calc_script.write_text("#!/bin/bash\necho 'result = 42' > output.txt\n") + calc_script.chmod(0o755) + + model = { + "varprefix": "$", + "delim": "{}", + "output": {"result": "echo 42"} + } + + analysis_dir = tmpdir / "analysis" + + # algorithm is a dict instead of string + with pytest.raises((TypeError, ValueError, AttributeError)): + fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm={"not": "a", "string": True}, + calculators=f"sh://bash {calc_script}", + analysis_dir=str(analysis_dir) + ) + + +def test_algorithm_options_invalid_type(): + """Test fzd with algorithm_options that's not a dict""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + input_file = tmpdir / "input.txt" + input_file.write_text("x = ${x}\n") + + calc_script = tmpdir / "calc.sh" + calc_script.write_text("#!/bin/bash\necho 'result = 42' > output.txt\n") + calc_script.chmod(0o755) + + # Create a minimal valid algorithm + algo_file = tmpdir / "simple.py" + algo_file.write_text(""" +class SimpleAlgorithm: + def __init__(self, **options): + pass + def get_initial_design(self, input_vars, output_vars): + return [{"x": 5.0}] + def get_next_design(self, input_vars, output_values): + return [] + def get_analysis(self, input_vars, output_values): + return "Done" +""") + + model = { + "varprefix": "$", + "delim": "{}", + "output": {"result": "echo 42"} + } + + analysis_dir = tmpdir / "analysis" + + # algorithm_options is a list instead of dict + with pytest.raises((TypeError, ValueError)): + fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm=str(algo_file), + calculators=f"sh://bash {calc_script}", + algorithm_options=["not", "a", "dict"], + analysis_dir=str(analysis_dir) + ) + + +def test_algorithm_with_missing_dependencies(): + """Test algorithm that requires missing dependencies""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + input_file = tmpdir / "input.txt" + input_file.write_text("x = ${x}\n") + + calc_script = tmpdir / "calc.sh" + calc_script.write_text("#!/bin/bash\necho 'result = 42' > output.txt\n") + calc_script.chmod(0o755) + + # Algorithm that requires non-existent package + algo_file = tmpdir / "requires_deps.py" + algo_file.write_text(""" +__require__ = ["nonexistent_package_xyz_12345"] + +class MyAlgorithm: + def __init__(self, **options): + pass + def get_initial_design(self, input_vars, output_vars): + return [{"x": 5.0}] + def get_next_design(self, input_vars, output_values): + return [] + def get_analysis(self, input_vars, output_values): + return "Done" +""") + + model = { + "varprefix": "$", + "delim": "{}", + "output": {"result": "echo 42"} + } + + analysis_dir = tmpdir / "analysis" + + # Should warn about missing dependencies but may still try to run + # (The actual behavior depends on implementation) + try: + result = fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm=str(algo_file), + calculators=f"sh://bash {calc_script}", + analysis_dir=str(analysis_dir) + ) + # May succeed with warnings + except (ImportError, ModuleNotFoundError): + # Or may fail if algorithm actually tries to import + pass + + +def test_algorithm_no_class_defined(): + """Test algorithm file with no class defined""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + input_file = tmpdir / "input.txt" + input_file.write_text("x = ${x}\n") + + calc_script = tmpdir / "calc.sh" + calc_script.write_text("#!/bin/bash\necho 'result = 42' > output.txt\n") + calc_script.chmod(0o755) + + # Algorithm file with only functions, no class + algo_file = tmpdir / "no_class.py" + algo_file.write_text(""" +def some_function(): + return 42 + +def another_function(x): + return x * 2 +""") + + model = { + "varprefix": "$", + "delim": "{}", + "output": {"result": "echo 42"} + } + + analysis_dir = tmpdir / "analysis" + + # Should raise error (no algorithm class found) + with pytest.raises((ValueError, AttributeError, Exception)): + fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm=str(algo_file), + calculators=f"sh://bash {calc_script}", + analysis_dir=str(analysis_dir) + ) + + +def test_algorithm_with_runtime_error_in_init(): + """Test algorithm that raises error in __init__""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + input_file = tmpdir / "input.txt" + input_file.write_text("x = ${x}\n") + + calc_script = tmpdir / "calc.sh" + calc_script.write_text("#!/bin/bash\necho 'result = 42' > output.txt\n") + calc_script.chmod(0o755) + + # Algorithm that raises error during initialization + algo_file = tmpdir / "error_init.py" + algo_file.write_text(""" +class ErrorAlgorithm: + def __init__(self, **options): + raise RuntimeError("Initialization failed!") + def get_initial_design(self, input_vars, output_vars): + return [[5.0]] + def get_next_design(self, input_vars, output_values): + return [] + def get_analysis(self, input_vars, output_values): + return "Done" +""") + + model = { + "varprefix": "$", + "delim": "{}", + "output": {"result": "echo 42"} + } + + analysis_dir = tmpdir / "analysis" + + # Should propagate the RuntimeError + with pytest.raises((RuntimeError, Exception)): + fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm=str(algo_file), + calculators=f"sh://bash {calc_script}", + analysis_dir=str(analysis_dir) + ) + + +def test_algorithm_returns_invalid_initial_design(): + """Test algorithm that returns invalid initial design""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + input_file = tmpdir / "input.txt" + input_file.write_text("x = ${x}\n") + + calc_script = tmpdir / "calc.sh" + calc_script.write_text("#!/bin/bash\necho 'result = 42' > output.txt\n") + calc_script.chmod(0o755) + + # Algorithm that returns invalid design format + algo_file = tmpdir / "bad_design.py" + algo_file.write_text(""" +class BadDesignAlgorithm: + def __init__(self, **options): + pass + def get_initial_design(self, input_vars, output_vars): + return "not a list" # Should return list of lists + def get_next_design(self, input_vars, output_values): + return [] + def get_analysis(self, input_vars, output_values): + return "Done" +""") + + model = { + "varprefix": "$", + "delim": "{}", + "output": {"result": "echo 42"} + } + + analysis_dir = tmpdir / "analysis" + + # Should fail when trying to process invalid design + with pytest.raises((TypeError, ValueError, Exception)): + fzd( + input_path=str(input_file), + input_variables={"x": "[0;10]"}, + model=model, + output_expression="result", + algorithm=str(algo_file), + calculators=f"sh://bash {calc_script}", + analysis_dir=str(analysis_dir) + ) + + + diff --git a/tests/test_platform_specific.py b/tests/test_platform_specific.py new file mode 100644 index 0000000..9b3e52a --- /dev/null +++ b/tests/test_platform_specific.py @@ -0,0 +1,65 @@ +""" +Platform-specific tests for fz + +These tests verify platform-specific functionality like interrupt handling +on different operating systems. +""" + +import pytest +import sys +import time +import platform +import tempfile +from pathlib import Path + + +class TestInterruptHandling: + """Test interrupt handling (Ctrl+C) on different platforms""" + + @pytest.mark.skipif( + platform.system() != "Windows", + reason="Windows-specific interrupt test" + ) + def test_windows_interrupt_basic(self): + """Test basic interrupt handling on Windows + + Note: This test cannot actually trigger Ctrl+C automatically. + It verifies that the interrupt mechanism is set up correctly. + """ + # Test that KeyboardInterrupt can be caught + caught_interrupt = False + try: + raise KeyboardInterrupt() + except KeyboardInterrupt: + caught_interrupt = True + + assert caught_interrupt, "KeyboardInterrupt should be catchable" + + @pytest.mark.skipif( + platform.system() != "Windows", + reason="Windows-specific test" + ) + @pytest.mark.slow + @pytest.mark.manual + def test_windows_fz_interrupt(self): + """Manual test for FZ interrupt handling on Windows + + This test should be run manually with Ctrl+C to verify interrupt handling. + It is marked as 'manual' and skipped by default. + """ + pytest.skip("Manual test - requires user interaction (Ctrl+C)") + + +class TestPandasRequirement: + """Test that fzd properly requires pandas""" + + def test_pandas_is_available(self): + """Test that pandas is installed and importable""" + try: + import pandas as pd + assert pd is not None + except ImportError: + pytest.fail("pandas should be installed for fzd to work") + + # Removed test_fzd_imports_pandas and test_fzd_requires_pandas_error_message + # pandas is now a required dependency, not optional diff --git a/tests/test_r_algorithms.py b/tests/test_r_algorithms.py new file mode 100644 index 0000000..927b1ff --- /dev/null +++ b/tests/test_r_algorithms.py @@ -0,0 +1,395 @@ +#!/usr/bin/env python3 +""" +Test R algorithm loading and integration with fzd + +This test suite verifies that: +1. R algorithms can be loaded via rpy2 +2. RAlgorithmWrapper correctly wraps R S3 class instances +3. All algorithm methods work correctly (get_initial_design, get_next_design, get_analysis, get_analysis_tmp) +4. Data type conversion between Python and R works correctly +5. R algorithms integrate seamlessly with fzd +""" + +import pytest +import sys +from pathlib import Path + +# Try to import rpy2 +try: + import rpy2 + import rpy2.robjects + HAS_RPY2 = True +except ImportError: + HAS_RPY2 = False + +# Skip all tests in this module if rpy2 is not available +pytestmark = pytest.mark.skipif( + not HAS_RPY2, + reason="rpy2 is required for R algorithm tests. Install with: pip install rpy2" +) + + +def test_r_algorithm_loading(): + """Test loading R algorithm with load_algorithm""" + from fz.algorithms import load_algorithm + + # Get path to R algorithm + repo_root = Path(__file__).parent.parent + r_algo_path = repo_root / "examples" / "algorithms" / "montecarlo_uniform.R" + + # Load R algorithm + algo = load_algorithm( + str(r_algo_path), + batch_sample_size=5, + max_iterations=3, + confidence=0.9, + target_confidence_range=0.5, + seed=42 + ) + + # Verify wrapper was created + from fz.algorithms import RAlgorithmWrapper + assert isinstance(algo, RAlgorithmWrapper) + assert algo.r_instance is not None + assert algo.r_globals is not None + + +def test_r_algorithm_get_initial_design(): + """Test get_initial_design method with R algorithm""" + from fz.algorithms import load_algorithm + + # Get path to R algorithm + repo_root = Path(__file__).parent.parent + r_algo_path = repo_root / "examples" / "algorithms" / "montecarlo_uniform.R" + + # Load R algorithm + algo = load_algorithm(str(r_algo_path), batch_sample_size=5, seed=42) + + # Call get_initial_design + input_vars = { + "x": (0.0, 10.0), + "y": (-5.0, 5.0) + } + output_vars = ["result"] + + initial_design = algo.get_initial_design(input_vars, output_vars) + + # Verify result + assert isinstance(initial_design, list) + assert len(initial_design) == 5 + assert all(isinstance(point, dict) for point in initial_design) + assert all("x" in point and "y" in point for point in initial_design) + assert all(0.0 <= point["x"] <= 10.0 for point in initial_design) + assert all(-5.0 <= point["y"] <= 5.0 for point in initial_design) + + +def test_r_algorithm_get_next_design(): + """Test get_next_design method with R algorithm""" + from fz.algorithms import load_algorithm + + # Get path to R algorithm + repo_root = Path(__file__).parent.parent + r_algo_path = repo_root / "examples" / "algorithms" / "montecarlo_uniform.R" + + # Load R algorithm + algo = load_algorithm(str(r_algo_path), batch_sample_size=5, seed=42) + + # Get initial design + input_vars = {"x": (0.0, 10.0), "y": (-5.0, 5.0)} + output_vars = ["result"] + X = algo.get_initial_design(input_vars, output_vars) + + # Simulate outputs + Y = [point["x"]**2 + point["y"]**2 for point in X] + + # Call get_next_design + next_design = algo.get_next_design(X, Y) + + # Verify result + assert isinstance(next_design, list) + assert len(next_design) == 5 + assert all(isinstance(point, dict) for point in next_design) + + +def test_r_algorithm_get_next_design_with_none(): + """Test get_next_design handles None values in outputs""" + from fz.algorithms import load_algorithm + + # Get path to R algorithm + repo_root = Path(__file__).parent.parent + r_algo_path = repo_root / "examples" / "algorithms" / "montecarlo_uniform.R" + + # Load R algorithm + algo = load_algorithm(str(r_algo_path), batch_sample_size=5, seed=42) + + # Get initial design + input_vars = {"x": (0.0, 10.0), "y": (-5.0, 5.0)} + output_vars = ["result"] + X = algo.get_initial_design(input_vars, output_vars) + + # Simulate outputs with some None values (failed evaluations) + Y = [] + for i, point in enumerate(X): + if i % 2 == 0: + Y.append(point["x"]**2 + point["y"]**2) + else: + Y.append(None) # Failed evaluation + + # Call get_next_design - should handle None values + next_design = algo.get_next_design(X, Y) + + # Verify result (should still generate next design) + assert isinstance(next_design, list) + + +def test_r_algorithm_get_analysis(): + """Test get_analysis method with R algorithm""" + from fz.algorithms import load_algorithm + + # Get path to R algorithm + repo_root = Path(__file__).parent.parent + r_algo_path = repo_root / "examples" / "algorithms" / "montecarlo_uniform.R" + + # Load R algorithm + algo = load_algorithm(str(r_algo_path), batch_sample_size=5, seed=42) + + # Get initial design + input_vars = {"x": (0.0, 10.0), "y": (-5.0, 5.0)} + output_vars = ["result"] + X = algo.get_initial_design(input_vars, output_vars) + + # Simulate outputs + Y = [point["x"]**2 + point["y"]**2 for point in X] + + # Call get_analysis + analysis = algo.get_analysis(X, Y) + + # Verify result + assert isinstance(analysis, dict) + assert "text" in analysis + assert "data" in analysis + assert isinstance(analysis["text"], str) + assert isinstance(analysis["data"], dict) + assert "mean" in analysis["data"] + assert "std" in analysis["data"] + + +def test_r_algorithm_get_analysis_tmp(): + """Test get_analysis_tmp method with R algorithm""" + from fz.algorithms import load_algorithm + + # Get path to R algorithm + repo_root = Path(__file__).parent.parent + r_algo_path = repo_root / "examples" / "algorithms" / "montecarlo_uniform.R" + + # Load R algorithm + algo = load_algorithm(str(r_algo_path), batch_sample_size=5, seed=42) + + # Get initial design + input_vars = {"x": (0.0, 10.0), "y": (-5.0, 5.0)} + output_vars = ["result"] + X = algo.get_initial_design(input_vars, output_vars) + + # Simulate outputs + Y = [point["x"]**2 + point["y"]**2 for point in X] + + # Call get_analysis_tmp + tmp_analysis = algo.get_analysis_tmp(X, Y) + + # Verify result (method is optional, may return None if not implemented) + if tmp_analysis is not None: + assert isinstance(tmp_analysis, dict) + assert "text" in tmp_analysis or "data" in tmp_analysis + + +def test_r_algorithm_html_output(): + """Test that R algorithm can generate HTML output""" + from fz.algorithms import load_algorithm + + # Get path to R algorithm + repo_root = Path(__file__).parent.parent + r_algo_path = repo_root / "examples" / "algorithms" / "montecarlo_uniform.R" + + # Load R algorithm + algo = load_algorithm(str(r_algo_path), batch_sample_size=10, seed=42) + + # Get some data + input_vars = {"x": (0.0, 10.0), "y": (-5.0, 5.0)} + output_vars = ["result"] + X = algo.get_initial_design(input_vars, output_vars) + Y = [point["x"]**2 + point["y"]**2 for point in X] + + # Get more data + X2 = algo.get_next_design(X, Y) + for point in X2: + X.append(point) + Y.append(point["x"]**2 + point["y"]**2) + + # Call get_analysis + analysis = algo.get_analysis(X, Y) + + # Verify HTML output exists (if base64enc is available in R) + # HTML generation is optional and depends on base64enc package + if "html" in analysis: + assert isinstance(analysis["html"], str) + assert len(analysis["html"]) > 0 + + +def test_r_algorithm_empty_next_design(): + """Test that R algorithm returns empty list when finished""" + from fz.algorithms import load_algorithm + + # Get path to R algorithm + repo_root = Path(__file__).parent.parent + r_algo_path = repo_root / "examples" / "algorithms" / "montecarlo_uniform.R" + + # Load R algorithm with very tight convergence criteria + algo = load_algorithm( + str(r_algo_path), + batch_sample_size=100, + max_iterations=1, # Only 1 iteration allowed + seed=42 + ) + + # Get initial design + input_vars = {"x": (0.0, 10.0), "y": (-5.0, 5.0)} + output_vars = ["result"] + X = algo.get_initial_design(input_vars, output_vars) + + # Simulate outputs + Y = [point["x"]**2 + point["y"]**2 for point in X] + + # Call get_next_design - should return empty list (max iterations reached) + next_design = algo.get_next_design(X, Y) + + # Verify empty list is returned + assert isinstance(next_design, list) + assert len(next_design) == 0 + + +def test_r_algorithm_convergence(): + """Test that R algorithm converges based on confidence interval""" + from fz.algorithms import load_algorithm + + # Get path to R algorithm + repo_root = Path(__file__).parent.parent + r_algo_path = repo_root / "examples" / "algorithms" / "montecarlo_uniform.R" + + # Load R algorithm with very loose convergence criteria (easy to reach) + algo = load_algorithm( + str(r_algo_path), + batch_sample_size=50, + max_iterations=10, + confidence=0.9, + target_confidence_range=100.0, # Very large target - should converge quickly + seed=42 + ) + + # Get initial design + input_vars = {"x": (0.0, 10.0), "y": (-5.0, 5.0)} + output_vars = ["result"] + X = algo.get_initial_design(input_vars, output_vars) + + # Simulate outputs (constant function - will have tight confidence interval) + Y = [50.0 for _ in X] # All same value + + # Call get_next_design - should return empty list (converged) + next_design = algo.get_next_design(X, Y) + + # Verify empty list is returned (algorithm converged) + assert isinstance(next_design, list) + assert len(next_design) == 0 + + +def test_r_algorithm_data_type_conversion(): + """Test that data types are correctly converted between Python and R""" + from fz.algorithms import load_algorithm + + # Get path to R algorithm + repo_root = Path(__file__).parent.parent + r_algo_path = repo_root / "examples" / "algorithms" / "montecarlo_uniform.R" + + # Load R algorithm + algo = load_algorithm(str(r_algo_path), batch_sample_size=3, seed=42) + + # Get initial design + input_vars = {"x": (0.0, 10.0), "y": (-5.0, 5.0)} + output_vars = ["result"] + X = algo.get_initial_design(input_vars, output_vars) + + # Test with various output types + Y = [ + 10.5, # float + None, # None -> NULL in R + 25.3 # float + ] + + # Call get_next_design - should handle mixed types + next_design = algo.get_next_design(X, Y) + + # Verify it works + assert isinstance(next_design, list) + + # Call get_analysis + analysis = algo.get_analysis(X, Y) + + # Verify analysis data types + assert isinstance(analysis["data"]["mean"], float) + assert isinstance(analysis["data"]["std"], float) + assert isinstance(analysis["data"]["n_samples"], (int, float)) + + +def test_r_algorithm_multiple_variables(): + """Test R algorithm with multiple input variables""" + from fz.algorithms import load_algorithm + + # Get path to R algorithm + repo_root = Path(__file__).parent.parent + r_algo_path = repo_root / "examples" / "algorithms" / "montecarlo_uniform.R" + + # Load R algorithm + algo = load_algorithm(str(r_algo_path), batch_sample_size=5, seed=42) + + # Get initial design with 3 variables + input_vars = { + "x": (0.0, 10.0), + "y": (-5.0, 5.0), + "z": (1.0, 3.0) + } + output_vars = ["result"] + X = algo.get_initial_design(input_vars, output_vars) + + # Verify all variables are present + assert all("x" in point and "y" in point and "z" in point for point in X) + assert all(0.0 <= point["x"] <= 10.0 for point in X) + assert all(-5.0 <= point["y"] <= 5.0 for point in X) + assert all(1.0 <= point["z"] <= 3.0 for point in X) + + +def test_r_algorithm_error_handling(): + """Test that loading non-existent R file raises appropriate error""" + from fz.algorithms import load_algorithm + + # Try to load non-existent R file + with pytest.raises(ValueError, match="Algorithm file not found"): + load_algorithm("nonexistent_algorithm.R") + + +def test_r_algorithm_invalid_extension(): + """Test that loading file with wrong extension raises error""" + from fz.algorithms import load_algorithm + import tempfile + + # Create a temp file with wrong extension + with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f: + temp_path = f.name + f.write(b"dummy content") + + try: + # Try to load file with wrong extension + with pytest.raises(ValueError, match="must be a Python \\(\\.py\\) or R \\(\\.R\\) file"): + load_algorithm(temp_path) + finally: + # Clean up + import os + os.unlink(temp_path)