Source code for pathsim.blocks.differentiator

#########################################################################################
##
##                               DIFFERENTIATOR BLOCK 
##                            (blocks/differentiator.py)
##
##                                Milan Rother 2024
##
#########################################################################################

# IMPORTS ===============================================================================

import numpy as np

from ._block import Block


# BLOCKS ================================================================================

[docs] class Differentiator(Block): """Differentiates the input signal (SISO) using a first order transfer function with a pole at the origin which implements a high pass filter. H_diff(s) = s / (1 + s/f_max) The approximation holds for signals up to a frequency of approximately f_max. Notes ----- Depending on 'f_max', the resulting system might become stiff or ill conditioned! As a practical choice set f_max to 3x the highest expected signal frequency. Parameters ---------- f_max : float highest expected signal frequency """ def __init__(self, f_max=1e2): super().__init__() #maximum frequency for differentiator approximation self.f_max = f_max def __len__(self): return 1 if self._active else 0
[docs] def set_solver(self, Solver, **solver_args): """set the internal numerical integrator Parameters ---------- Solver : Solver numerical integration solver class solver_args : dict parameters for solver initialization """ #change solver if already initialized if self.engine is not None: self.engine = Solver.cast(self.engine, **solver_args) return #quit early #initialize the numerical integration engine with kernel def _f(x, u, t): return - self.f_max * (x - u) def _jac(x, u, t): return - self.f_max self.engine = Solver(0.0, _f, _jac, **solver_args)
[docs] def update(self, t): """update system equation fixed point loop Parameters ---------- t : float evaluation time Returns ------- error : float relative error to previous iteration for convergence control """ prev_output = self.outputs[0] self.outputs[0] = -self.f_max * (self.engine.get() - self.inputs[0]) return abs(prev_output - self.outputs[0])
[docs] def solve(self, t, dt): """advance solution of implicit update equation Parameters ---------- t : float evaluation time dt : float integration timestep Returns ------- error : float solver residual norm """ return self.engine.solve(self.inputs[0], t, dt)
[docs] def step(self, t, dt): """compute update step with integration engine Parameters ---------- t : float evaluation time dt : float integration timestep Returns ------- success : bool step was successful error : float local truncation error from adaptive integrators scale : float timestep rescale from adaptive integrators """ return self.engine.step(self.inputs[0], t, dt)