A Funz plugin template repository for creating custom R algorithm plugins.
This repository serves as a template and starting point for creating new Funz algorithm plugins written in R. It provides a working example with a random sampling algorithm using R's S3 class system that you can customize for your own optimization, sampling, or design-of-experiments algorithm.
Every R algorithm must implement these S3 methods:
Constructor(...): S3 constructor accepting algorithm-specific optionsget_initial_design.ClassName(obj, input_variables, output_variables): Return initial set of points to evaluateget_next_design.ClassName(obj, X, Y): Return next points based on previous results, orlist()when finishedget_analysis.ClassName(obj, X, Y): Return final analysis results
Optional method:
get_analysis_tmp.ClassName(obj, X, Y): Return intermediate analysis at each iteration (for progress display)
The template includes a Random Sampling algorithm (AlgorithmR) that:
- Generates
nvaluesrandom points uniformly in the input variable bounds - Is a one-shot algorithm (no iterative refinement)
- Reports basic statistics (mean, best, worst)
- R must be installed on your system
- rpy2 Python package:
pip install rpy2 - fz framework:
pip install git+https://github.com/Funz/fz.git
pip install git+https://github.com/Funz/fz.git
pip install rpy2import fz
fz.install_algorithm("AlgorithmR")Or from a URL:
fz.install_algorithm("https://github.com/Funz/fz-AlgorithmR")Or using the CLI:
fz install AlgorithmRYou can test your R algorithm without any simulation code, using rpy2 directly:
from rpy2 import robjects
# Source the R algorithm
robjects.r.source(".fz/algorithms/AlgorithmR.R")
r_globals = robjects.globalenv
# Create an instance
r_algo = robjects.r["AlgorithmR"](nvalues=20, seed=123)
# Define input variable ranges as R list
r_input_vars = robjects.r('list(x = c(0.0, 10.0), y = c(-5.0, 5.0))')
r_output_vars = robjects.StrVector(["output"])
# Get initial design
r_design = r_globals['get_initial_design'](r_algo, r_input_vars, r_output_vars)
print(f"Initial design: {len(r_design)} points")Or via fz's automatic wrapper:
from fz.algorithms import load_algorithm
# Load R algorithm (fz handles rpy2 wrapping automatically)
algo = load_algorithm("AlgorithmR", nvalues=20, seed=123)
# Same Python interface as Python algorithms
design = algo.get_initial_design({"x": (0.0, 10.0), "y": (-5.0, 5.0)}, ["output"])
print(f"Initial design: {len(design)} points")Use fz.fzd() to run the R algorithm coupled with a model and calculators:
import fz
# Install model and algorithm plugins
fz.install("Model") # or your model
fz.install_algorithm("AlgorithmR")
# Run iterative design
analysis = fz.fzd(
input_path="examples/Model/input.txt",
input_variables={"x": "[0;10]", "y": "[-5;5]"},
model="Model",
output_expression="result",
algorithm="AlgorithmR",
algorithm_options={"nvalues": 20, "seed": 123},
calculators="localhost_Model",
analysis_dir="analysis_results"
)
print(analysis)fz-AlgorithmR/
├── .fz/
│ └── algorithms/
│ └── AlgorithmR.R # R algorithm implementation (S3 class)
├── .github/
│ └── workflows/
│ └── test.yml # CI workflow (includes R setup)
├── tests/
│ └── test_plugin.py # Test suite (uses rpy2)
├── example_standalone.ipynb # Notebook: algorithm without fzd
├── example_with_fzd.ipynb # Notebook: algorithm with fzd
├── LICENSE
└── README.md
To create a custom R algorithm plugin based on this template:
-
Clone this repository as a starting point:
# On GitHub: Use "Use this template" button, or: git clone https://github.com/Funz/fz-AlgorithmR.git fz-MyAlgorithmR cd fz-MyAlgorithmR
-
Rename the algorithm:
- Rename
.fz/algorithms/AlgorithmR.Rto.fz/algorithms/MyAlgorithm.R - Rename the S3 class constructor and all methods (e.g.,
MyAlgorithm <- function(...),get_initial_design.MyAlgorithm) - Update
class(obj) <- "MyAlgorithm" - Update the
#title,#author,#type,#options,#requireheaders
- Rename
-
Implement your algorithm:
get_initial_design.MyAlgorithm(): Generate your initial set of pointsget_next_design.MyAlgorithm(): Implement your iterative logic (returnlist()when done)get_analysis.MyAlgorithm(): Format your results- Optionally implement
get_analysis_tmp.MyAlgorithm()for progress reporting
-
Update metadata headers:
#title: My Optimization Algorithm #author: Your Name #type: optimization #options: max_iter=100;tol=0.001;population_size=20 #require: MASS;lhs
-
Update tests and examples:
- Edit
tests/test_plugin.pyto match your algorithm - Update the example notebooks
- Edit
An R algorithm file must follow the S3 class pattern:
#title: My Algorithm
#author: Author Name
#type: optimization
#options: max_iter=100;tol=0.01
#require: MASS
# Constructor
MyAlgorithm <- function(...) {
opts <- list(...)
obj <- list(
options = list(
max_iter = as.integer(ifelse(is.null(opts$max_iter), 100, opts$max_iter)),
tol = as.numeric(ifelse(is.null(opts$tol), 0.01, opts$tol))
)
)
class(obj) <- "MyAlgorithm"
return(obj)
}
# Generic definitions (if not already defined)
if (!exists("get_initial_design")) {
get_initial_design <- function(obj, ...) UseMethod("get_initial_design")
}
# ... same for get_next_design, get_analysis, get_analysis_tmp
# S3 Methods
get_initial_design.MyAlgorithm <- function(obj, input_variables, output_variables) {
# Return list of named lists
}
get_next_design.MyAlgorithm <- function(obj, X, Y) {
# Return list() when done
}
get_analysis.MyAlgorithm <- function(obj, X, Y) {
# Return list(text = "...", data = list(...))
}Common algorithm types (set in #type header):
sampling: Random sampling, Latin Hypercube, etc.optimization: Gradient descent, PSO, Brent, etc.sensitivity: Sobol, Morris, etc.doe: Design of experiments (full factorial, etc.)
Algorithm files support these metadata headers:
#title: Algorithm display name
#author: Author name
#type: algorithm category (sampling, optimization, sensitivity, ...)
#options: key1=default1;key2=default2;...
#require: Rpackage1;Rpackage2;...#options: Default values for algorithm options. Users can override these viafzd(..., algorithm_options={...})#require: R packages that will be checked/warned if missing
# Run all tests
python -m pytest tests/ -v
# Or directly
python tests/test_plugin.pyNote: Tests require R and rpy2. Tests that need rpy2 will be skipped automatically if it's not available.
BSD 3-Clause License. See LICENSE file.
- Funz/fz - Main framework
- Funz/fz-Algorithm - Template for Python algorithm plugins
- Funz/fz-Model - Template for model plugins