derived (pmrf.derived)
- pmrf.derived(fn: Callable[[...], Model]) Callable[[...], Derived]
Turns a function of a base model and new parameters into a derived model constructor.
A derived model starts from a nominal model and derives a more complete one that captures some artifact (a wet section, degraded copper, a cut). The decorated function is called as
f(base, **new): exactly one positional base (a model, or any collection of models and parameters) and keyword arguments that are the new parameters (apmrf.Param, or anythingpmrf.as_param()accepts). It returns apmrf.Modelthat holds the base and the new parameters once, and calls fn on them whenever the model is used.fn receives the base and the new parameters as the model is unwrapped, so parameters arrive as physical values, as for
pmrf.tie(). It must return apmrf.Model, must be pure, and its output’s structure and port count must not depend on parameter values. Inside fn, usepmrf.replace()for fields of the object in hand andpmrf.update()for parts reached by name.Names. The base’s parameters keep the names they have on the base, and each new parameter is named by its keyword. Nothing produced inside fn is named. The derived model takes the base’s name unless
name=is passed, so a container prefixes both as usual. A derived model can be the base of another, and names accumulate flat; a parameter shared by several parts is expressed by deriving at the level that owns it.fn is a static part of the model: two models derived with the same function share a jit cache entry. Define it once at module level; a lambda created on every call recompiles.
- Parameters:
fn (Callable) –
fn(base, **new) -> Model.- Returns:
constructor(base, *, name=None, **new) -> Derived.- Return type:
Callable
- Raises:
TypeError – On a call with other than one positional base or with no new parameters, or (when the model is used) if fn does not return a model.
ValueError – If a keyword clashes with a parameter name of the base.
Examples
A coaxial cable of total length
Lthat is wet for its firstwet_length:@prf.derived def wet(cable, wet_length, wet_ep_r): wet = prf.replace(cable, length=wet_length, dielectric=prf.replace(cable.dielectric, ep_r=wet_ep_r)) dry = prf.replace(cable, length=cable.length - wet_length) return wet ** dry coax = wet(coax, wet_length=prf.Random(Uniform(0, 20), scale=1e-3), wet_ep_r=prf.Random(Uniform(1, 80))) prf.params(coax) # the cable's names, plus 'wet_length' and 'wet_ep_r'