setRateFunction: Set own rate function to replace mizer rate function

View source: R/extension.R

setRateFunctionR Documentation

Set own rate function to replace mizer rate function

Description

If the way mizer calculates a fundamental rate entering the model is not flexible enough for you (for example if you need to introduce time dependence) then you can write your own functions for calculating that rate and use setRateFunction() to register it with mizer.

Usage

setRateFunction(params, rate, fun)

getRateFunction(params, rate)

other_params(params)

other_params(params) <- value

Arguments

params

A MizerParams object

rate

Name of the rate for which a new function is to be set.

fun

Name of the function to use to calculate the rate.

value

A named list of user-defined parameters to store in other_params(params).

Details

At each time step during a simulation with the project() function, mizer needs to calculate the instantaneous values of the various rates. By default it calls the mizerRates() function which creates a list with the following components:

  • encounter from mizerEncounter()

  • feeding_level from mizerFeedingLevel()

  • pred_rate from mizerPredRate()

  • pred_mort from mizerPredMort()

  • f_mort from mizerFMort()

  • mort from mizerMort()

  • resource_mort from mizerResourceMort()

  • e from mizerEReproAndGrowth()

  • e_repro from mizerERepro()

  • e_growth from mizerEGrowth()

  • diffusion from mizerDiffusion()

  • rdi from mizerRDI()

  • rdd from BevertonHoltRDD()

For each of these you can substitute your own function. So for example if you have written your own function for calculating the total mortality rate and have called it myMort and have a mizer model stored in a MizerParams object called params that you want to run with your new mortality rate, then you would call

params <- setRateFunction(params, "Mort", "myMort")

In general if you want to replace a function mizerSomeRateFunc() with a function myVersionOfThis() you would call

params <- setRateFunction(params, "SomeRateFunc", "myVersionOfThis")

In some extreme cases you may need to swap out the entire mizerRates() function for your own function called myRates(). That you can do with

params <- setRateFunction(params, "Rates", "myRates")

Your new rate functions may need their own model parameters. These you can store in other_params(params). For example

other_params(params)$my_param <- 42

Note that your own rate functions need to be defined in the global environment or in a package. If they are defined within a function then mizer will not find them.

Value

For setRateFunction(): An updated MizerParams object

For getRateFunction(): The name of the registered rate function for the requested rate, or the list of all rate functions if called without rate argument.

For other_params(): The user-defined parameters stored in other_params(params), or NULL if none have been set. This excludes any component-specific parameters stored via setComponent().

Avoid rates that jump as a function of abundance

Make sure your rate function depends continuously on the abundances n, n_pp and n_other. It is tempting to write a rate that switches abruptly on the state of the model — a fishery that closes when a stock falls below a limit reference point, a predator that switches diet when its preferred prey becomes scarce, a mortality that kicks in below a critical condition. Such a rate breaks the assumption underlying every one of mizer's time-stepping methods, which freeze the rates during each density update and so cannot see a threshold being crossed within a step.

The symptoms are quiet: mizer issues no warning, but the trajectory keeps changing as you refine dt, the Newton solver stalls, and getStability() reports a confident but meaningless answer. Choosing the L-stable method = "tr_bdf2" in project() does not help, because the difficulty lies in the frozen rates rather than in the linear solve.

The remedy is to give the switch a finite width, using a linear ramp between two thresholds or a logistic transition, which is usually the more realistic model anyway. Rates built with max() or min() are continuous but not differentiable; these are much less troublesome, costing some accuracy but not correctness. See the Discontinuous rate functions article for the full story, the diagnostics and the fix.

See Also

"Extending mizer": guide to extending mizer; Discontinuous rate functions

Other extension tools: NOther(), clearExtensionChain(), coerceToExtensionClass(), getRegisteredExtensions(), initialNOther<-(), recordExtension(), registerExtension(), registerExtensions(), setComponent()


mizer documentation built on Aug. 24, 2026, 9:08 a.m.