Skip to content

Funz/fz-AlgorithmR

Repository files navigation

fz-AlgorithmR

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.

Features

Algorithm Interface (R S3 class)

Every R algorithm must implement these S3 methods:

  • Constructor(...): S3 constructor accepting algorithm-specific options
  • get_initial_design.ClassName(obj, input_variables, output_variables): Return initial set of points to evaluate
  • get_next_design.ClassName(obj, X, Y): Return next points based on previous results, or list() when finished
  • get_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)

Template Algorithm

The template includes a Random Sampling algorithm (AlgorithmR) that:

  • Generates nvalues random points uniformly in the input variable bounds
  • Is a one-shot algorithm (no iterative refinement)
  • Reports basic statistics (mean, best, worst)

Requirements

  • R must be installed on your system
  • rpy2 Python package: pip install rpy2
  • fz framework: pip install git+https://github.com/Funz/fz.git

Installation

pip install git+https://github.com/Funz/fz.git
pip install rpy2

Install the Algorithm Plugin

import fz
fz.install_algorithm("AlgorithmR")

Or from a URL:

fz.install_algorithm("https://github.com/Funz/fz-AlgorithmR")

Or using the CLI:

fz install AlgorithmR

Usage

Without fzd (standalone algorithm testing)

You 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")

With fzd (coupled with a model)

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)

Directory Structure

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

Creating Your Own R Algorithm Plugin

To create a custom R algorithm plugin based on this template:

  1. 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
  2. Rename the algorithm:

    • Rename .fz/algorithms/AlgorithmR.R to .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, #require headers
  3. Implement your algorithm:

    • get_initial_design.MyAlgorithm(): Generate your initial set of points
    • get_next_design.MyAlgorithm(): Implement your iterative logic (return list() when done)
    • get_analysis.MyAlgorithm(): Format your results
    • Optionally implement get_analysis_tmp.MyAlgorithm() for progress reporting
  4. 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
  5. Update tests and examples:

    • Edit tests/test_plugin.py to match your algorithm
    • Update the example notebooks

R Algorithm Structure

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(...))
}

Algorithm Types

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.)

Header Format

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 via fzd(..., algorithm_options={...})
  • #require: R packages that will be checked/warned if missing

Running Tests

# Run all tests
python -m pytest tests/ -v

# Or directly
python tests/test_plugin.py

Note: Tests require R and rpy2. Tests that need rpy2 will be skipped automatically if it's not available.

License

BSD 3-Clause License. See LICENSE file.

Related Links

About

Template for fz algorithm (in R)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published