From e4e55a0cc2d7b1cccfe28b6d0f0a88eb1146fc3d Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Mon, 3 Mar 2025 09:50:42 +0000 Subject: [PATCH] build based on e912fc8 --- dev/.documenter-siteinfo.json | 2 +- .../introductoryResources/index.html | 2 +- dev/background/liqss/index.html | 2 +- dev/background/mliqss/index.html | 2 +- dev/background/qss/index.html | 2 +- dev/developer/algorithm/index.html | 2 +- dev/developer/devIntro/index.html | 2 +- dev/developer/integrator/index.html | 2 +- dev/developer/problem/index.html | 48 +++++++++---------- dev/developer/quantizer/index.html | 2 +- dev/developer/solution/index.html | 4 +- dev/developer/solve/index.html | 2 +- dev/developer/taylor/index.html | 6 +-- dev/developer/utils/index.html | 2 +- dev/examples/adr/index.html | 2 +- dev/examples/dosing/index.html | 2 +- .../linearTimeInvariantSystem/index.html | 2 +- .../index.html | 2 +- dev/examples/tysonModel/index.html | 2 +- dev/examples/vanderpol/index.html | 2 +- dev/guide/userAPI/index.html | 10 ++-- dev/guide/userTutorial/index.html | 2 +- dev/index.html | 2 +- 23 files changed, 53 insertions(+), 53 deletions(-) diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index b9cd542..3fceb23 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.7.3","generation_timestamp":"2025-03-01T11:11:46","documenter_version":"1.8.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.7.3","generation_timestamp":"2025-03-03T09:50:37","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/dev/background/introductoryResources/index.html b/dev/background/introductoryResources/index.html index 3c6a509..b01402b 100644 --- a/dev/background/introductoryResources/index.html +++ b/dev/background/introductoryResources/index.html @@ -11,4 +11,4 @@ & \qquad \qquad...\\ & \qquad d_p=L(x_i...,d_p...,t) \\ & \qquad \qquad...\\ -\end{align*}\]

where $n$ and $m$ are the number of state variables and discrete variables of the system respectively. $D=[d_1,d_2...,d_m]^T$ is the vector of the system discrete variables. $v$ is the number of events and $zc$ is an event condition, $H$ and $L$ are functions used in the effects of the event $zc$.

QSS methods were shown to have nice stability and error bound properties and they outperformed some classic solvers [2].

References

[1] Cellier, F. and Kofman, E. (2006). Continuous system. Springer, simulation.New York.

[2] Kofman, E. (2009). Relative error control in quantization based integration. Latin American Applied Research, 39(no.3):pp.231–238.

+\end{align*}\]

where $n$ and $m$ are the number of state variables and discrete variables of the system respectively. $D=[d_1,d_2...,d_m]^T$ is the vector of the system discrete variables. $v$ is the number of events and $zc$ is an event condition, $H$ and $L$ are functions used in the effects of the event $zc$.

QSS methods were shown to have nice stability and error bound properties and they outperformed some classic solvers [2].

References

[1] Cellier, F. and Kofman, E. (2006). Continuous system. Springer, simulation.New York.

[2] Kofman, E. (2009). Relative error control in quantization based integration. Latin American Applied Research, 39(no.3):pp.231–238.

diff --git a/dev/background/liqss/index.html b/dev/background/liqss/index.html index fe91bf0..944c6e2 100644 --- a/dev/background/liqss/index.html +++ b/dev/background/liqss/index.html @@ -4,4 +4,4 @@ x_i\mp\Delta_i & if \dot x_i . \tilde{f}_i(x_i\mp\Delta_i) >0 \\ \frac{-u_{ii}}{a_{ii}} & otherwise \end{cases} -\end{equation*}\]

where $\tilde{f}_i=a_{ii}.q_i+u_{ii}$ is a linear approximation of the derivative function $f_i$ at the future instant.

The LIQSS order 1 method is defined in the following Algorithm: LIQSS1 algorithm

  1. If a variable $i$ needs to change
    • Compute the elapsed time $e$ since the last update of variable $i$
    • Update its value using Taylor expansion: $x_{i}=x_{i}+\dot x_i.e$
    • Update the quantum $\Delta_i$
    • If $\dot x . (a_{ii}.(x_i+sign(\dot x).\Delta_i)+u_{ii}) >0$
      • Update the Quantized variable $q_i=x_i+sign(\dot x).\Delta_i$
    • Else
      • Update the Quantized variable $q_i=\frac{-u_{ii}}{a_{ii}}$
    • Compute the next time when $q_i=x_i$
    • For {any variable $j$ depends on $i$}
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j$
      • Update the derivative $\dot x_{j}=f_j(q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_i$
    • For {any zero crossing function $zc$ depends on $i$}
      • Update $zc$
      • Compute the next event time of $zc$
  2. If an event needs to occur
    • Recheck validity of the event
    • Execute the event and update the related quantized variables
    • For any variable $j$ depends on the event
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j$
      • Update the derivative $\dot x_j=f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_j$
    • For any zero crossing function $zc$ depends on the event
      • Update $zc$
      • Compute the next event time of $zc$

LIQSS2

In Order 2, the updates involve not only the first-order variables but also their second-order derivatives. Similar to Order 1, these updates depend on the future behavior of the state variables, but with a focus on both their positions and rates of change as reflected in the second-order derivative terms. To define LIQSS2, we need to consider the second derivative of the state variables. The linear approximation of the future second derivative is given as follows: $\ddot x_i=a_{ii}.\dot q_i+\dot u_{ii}$.

The LIQSS order 2 method is defined in the following Algorithm. LIQSS2 algorithm

  1. If a variable $i$ needs to change
    • Compute the elapsed time $e$ since the last update of variable $i$
    • Update the variable $x_{i}=x_{i}+\dot x_i.e_i+\frac{1}{2}\ddot x_i.e_i^2$
    • Update the quantum $\Delta_i$
    • Update the derivative $\dot x_{i}=\dot x_{i}+\ddot x_i.e$
    • Update the affine coefficient $u_{ii} = \dot x_i - a_{ii} . (q_{i}+\dot q_i.e_i)$
    • Update the derivative of the affine coefficient $\dot u_{ii} = \ddot x_i - a_{ii} . \dot q_i$
    • The Quantized variable $q_i(h)=\frac{(x_i-h.a_{ii}.x_i-h^2.(a.u_{ii}+\dot u_{ii})/2)}{(1 - h . a_{ii} + h^2.a_{ii}^2 / 2)}$
    • Update the step size $h=Final\;Simulation\;Time-current\;Sim\;Time$; $q_i=q_i(h)$
    • If {$|q_i-x_i|>\Delta_i$}
      • Update the Quantized variable $h=\sqrt{\frac{2\Delta_i}{|ddx_i|}}$; $q_i=q_i(h)$
    • While $|q_i-x_i|>\Delta_i$
      • Update the Quantized variable $h=h\sqrt{\frac{\Delta_i}{|q_i-x_i|}}$; $q_i=q_i(h)$
    • Update the Quantized derivative $\dot q_i=\frac{a_{ii}.q_i+u_{ii}+h.\dot u_{ii}}{1-h.a_{ii}}$
    • Compute the next time when $q_i=x_i$
    • For any variable $j$ depends on $i$
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j+\frac{1}{2}\ddot x_j.e_j^2$
      • For {any variable $k$ that $f_j$ depends upon}
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update the derivatives $\dot x_{j}=f_j(q,t) \; and \ddot x_j=\dot f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_i$
    • For any zero crossing function $zc$ depends on $i$
      • For {any variable $k$ that $zc$ depends upon}
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update $zc$
      • Compute the next event time of $zc$
  2. If an event needs to occur
    • Recheck validity of the event
    • Execute the event and update the related quantized variables
    • For any variable $j$ depends on the event
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j+\frac{1}{2}\ddot x_j.e_j^2$
      • For any variable $k$ that $f_j$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update the derivatives $\dot x_j=f_j(Q,t) \; and \ddot x_j=\dot f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_j$
    • For any zero crossing function $zc$ depends on the event
      • For any variable $k$ that $zc$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update $zc$
      • Compute the next event time of $zc$

References

[1] Migoni, G., Kofman, E., and Cellier, F. (2012). Quantization-based new integration methods for stiff odes. Simulation: Transactions of the Society for Modeling and Simulation International, 88(4):378–407.

[2] G. Migoni, M. Bortolotto, E. Kofman, and F. Cellier. Linearly implicit quantization-based integration methods for stiff ordinary differential equations. Simulation Modelling Practice and Theory, vol.35:pp.118–136, 2013.

+\end{equation*}\]

where $\tilde{f}_i=a_{ii}.q_i+u_{ii}$ is a linear approximation of the derivative function $f_i$ at the future instant.

The LIQSS order 1 method is defined in the following Algorithm: LIQSS1 algorithm

  1. If a variable $i$ needs to change
    • Compute the elapsed time $e$ since the last update of variable $i$
    • Update its value using Taylor expansion: $x_{i}=x_{i}+\dot x_i.e$
    • Update the quantum $\Delta_i$
    • If $\dot x . (a_{ii}.(x_i+sign(\dot x).\Delta_i)+u_{ii}) >0$
      • Update the Quantized variable $q_i=x_i+sign(\dot x).\Delta_i$
    • Else
      • Update the Quantized variable $q_i=\frac{-u_{ii}}{a_{ii}}$
    • Compute the next time when $q_i=x_i$
    • For {any variable $j$ depends on $i$}
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j$
      • Update the derivative $\dot x_{j}=f_j(q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_i$
    • For {any zero crossing function $zc$ depends on $i$}
      • Update $zc$
      • Compute the next event time of $zc$
  2. If an event needs to occur
    • Recheck validity of the event
    • Execute the event and update the related quantized variables
    • For any variable $j$ depends on the event
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j$
      • Update the derivative $\dot x_j=f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_j$
    • For any zero crossing function $zc$ depends on the event
      • Update $zc$
      • Compute the next event time of $zc$

LIQSS2

In Order 2, the updates involve not only the first-order variables but also their second-order derivatives. Similar to Order 1, these updates depend on the future behavior of the state variables, but with a focus on both their positions and rates of change as reflected in the second-order derivative terms. To define LIQSS2, we need to consider the second derivative of the state variables. The linear approximation of the future second derivative is given as follows: $\ddot x_i=a_{ii}.\dot q_i+\dot u_{ii}$.

The LIQSS order 2 method is defined in the following Algorithm. LIQSS2 algorithm

  1. If a variable $i$ needs to change
    • Compute the elapsed time $e$ since the last update of variable $i$
    • Update the variable $x_{i}=x_{i}+\dot x_i.e_i+\frac{1}{2}\ddot x_i.e_i^2$
    • Update the quantum $\Delta_i$
    • Update the derivative $\dot x_{i}=\dot x_{i}+\ddot x_i.e$
    • Update the affine coefficient $u_{ii} = \dot x_i - a_{ii} . (q_{i}+\dot q_i.e_i)$
    • Update the derivative of the affine coefficient $\dot u_{ii} = \ddot x_i - a_{ii} . \dot q_i$
    • The Quantized variable $q_i(h)=\frac{(x_i-h.a_{ii}.x_i-h^2.(a.u_{ii}+\dot u_{ii})/2)}{(1 - h . a_{ii} + h^2.a_{ii}^2 / 2)}$
    • Update the step size $h=Final\;Simulation\;Time-current\;Sim\;Time$; $q_i=q_i(h)$
    • If {$|q_i-x_i|>\Delta_i$}
      • Update the Quantized variable $h=\sqrt{\frac{2\Delta_i}{|ddx_i|}}$; $q_i=q_i(h)$
    • While $|q_i-x_i|>\Delta_i$
      • Update the Quantized variable $h=h\sqrt{\frac{\Delta_i}{|q_i-x_i|}}$; $q_i=q_i(h)$
    • Update the Quantized derivative $\dot q_i=\frac{a_{ii}.q_i+u_{ii}+h.\dot u_{ii}}{1-h.a_{ii}}$
    • Compute the next time when $q_i=x_i$
    • For any variable $j$ depends on $i$
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j+\frac{1}{2}\ddot x_j.e_j^2$
      • For {any variable $k$ that $f_j$ depends upon}
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update the derivatives $\dot x_{j}=f_j(q,t) \; and \ddot x_j=\dot f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_i$
    • For any zero crossing function $zc$ depends on $i$
      • For {any variable $k$ that $zc$ depends upon}
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update $zc$
      • Compute the next event time of $zc$
  2. If an event needs to occur
    • Recheck validity of the event
    • Execute the event and update the related quantized variables
    • For any variable $j$ depends on the event
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j+\frac{1}{2}\ddot x_j.e_j^2$
      • For any variable $k$ that $f_j$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update the derivatives $\dot x_j=f_j(Q,t) \; and \ddot x_j=\dot f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_j$
    • For any zero crossing function $zc$ depends on the event
      • For any variable $k$ that $zc$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update $zc$
      • Compute the next event time of $zc$

References

[1] Migoni, G., Kofman, E., and Cellier, F. (2012). Quantization-based new integration methods for stiff odes. Simulation: Transactions of the Society for Modeling and Simulation International, 88(4):378–407.

[2] G. Migoni, M. Bortolotto, E. Kofman, and F. Cellier. Linearly implicit quantization-based integration methods for stiff ordinary differential equations. Simulation Modelling Practice and Theory, vol.35:pp.118–136, 2013.

diff --git a/dev/background/mliqss/index.html b/dev/background/mliqss/index.html index 68cabf5..7a4a1ae 100644 --- a/dev/background/mliqss/index.html +++ b/dev/background/mliqss/index.html @@ -32,4 +32,4 @@ \beta=-(h.I-h^2.A_{ij}/2).(I-h.A_{ij})^{-1}.(U_{ij}+h.\dot U_{ij})+\alpha \nonumber\\ \gamma=(I-h.A_{ij})+(h.I-h^2.A_{ij}/2).(I-h.A_{ij})^{-1}.A_{ij} \nonumber\\ Q_{ij}= \gamma^{-1}.\beta - \end{align}\]

where $\dot Q_{ij}=$ $\begin{pmatrix} \dot q_i \\ \dot q_j \end{pmatrix}$ and $\dot U_{ij}=$ $\begin{pmatrix} \dot u_{ij} \\ \dot u_{ji} \end{pmatrix}$

The value of $h$ is computed analytically or via iterations as the maximum value that satisfies Eq.(5).

References

[1] F. Pietro, G. Migoni, and E. Kofman. Improving linearly implicit quantized state system methods. Simulation: Transactions of the Society for Modeling and Simulation International, vol.95(no.2):pp.127–144, 2019.

+ \end{align}\]

where $\dot Q_{ij}=$ $\begin{pmatrix} \dot q_i \\ \dot q_j \end{pmatrix}$ and $\dot U_{ij}=$ $\begin{pmatrix} \dot u_{ij} \\ \dot u_{ji} \end{pmatrix}$

The value of $h$ is computed analytically or via iterations as the maximum value that satisfies Eq.(5).

References

[1] F. Pietro, G. Migoni, and E. Kofman. Improving linearly implicit quantized state system methods. Simulation: Transactions of the Society for Modeling and Simulation International, vol.95(no.2):pp.127–144, 2019.

diff --git a/dev/background/qss/index.html b/dev/background/qss/index.html index 9fc075b..4c5da3d 100644 --- a/dev/background/qss/index.html +++ b/dev/background/qss/index.html @@ -4,4 +4,4 @@ \end{align*}\]

where $x_{i}$ is the $i^{th}$ state variable, $\dot x_i$ is the derivative of this state variable, and $e$ is the elapsed time since its last update. The next time of change is computed as $t_i^n=t_{current}+\frac{\Delta_i}{|\dot x_i|}$ where $\Delta_i$ is the quantum of the variable $x_i$. The QSS1 method is defined in the foloowing Algorithm.

QSS1 algorithm

  1. If a variable $i$ needs to change
    • Compute the elapsed time $e_i$ since the last update of variable $i$
    • Update the variable $x_{i}=x_{i}+\dot x_i.e_i$
    • Update the quantum $\Delta_i$
    • Update the Quantized variable $q_i$ = $x_i$
    • Compute the next time of change $t_i^n$
    • For any variable $j$ depends on $i$
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j$
      • Update the derivative $\dot x_j=f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_j$
    • For any zero crossing function $zc$ depends on $i$
      • Update $zc$
      • Compute the next event time of $zc$
  2. If an event needs to occur
    • recheck validity of the event
    • execute the event and update the related quantized variables
    • For any variable $j$ depends on the event
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j$
      • Update the derivative $\dot x_j=f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_j$
    • For any zero crossing function $zc$ depends on the event
      • Update $zc$
      • Compute the next event time of $zc$

QSS2

The QSS2 method is a second-order method. The state variables are updated using a Taylor expansion given by the following equations:

\[ \begin{align*} & x_{i}=x_{i}+\dot x_i.e_i+\frac{1}{2}\ddot x_i.e_i^2 \\ & \dot x_{i}=\dot x_{i}+\ddot x_i.e_i - \end{align*}\]

where $\ddot x_i$ is the second derivative of this state variable. The next time of change is computed as $t_i^n=t_{current}+sqrt(\frac{\Delta_i}{|\ddot x_i|})$. The QSS2 method is defined in the following Algorithm.

QSS2 algorithm

  1. If a variable $i$ needs to change
    • Compute the elapsed time $e_i$ since the last update of variable $i$
    • Update the variable $x_{i}=x_{i}+\dot x_i.e_i+\frac{1}{2}\ddot x_i.e_i^2$
    • Update the quantum $\Delta_i$
    • Update the variable $\dot x_{i}=\dot x_{i}+\ddot x_i.e$
    • Update the Quantized variable $q_i$ = $x_i$
    • Update the Quantized derivative $\dot q_i$ = $\dot x_i$
    • Compute the next time of change $t_i^n$
    • For any variable $j$ depends on $i$
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j+\frac{1}{2}\ddot x_j.e_j^2$
      • For any variable $k$ that $f_j$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update the derivative $\dot x_j=f_j(Q,t)$
      • Update the second derivative $\ddot x_j=\dot f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_j$
    • For any zero crossing function $zc$ depends on $i$
      • For any variable $k$ that $zc$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update $zc$
      • Compute the next event time of $zc$
  2. If an event needs to occur
    • recheck validity of the event
    • execute the event and update the related quantized variables
    • For any variable $j$ depends on the event
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j+\frac{1}{2}\ddot x_j.e_j^2$
      • For any variable $k$ that $f_j$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update the derivative $\dot x_j=f_j(Q,t)$
      • Update the second derivative $\ddot x_j=\dot f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_j$
    • For any zero crossing function $zc$ depends on the event
      • For any variable $k$ that $zc$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update $zc$
      • Compute the next event time of $zc$
+ \end{align*}\]

where $\ddot x_i$ is the second derivative of this state variable. The next time of change is computed as $t_i^n=t_{current}+sqrt(\frac{\Delta_i}{|\ddot x_i|})$. The QSS2 method is defined in the following Algorithm.

QSS2 algorithm

  1. If a variable $i$ needs to change
    • Compute the elapsed time $e_i$ since the last update of variable $i$
    • Update the variable $x_{i}=x_{i}+\dot x_i.e_i+\frac{1}{2}\ddot x_i.e_i^2$
    • Update the quantum $\Delta_i$
    • Update the variable $\dot x_{i}=\dot x_{i}+\ddot x_i.e$
    • Update the Quantized variable $q_i$ = $x_i$
    • Update the Quantized derivative $\dot q_i$ = $\dot x_i$
    • Compute the next time of change $t_i^n$
    • For any variable $j$ depends on $i$
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j+\frac{1}{2}\ddot x_j.e_j^2$
      • For any variable $k$ that $f_j$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update the derivative $\dot x_j=f_j(Q,t)$
      • Update the second derivative $\ddot x_j=\dot f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_j$
    • For any zero crossing function $zc$ depends on $i$
      • For any variable $k$ that $zc$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update $zc$
      • Compute the next event time of $zc$
  2. If an event needs to occur
    • recheck validity of the event
    • execute the event and update the related quantized variables
    • For any variable $j$ depends on the event
      • Update the variable $x_{j}=x_{j}+\dot x_j.e_j+\frac{1}{2}\ddot x_j.e_j^2$
      • For any variable $k$ that $f_j$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update the derivative $\dot x_j=f_j(Q,t)$
      • Update the second derivative $\ddot x_j=\dot f_j(Q,t)$
      • Compute the next time when $q_j=x_j \; or |q_j-x_j|=2\Delta_j$
    • For any zero crossing function $zc$ depends on the event
      • For any variable $k$ that $zc$ depends upon
        • Update the Quantized variable $q_{k}=q_{k}+\dot q_k.e_k$
      • Update $zc$
      • Compute the next event time of $zc$
diff --git a/dev/developer/algorithm/index.html b/dev/developer/algorithm/index.html index 5672220..e7d7183 100644 --- a/dev/developer/algorithm/index.html +++ b/dev/developer/algorithm/index.html @@ -1,2 +1,2 @@ -QSS Algorithms · Quantized System Solver

QSS Algorithms

The Algorithm type is parametric on the solver name (N) and order (O). Currently there are three specific algorithm names: (QSS Algorithm, LiQSS Algorithm, and mLiQSS Algorithm), and two orders (1 and 2).

Algorithm extension

Any new algorithm can be added via the name N which is of type Val, and with the order O which also of type Val according to this type:

What is needed with a new algorithm:

  • A new algorithm with the same old name and a different order (>2) requires an addition only of the quantizer methods.
  • A new algorithm with a new name and an old order (1,2) requires an addition of an integrate method only.
  • A new algorithm with a new name and a new order requires an addition of an integrate method and addition of the quantizer methods.
  • Creating a new superclass similar to the QSSAlgorithm requires an addition of a new solve function.

Example

my_new_algorithm()=QSSAlgorithm(Val(:my_new_algorithm),Val(3))

This is a new algorithm name of order 3 belongs to the family of the QSSAlgorithm. Only an addition of the integrate and the quantizer methods is needed.

+QSS Algorithms · Quantized System Solver

QSS Algorithms

The Algorithm type is parametric on the solver name (N) and order (O). Currently there are three specific algorithm names: (QSS Algorithm, LiQSS Algorithm, and mLiQSS Algorithm), and two orders (1 and 2).

Algorithm extension

Any new algorithm can be added via the name N which is of type Val, and with the order O which also of type Val according to this type:

What is needed with a new algorithm:

  • A new algorithm with the same old name and a different order (>2) requires an addition only of the quantizer methods.
  • A new algorithm with a new name and an old order (1,2) requires an addition of an integrate method only.
  • A new algorithm with a new name and a new order requires an addition of an integrate method and addition of the quantizer methods.
  • Creating a new superclass similar to the QSSAlgorithm requires an addition of a new solve function.

Example

my_new_algorithm()=QSSAlgorithm(Val(:my_new_algorithm),Val(3))

This is a new algorithm name of order 3 belongs to the family of the QSSAlgorithm. Only an addition of the integrate and the quantizer methods is needed.

diff --git a/dev/developer/devIntro/index.html b/dev/developer/devIntro/index.html index 0b56a18..d027e61 100644 --- a/dev/developer/devIntro/index.html +++ b/dev/developer/devIntro/index.html @@ -4,4 +4,4 @@ julia> ] -(@v1.x) pkg> dev("/some/path/")

Want to help in other ways? You can start contributing to the project by solving some of the issues.

Style Guides

See the Julia CONTRIBUTING.md for further information.

Components overview

While the package is optimized to be fast, extensibility is not compromised. It is divided into 3 entities that can be extended separately: Problem, Algorithm, and Solution. The package uses other packages such as MacroTools.jl for user-code parsing, SymEngine.jl for Jacobian computation, and a modified TaylorSeries.jl that uses caching to obtain free Taylor variables. The other components of the solver include the NLodeProblem function, the solve function, the scheduler, and the quantizer. The following sections provide an in-depth explanation of the key components and their interactions within the solver framework.

The QSS Solver Structure.

Create Problem structure

The problem creation Structure.

Future work

+(@v1.x) pkg> dev("/some/path/")

Want to help in other ways? You can start contributing to the project by solving some of the issues.

Style Guides

See the Julia CONTRIBUTING.md for further information.

Components overview

While the package is optimized to be fast, extensibility is not compromised. It is divided into 3 entities that can be extended separately: Problem, Algorithm, and Solution. The package uses other packages such as MacroTools.jl for user-code parsing, SymEngine.jl for Jacobian computation, and a modified TaylorSeries.jl that uses caching to obtain free Taylor variables. The other components of the solver include the NLodeProblem function, the solve function, the scheduler, and the quantizer. The following sections provide an in-depth explanation of the key components and their interactions within the solver framework.

The QSS Solver Structure.

Create Problem structure

The problem creation Structure.

Future work

diff --git a/dev/developer/integrator/index.html b/dev/developer/integrator/index.html index 0bd557c..cd32718 100644 --- a/dev/developer/integrator/index.html +++ b/dev/developer/integrator/index.html @@ -1,2 +1,2 @@ -Integrators · Quantized System Solver

Integrators

QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:qss,O}, CommonqssData::CommonQSS_Data{0}, odep::NLODEProblem{F,PRTYPE,T,D,0,CS}, f::Function, jac::Function, SD::Function) where {F,PRTYPE,O,T,CS,D}

Integrates a nonlinear ordinary differential equation (ODE) problem using a Quantized State System (QSS) algorithm.

Arguments

  • Al::QSSAlgorithm{:qss,O}: The QSS algorithm to be used for integration.
  • CommonqssData::CommonQSS_Data{0}: Common data structure for QSS integration.
  • odep::NLODEProblem{F,PRTYPE,T,0,0,CS}: The nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.

Returns

  • A solution
source
QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:qss,O}, CommonqssData::CommonQSS_Data{Z}, odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}, f::Function, jac::Function, SD::Function) where {F,PRTYPE,O,T,D,Z,CS}

Integrates a nonlinear ordinary differential equation (ODE) problem with events using a Quantized State System (QSS) algorithm.

Arguments

  • Al::QSSAlgorithm{:qss,O}: The QSS algorithm to be used for integration.
  • CommonqssData::CommonQSS_Data{Z}: Common data structure for QSS algorithms.
  • odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}: The nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.

Type Parameters

  • PRTYPE: The type of the problem.
  • O: The order of the QSS algorithm.
  • T: The number of continuous variables.
  • Z: The number of zero crossing functions.
  • D: The number of discrete variables
  • CS: The cache size.

Returns

  • A solution
source
QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:liqss,O}, CommonqssData::CommonQSS_Data{Z}, liqssdata::LiQSS_Data{O,3}, odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}, f::Function, jac::Function, SD::Function, exactA::Function) where {F,PRTYPE,O,T,D,Z,CS}

Integrates a nonlinear ordinary differential equation (ODE) problem with events using the LiQSS (Linearized Quantized State System) algorithm.

Arguments

  • Al::QSSAlgorithm{:liqss,O}: The QSS algorithm type for LiQSS.
  • CommonqssData::CommonQSS_Data{Z}: Common data structure for QSS algorithms.
  • liqssdata::LiQSS_Data{O,1}: Data structure specific to the LiQSS algorithm.
  • odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}: The nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.
  • exactA::Function: The exact jacobian expression function for the ODE system.

Returns

  • A solution after the integration process.
source
QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:liqss,O}, CommonqssData::CommonQSS_Data{0}, liqssdata::LiQSS_Data{O,3}, odep::NLODEProblem{F,PRTYPE,T,D,0,CS}, f::Function, jac::Function, SD::Function, exactA::Function) where {F,PRTYPE,CS,O,T,D}

Integrates a nonlinear ordinary differential equation (ODE) problem (without events) using the LiQSS (Linearized Quantized State System) algorithm.

Arguments

  • Al::QSSAlgorithm{:liqss,O}: The QSS algorithm type with the liqss method.
  • CommonqssData::CommonQSS_Data{0}: Common QSS data structure.
  • liqssdata::LiQSS_Data{O,1}: LiQSS-specific data structure.
  • odep::NLODEProblem{F,PRTYPE,T,0,0,CS}: Nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.
  • exactA::Function: The exact jacobian expression function for the ODE system.

Returns

  • A solution.
source
QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:nmliqss,O}, CommonqssData::CommonQSS_Data{Z}, liqssdata::LiQSS_Data{O,M}, odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}, f::Function, jac::Function, SD::Function, exactA::Function) where {F,PRTYPE,O,T,D,Z,CS,M}

Integrates a nonlinear ordinary differential equation (ODE) problem with events using the nmLiqss (modified Liqss that detect events) discrete integrator algorithm.

Arguments

  • Al::QSSAlgorithm{:nmliqss,O}: The QSS algorithm type for nmLiqss.
  • CommonqssData::CommonQSS_Data{Z}: Common QSS data structure.
  • liqssdata::LiQSS_Data{O,M}: LiQSS data structure.
  • odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}: Nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.
  • exactA::Function: The exact jacobian expression function for the ODE system.

Returns

  • A solution.
source
QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:nmliqss,O}, CommonqssData::CommonQSS_Data{0}, liqssdata::LiQSS_Data{O,M}, odep::NLODEProblem{F,PRTYPE,T,D,0,CS}, f::Function, jac::Function, SD::Function, exactA::Function) where {F,PRTYPE,CS,O,T,D,M}

Integrates a nonlinear ordinary differential equation (ODE) problem (without events) using the nmLiqss (modified Liqss that detect events) algorithm.

Arguments

  • Al::QSSAlgorithm{:nmliqss,O}: The QSS algorithm to be used for integration.
  • CommonqssData::CommonQSS_Data{0}: Common data structure for QSS algorithms.
  • liqssdata::LiQSS_Data{O,M}: Data specific to the LiQSS algorithm.
  • odep::NLODEProblem{F,PRTYPE,T,0,0,CS}: The nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.
  • exactA::Function: The exact jacobian expression function for the ODE system.

Returns

  • A solution
source
+Integrators · Quantized System Solver

Integrators

QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:qss,O}, CommonqssData::CommonQSS_Data{0}, odep::NLODEProblem{F,PRTYPE,T,D,0,CS}, f::Function, jac::Function, SD::Function) where {F,PRTYPE,O,T,CS,D}

Integrates a nonlinear ordinary differential equation (ODE) problem using a Quantized State System (QSS) algorithm.

Arguments

  • Al::QSSAlgorithm{:qss,O}: The QSS algorithm to be used for integration.
  • CommonqssData::CommonQSS_Data{0}: Common data structure for QSS integration.
  • odep::NLODEProblem{F,PRTYPE,T,0,0,CS}: The nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.

Returns

  • A solution
source
QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:qss,O}, CommonqssData::CommonQSS_Data{Z}, odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}, f::Function, jac::Function, SD::Function) where {F,PRTYPE,O,T,D,Z,CS}

Integrates a nonlinear ordinary differential equation (ODE) problem with events using a Quantized State System (QSS) algorithm.

Arguments

  • Al::QSSAlgorithm{:qss,O}: The QSS algorithm to be used for integration.
  • CommonqssData::CommonQSS_Data{Z}: Common data structure for QSS algorithms.
  • odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}: The nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.

Type Parameters

  • PRTYPE: The type of the problem.
  • O: The order of the QSS algorithm.
  • T: The number of continuous variables.
  • Z: The number of zero crossing functions.
  • D: The number of discrete variables
  • CS: The cache size.

Returns

  • A solution
source
QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:liqss,O}, CommonqssData::CommonQSS_Data{Z}, liqssdata::LiQSS_Data{O,3}, odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}, f::Function, jac::Function, SD::Function, exactA::Function) where {F,PRTYPE,O,T,D,Z,CS}

Integrates a nonlinear ordinary differential equation (ODE) problem with events using the LiQSS (Linearized Quantized State System) algorithm.

Arguments

  • Al::QSSAlgorithm{:liqss,O}: The QSS algorithm type for LiQSS.
  • CommonqssData::CommonQSS_Data{Z}: Common data structure for QSS algorithms.
  • liqssdata::LiQSS_Data{O,1}: Data structure specific to the LiQSS algorithm.
  • odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}: The nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.
  • exactA::Function: The exact jacobian expression function for the ODE system.

Returns

  • A solution after the integration process.
source
QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:liqss,O}, CommonqssData::CommonQSS_Data{0}, liqssdata::LiQSS_Data{O,3}, odep::NLODEProblem{F,PRTYPE,T,D,0,CS}, f::Function, jac::Function, SD::Function, exactA::Function) where {F,PRTYPE,CS,O,T,D}

Integrates a nonlinear ordinary differential equation (ODE) problem (without events) using the LiQSS (Linearized Quantized State System) algorithm.

Arguments

  • Al::QSSAlgorithm{:liqss,O}: The QSS algorithm type with the liqss method.
  • CommonqssData::CommonQSS_Data{0}: Common QSS data structure.
  • liqssdata::LiQSS_Data{O,1}: LiQSS-specific data structure.
  • odep::NLODEProblem{F,PRTYPE,T,0,0,CS}: Nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.
  • exactA::Function: The exact jacobian expression function for the ODE system.

Returns

  • A solution.
source
QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:nmliqss,O}, CommonqssData::CommonQSS_Data{Z}, liqssdata::LiQSS_Data{O,M}, odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}, f::Function, jac::Function, SD::Function, exactA::Function) where {F,PRTYPE,O,T,D,Z,CS,M}

Integrates a nonlinear ordinary differential equation (ODE) problem with events using the nmLiqss (modified Liqss that detect events) discrete integrator algorithm.

Arguments

  • Al::QSSAlgorithm{:nmliqss,O}: The QSS algorithm type for nmLiqss.
  • CommonqssData::CommonQSS_Data{Z}: Common QSS data structure.
  • liqssdata::LiQSS_Data{O,M}: LiQSS data structure.
  • odep::NLODEProblem{F,PRTYPE,T,D,Z,CS}: Nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.
  • exactA::Function: The exact jacobian expression function for the ODE system.

Returns

  • A solution.
source
QuantizedSystemSolver.integrateMethod
integrate(Al::QSSAlgorithm{:nmliqss,O}, CommonqssData::CommonQSS_Data{0}, liqssdata::LiQSS_Data{O,M}, odep::NLODEProblem{F,PRTYPE,T,D,0,CS}, f::Function, jac::Function, SD::Function, exactA::Function) where {F,PRTYPE,CS,O,T,D,M}

Integrates a nonlinear ordinary differential equation (ODE) problem (without events) using the nmLiqss (modified Liqss that detect events) algorithm.

Arguments

  • Al::QSSAlgorithm{:nmliqss,O}: The QSS algorithm to be used for integration.
  • CommonqssData::CommonQSS_Data{0}: Common data structure for QSS algorithms.
  • liqssdata::LiQSS_Data{O,M}: Data specific to the LiQSS algorithm.
  • odep::NLODEProblem{F,PRTYPE,T,0,0,CS}: The nonlinear ODE problem to be solved.
  • f::Function: The function defining the ODE system.
  • jac::Function: The Jacobian dependency function of the ODE system.
  • SD::Function: The state derivative dependency function.
  • exactA::Function: The exact jacobian expression function for the ODE system.

Returns

  • A solution
source
diff --git a/dev/developer/problem/index.html b/dev/developer/problem/index.html index be8549a..486a164 100644 --- a/dev/developer/problem/index.html +++ b/dev/developer/problem/index.html @@ -1,29 +1,29 @@ -Problem · Quantized System Solver

Problem

The NLodeProblem function is the entry point for defining a new problem to be solved by the QSS solver. It takes user-provided code, which includes system parameters, variables, equations, and event logic, and constructs a Problem object that encapsulates all the necessary information for the solver to simulate the system such as problem dimensions, dependencies, and equations. The function works by parsing the user code and extracting relevant data to populate the Problem object.

Problem extension

Problem extension can be achieved easily via PRTYPE which is of type Val, or another subtype of this superclass can be created.

QuantizedSystemSolver.NLODEProblemType
NLODEProblem{F,PRTYPE,T,D,Z,CS}

This is a superclass for all ODE problems. It is parametric on:

  • The problem type PRTYPE.
  • The number of continuous variables T
  • The number of discrete events D
  • The number of events (zero crossing functions) Z
  • The cache size CS.
source

What is needed with a new problem:

The more different the new problem from the NLODEContProblem, the more functions are needed to be extended. In general the following functions need to be extended.

  • The NLodeProblemFunc method to handle this problem.
  • The integrate method for this new type of problem.
  • The custom_Solve method if needed.

Example

struct SmallODEProblem{CS}<: NLODEProblem{0,1,1,0,0,CS} 
+Problem · Quantized System Solver

Problem

The NLodeProblem function is the entry point for defining a new problem to be solved by the QSS solver. It takes user-provided code, which includes system parameters, variables, equations, and event logic, and constructs a Problem object that encapsulates all the necessary information for the solver to simulate the system such as problem dimensions, dependencies, and equations. The function works by parsing the user code and extracting relevant data to populate the Problem object.

Problem extension

Problem extension can be achieved easily via PRTYPE which is of type Val, or another subtype of this superclass can be created.

QuantizedSystemSolver.NLODEProblemType
NLODEProblem{F,PRTYPE,T,D,Z,CS}

This is a superclass for all ODE problems. It is parametric on:

  • The problem type PRTYPE.
  • The number of continuous variables T
  • The number of discrete events D
  • The number of events (zero crossing functions) Z
  • The cache size CS.
source

What is needed with a new problem:

The more different the new problem from the NLODEContProblem, the more functions are needed to be extended. In general the following functions need to be extended.

  • The NLodeProblemFunc method to handle this problem.
  • The integrate method for this new type of problem.
  • The custom_Solve method if needed.

Example

struct SmallODEProblem{CS}<: NLODEProblem{0,1,1,0,0,CS} 
   cacheSize::Val{CS}# CS= cache size 
   initConditions::Float64   
   eq::Function#function that holds the differential equation
-end

This new problem type takes care of one differential equation. There is no need for the Jacobian nor for the dependencies. This needs an extension of the custom_Solve method that just removes the references to the jac and the SD. An extension of the integrate method is also needed since the implementation is a lot simpler than what is currently implemented.

Further reading about the functions creating the problem

NLODEDiscProblem{F,PRTYPE,T,D,Z,CS}: This is the struct that holds all the necessary data for a nonlinear ordinary differential equation (ODE) problem with discrete events. The structure includes various fields such as initial conditions, discrete variables, Jacobians, event dependencies, and other data related to how the problem is formulated. This structure serves as the core data holder for the problem and will be used in the solver. It is a parametric abstract type that has the following parameters:

PRTYPE: The type of the problem (to distinguish between various types, and allow future extension of the solver to handle new types).

T: The number of continuous variables (state variables).

Z: The number of zero-crossing functions, which are used to detect events.

Y: The actual number of events.

CS: Cache size, which is used to store intermediate operations.

The use of abstract types in this context allows for flexibility and extensibility in the solver. By defining these abstract types, the code can be easily adapted to handle different types of problems, algorithms, and solutions without needing to modify the core solver logic. This design choice enhances the maintainability and scalability of the solver, making it easier to add new features or support additional problem types in the future.

NLodeProblemFunc: After an initial preparation performed by the The NLodeProblem function, The function NLodeProblemFunc takes the resulting expressions to continue constructing an instance of the NLODEDiscProblem structure. It works in several key stages:

Initialization: The function begins by initializing vectors and dictionaries that will hold equations (equs), Jacobian dependencies (jac), zero-crossing functions (ZCjac), and event dependencies. These serve to store the different types of equations and their relationships.

Processing ODEs: It loops through each of the ODE expressions provided by the user. Depending on the type of expression (discrete variables, differential equations, or loop constructs), it processes the right-hand side (RHS) of the equation. For differential equations, it extracts dependencies to build the Jacobian and transform the equations into a more appropriate form for further use. Special cases are handled, such as if the RHS is a number or a symbol.

Handling Events: The function also processes event-related constructs (if conditions) that correspond to different points where the system might undergo discrete changes. It process the RHS of the event equations, transforms them into a suitable form, and builds the necessary dependency structures. Specifically, it constructs how discrete and continuous variables influence one another through the events.

Constructing the Function Code: After processing all ODEs and events, the function dynamically generates a Julia function code needed to store the system of ODEs and events. This code is built into a function that handles different cases (i.e., which equation to evaluate based on an index of a state change or an event).

Building Dependencies: Several helper functions that build the dependencies between variables, events. They build dependency vectors that track how discrete and continous variables influence the system. This is used to know what variables to update and determine when specific events should be checked. By tracking the relationships between variables and events, the solver can determine the appropriate actions to take at each time step. The dependencies are stored in the following vectors:

-$jac$: It determines which variables affect a derivative.

-$ZCjac$: It determines which variables affect a zero-crossing function.

-$SD$: It determines which derivatives that are affected by a given variable.

-$SZ$: It determines which zero-crossing functions that are affected by a given variable.

-$HZ$: It tells which Zero-crossing functions influenced by a given event.

-$HD$: It tells which derivatives influenced by a given event.

Here's a quick summary and what each helper function is doing:

extractJacDepNormal: It Extracts the dependencies for normal (non-loop) expressions. It updates the Jacobian matrix $jac$ and a dictionary $dD$ for tracking dependencies of derivatives to discrete variables.

extractJacDepLoop: Similar to extractJacDepNormal, but specifically for loop expressions. It tracks dependencies across loop iterations.

extractZCJacDepNormal: It Extracts zero-crossing Jacobian dependencies for discrete variables ($dZ$), and it updates $zcjac$, $SZ$.

createDependencyToEventsDiscr: It maps discrete dependencies (dD, dZ) to specific events, it and constructs dependency matrices HZ and HD from the discrete variables only.

createDependencyToEventsCont: Similar to createDependencyToEventsDiscr, but for continuous dependencies (SD, sZ), and it updates the matrices HZ and HD from the continuous variables only.

unionDependency: Merges the two previous sets of dependencies (continuous and discrete) into the final matrices HZ and HD.

Helper packages

The 𝑝𝑜𝑠𝑡𝑤𝑎𝑙𝑘 function from the MacroTools.jl (Copyright (c) 2015: Mike Innes) package plugs parameters and helper functions directly into the equations, and traverses the right-hand side of differential equations and zero-crossing functions, facilitating the construction of the Jacobian matrix and identifying variable dependencies. It also transforms specific expressions like 𝑞[1] into 𝑞[1] [0] within events, and converts 𝑞[𝑖] to 𝑞𝑖, making the equations more tractable for differentiation and Jacobian construction. Additionally, the @𝑐𝑎𝑝𝑡𝑢𝑟𝑒 macro efficiently handles cases where differential equations are defined within a for loop.

The diff(basi, symarg) function from the SymEngine.jl (Copyright (c) 2015-2017 Isuru Fernando) package is applied to perform symbolic differentiation, where basi is an expression and symarg is the symbol with respect to which the derivative is taken. This returns the partial derivative of the expression, making it particularly useful for deriving system Jacobians.

@code_string macro from the CodeTracking.jl (Copyright (c) 2019 Tim Holy) is used to get the body expression of the function that holds the problem given by the user.

@RuntimeGeneratedFunction from the RuntimeGeneratedFunctions.jl package (Copyright (c) 2020 Chris Rackauckas) is used to avoid world-age issues with the generated functions.

Internals

Problem definition

QuantizedSystemSolver.NLODEContProblemType
NLODEContProblem{F,PRTYPE,T,D,Z,CS}

A struct that holds the continuous problem. It has the following fields:

  • prname: The name of the problem
  • prtype: The type of the problem
  • a: The size of the problem
  • c: The number of discrete events
  • b: The number of zero crossing functions
  • cacheSize: The size of the cache
  • initConditions: The initial conditions of the problem
  • discreteVars # to match the differentialEqation.jl interface that wants the parameter p to be part of the problem
  • eqs: The function that holds all the ODEs
  • jac: The Jacobian dependency
  • SD: The state derivative dependency
  • exactJac: The exact Jacobian function
  • closureFuncs::Vector{F} # function that holds closure function inside system defined by user
source
QuantizedSystemSolver.NLODEContProblemSpanType
NLODEContProblemSpan{F,PRTYPE,T,D,Z,CS}

A struct that holds the continuous problem with tspan. It has the following fields:

  • prname: The name of the problem
  • prtype: The type of the problem
  • a: The size of the problem
  • c: The number of discrete vars
  • b: The number of zero crossing functions
  • cacheSize: The size of the cache
  • initConditions: The initial conditions of the problem
  • discreteVars # to match the differentialEqation.jl interface that wants the parameter p to be part of the problem
  • eqs: The function that holds all the ODEs
  • jac: The Jacobian dependency
  • SD: The state derivative dependency
  • exactJac: The exact Jacobian function
  • tspan::Tuple{Float64, Float64}: This field variable did not exist in the original NLODEContProblem as this simulation time should part of the problem. However, to match the differentialEqation.jl interface, the tspan is added to the definition of the problem.
  • closureFuncs::Vector{F} # function that holds closure function inside system defined by user
source
QuantizedSystemSolver.NLODEDiscProblemType
NLODEDiscProblem{F,PRTYPE,T,D,Z,CS}

A struct that holds the Problem of a system of ODEs with a set of events. It has the following fields:

  • prname::Symbol
  • prtype::Val{PRTYPE}
  • a::Val{T}
  • c::Val{D}
  • b::Val{Z}
  • cacheSize::Val{CS}
  • initConditions::Vector{Float64}
  • discreteVars::Vector{Float64}
  • jac::Vector{Vector{Int}}#Jacobian dependency..I have a der and I want to know which vars affect it...opposite of SD
  • ZCjac::Vector{Vector{Int}} # to update other Qs before checking ZCfunction
  • eqs::Function#function that holds all ODEs
  • eventDependencies::Vector{EventDependencyStruct}
  • SD::Vector{Vector{Int}}# I have a var and I want the der that are affected by it
  • HZ::Vector{Vector{Int}}# an ev occured and I want the ZC that are affected by it
  • HD::Vector{Vector{Int}}# an ev occured and I want the der that are affected by it
  • SZ::Vector{Vector{Int}}# I have a var and I want the ZC that are affected by it
  • exactJac::Function #used only in the implicit integration: linear approximation
  • closureFuncs::Vector{F} # function that holds closure function inside system defined by user
source
QuantizedSystemSolver.NLODEDiscProblemSpanType
NLODEDiscProblemSpan{F,PRTYPE,T,D,Z,CS}

A struct that holds the Problem of a system of ODEs with a set of events with tspan. It has the following fields: -prname::Symbol -prtype::Val{PRTYPE} -a::Val{T} -c::Val{D} -b::Val{Z} -cacheSize::Val{CS} -initConditions::Vector{Float64} -discreteVars::Vector{Float64} -jac::Vector{Vector{Int}}#Jacobian dependency..I have a der and I want to know which vars affect it...opposite of SD -ZCjac::Vector{Vector{Int}} # to update other Qs before checking ZCfunction -eqs::Function#function that holds all ODEs -eventDependencies::Vector{EventDependencyStruct} -SD::Vector{Vector{Int}}# I have a var and I want the der that are affected by it -HZ::Vector{Vector{Int}}# an ev occured and I want the ZC that are affected by it -HD::Vector{Vector{Int}}# an ev occured and I want the der that are affected by it -SZ::Vector{Vector{Int}}# I have a var and I want the ZC that are affected by it -exactJac::Function#used only in the implicit integration: linear approximation -tspan::Tuple{Float64, Float64}# This field variable did not exist in the original NLODEDiscProblem as this simulation time should part of the problem. However, to match the differentialEqation.jl interface, the tspan is added to the definition of the problem. -closureFuncs::Vector{F} # function that holds closure function inside system defined by user

source

Problem construction

The examples of the continuous problem

All the examples that explain the problem construction functions use the following problem. The examples are reproducible as they are shown. To see the problem construction process in one step, add print() statements inside the functions of the package while solving this problem as shown in the tutorial section.

du[1] = u[2]-2.0*u[1]*u[2]
+end

This new problem type takes care of one differential equation. There is no need for the Jacobian nor for the dependencies. This needs an extension of the custom_Solve method that just removes the references to the jac and the SD. An extension of the integrate method is also needed since the implementation is a lot simpler than what is currently implemented.

Further reading about the functions creating the problem

NLODEDiscProblem{F,PRTYPE,T,D,Z,CS}: This is the struct that holds all the necessary data for a nonlinear ordinary differential equation (ODE) problem with discrete events. The structure includes various fields such as initial conditions, discrete variables, Jacobians, event dependencies, and other data related to how the problem is formulated. This structure serves as the core data holder for the problem and will be used in the solver. It is a parametric abstract type that has the following parameters:

PRTYPE: The type of the problem (to distinguish between various types, and allow future extension of the solver to handle new types).

T: The number of continuous variables (state variables).

Z: The number of zero-crossing functions, which are used to detect events.

Y: The actual number of events.

CS: Cache size, which is used to store intermediate operations.

The use of abstract types in this context allows for flexibility and extensibility in the solver. By defining these abstract types, the code can be easily adapted to handle different types of problems, algorithms, and solutions without needing to modify the core solver logic. This design choice enhances the maintainability and scalability of the solver, making it easier to add new features or support additional problem types in the future.

NLodeProblemFunc: After an initial preparation performed by the The NLodeProblem function, The function NLodeProblemFunc takes the resulting expressions to continue constructing an instance of the NLODEDiscProblem structure. It works in several key stages:

Initialization: The function begins by initializing vectors and dictionaries that will hold equations (equs), Jacobian dependencies (jac), zero-crossing functions (ZCjac), and event dependencies. These serve to store the different types of equations and their relationships.

Processing ODEs: It loops through each of the ODE expressions provided by the user. Depending on the type of expression (discrete variables, differential equations, or loop constructs), it processes the right-hand side (RHS) of the equation. For differential equations, it extracts dependencies to build the Jacobian and transform the equations into a more appropriate form for further use. Special cases are handled, such as if the RHS is a number or a symbol.

Handling Events: The function also processes event-related constructs (if conditions) that correspond to different points where the system might undergo discrete changes. It process the RHS of the event equations, transforms them into a suitable form, and builds the necessary dependency structures. Specifically, it constructs how discrete and continuous variables influence one another through the events.

Constructing the Function Code: After processing all ODEs and events, the function dynamically generates a Julia function code needed to store the system of ODEs and events. This code is built into a function that handles different cases (i.e., which equation to evaluate based on an index of a state change or an event).

Building Dependencies: Several helper functions that build the dependencies between variables, events. They build dependency vectors that track how discrete and continous variables influence the system. This is used to know what variables to update and determine when specific events should be checked. By tracking the relationships between variables and events, the solver can determine the appropriate actions to take at each time step. The dependencies are stored in the following vectors:

-$jac$: It determines which variables affect a derivative.

-$ZCjac$: It determines which variables affect a zero-crossing function.

-$SD$: It determines which derivatives that are affected by a given variable.

-$SZ$: It determines which zero-crossing functions that are affected by a given variable.

-$HZ$: It tells which Zero-crossing functions influenced by a given event.

-$HD$: It tells which derivatives influenced by a given event.

Here's a quick summary and what each helper function is doing:

extractJacDepNormal: It Extracts the dependencies for normal (non-loop) expressions. It updates the Jacobian matrix $jac$ and a dictionary $dD$ for tracking dependencies of derivatives to discrete variables.

extractJacDepLoop: Similar to extractJacDepNormal, but specifically for loop expressions. It tracks dependencies across loop iterations.

extractZCJacDepNormal: It Extracts zero-crossing Jacobian dependencies for discrete variables ($dZ$), and it updates $zcjac$, $SZ$.

createDependencyToEventsDiscr: It maps discrete dependencies (dD, dZ) to specific events, it and constructs dependency matrices HZ and HD from the discrete variables only.

createDependencyToEventsCont: Similar to createDependencyToEventsDiscr, but for continuous dependencies (SD, sZ), and it updates the matrices HZ and HD from the continuous variables only.

unionDependency: Merges the two previous sets of dependencies (continuous and discrete) into the final matrices HZ and HD.

Helper packages

The 𝑝𝑜𝑠𝑡𝑤𝑎𝑙𝑘 function from the MacroTools.jl (Copyright (c) 2015: Mike Innes) package plugs parameters and helper functions directly into the equations, and traverses the right-hand side of differential equations and zero-crossing functions, facilitating the construction of the Jacobian matrix and identifying variable dependencies. It also transforms specific expressions like 𝑞[1] into 𝑞[1] [0] within events, and converts 𝑞[𝑖] to 𝑞𝑖, making the equations more tractable for differentiation and Jacobian construction. Additionally, the @𝑐𝑎𝑝𝑡𝑢𝑟𝑒 macro efficiently handles cases where differential equations are defined within a for loop.

The diff(basi, symarg) function from the SymEngine.jl (Copyright (c) 2015-2017 Isuru Fernando) package is applied to perform symbolic differentiation, where basi is an expression and symarg is the symbol with respect to which the derivative is taken. This returns the partial derivative of the expression, making it particularly useful for deriving system Jacobians.

@code_string macro from the CodeTracking.jl (Copyright (c) 2019 Tim Holy) is used to get the body expression of the function that holds the problem given by the user.

@RuntimeGeneratedFunction from the RuntimeGeneratedFunctions.jl package (Copyright (c) 2020 Chris Rackauckas) is used to avoid world-age issues with the generated functions.

Internals

Problem definition

QuantizedSystemSolver.NLODEContProblemType
NLODEContProblem{F,PRTYPE,T,D,Z,CS}

A struct that holds the continuous problem. It has the following fields:

  • prname: The name of the problem
  • prtype: The type of the problem
  • a: The size of the problem
  • c: The number of discrete events
  • b: The number of zero crossing functions
  • cacheSize: The size of the cache
  • initConditions: The initial conditions of the problem
  • discreteVars # to match the differentialEqation.jl interface that wants the parameter p to be part of the problem
  • eqs: The function that holds all the ODEs
  • jac: The Jacobian dependency
  • SD: The state derivative dependency
  • exactJac: The exact Jacobian function
  • closureFuncs::Vector{F} # function that holds closure function inside system defined by user
source
QuantizedSystemSolver.NLODEContProblemSpanType
NLODEContProblemSpan{F,PRTYPE,T,D,Z,CS}

A struct that holds the continuous problem with tspan. It has the following fields:

  • prname: The name of the problem
  • prtype: The type of the problem
  • a: The size of the problem
  • c: The number of discrete vars
  • b: The number of zero crossing functions
  • cacheSize: The size of the cache
  • initConditions: The initial conditions of the problem
  • discreteVars # to match the differentialEqation.jl interface that wants the parameter p to be part of the problem
  • eqs: The function that holds all the ODEs
  • jac: The Jacobian dependency
  • SD: The state derivative dependency
  • exactJac: The exact Jacobian function
  • tspan::Tuple{Float64, Float64}: This field variable did not exist in the original NLODEContProblem as this simulation time should part of the problem. However, to match the differentialEqation.jl interface, the tspan is added to the definition of the problem.
  • closureFuncs::Vector{F} # function that holds closure function inside system defined by user
source
QuantizedSystemSolver.NLODEDiscProblemType
NLODEDiscProblem{F,PRTYPE,T,D,Z,CS}

A struct that holds the Problem of a system of ODEs with a set of events. It has the following fields:

  • prname::Symbol
  • prtype::Val{PRTYPE}
  • a::Val{T}
  • c::Val{D}
  • b::Val{Z}
  • cacheSize::Val{CS}
  • initConditions::Vector{Float64}
  • discreteVars::Vector{Float64}
  • jac::Vector{Vector{Int}}#Jacobian dependency..I have a der and I want to know which vars affect it...opposite of SD
  • ZCjac::Vector{Vector{Int}} # to update other Qs before checking ZCfunction
  • eqs::Function#function that holds all ODEs
  • eventDependencies::Vector{EventDependencyStruct}
  • SD::Vector{Vector{Int}}# I have a var and I want the der that are affected by it
  • HZ::Vector{Vector{Int}}# an ev occured and I want the ZC that are affected by it
  • HD::Vector{Vector{Int}}# an ev occured and I want the der that are affected by it
  • SZ::Vector{Vector{Int}}# I have a var and I want the ZC that are affected by it
  • exactJac::Function #used only in the implicit integration: linear approximation
  • closureFuncs::Vector{F} # function that holds closure function inside system defined by user
source
QuantizedSystemSolver.NLODEDiscProblemSpanType
NLODEDiscProblemSpan{F,PRTYPE,T,D,Z,CS}

A struct that holds the Problem of a system of ODEs with a set of events with tspan. It has the following fields: -prname::Symbol -prtype::Val{PRTYPE} -a::Val{T} -c::Val{D} -b::Val{Z} -cacheSize::Val{CS} -initConditions::Vector{Float64} -discreteVars::Vector{Float64} -jac::Vector{Vector{Int}}#Jacobian dependency..I have a der and I want to know which vars affect it...opposite of SD -ZCjac::Vector{Vector{Int}} # to update other Qs before checking ZCfunction -eqs::Function#function that holds all ODEs -eventDependencies::Vector{EventDependencyStruct} -SD::Vector{Vector{Int}}# I have a var and I want the der that are affected by it -HZ::Vector{Vector{Int}}# an ev occured and I want the ZC that are affected by it -HD::Vector{Vector{Int}}# an ev occured and I want the der that are affected by it -SZ::Vector{Vector{Int}}# I have a var and I want the ZC that are affected by it -exactJac::Function#used only in the implicit integration: linear approximation -tspan::Tuple{Float64, Float64}# This field variable did not exist in the original NLODEDiscProblem as this simulation time should part of the problem. However, to match the differentialEqation.jl interface, the tspan is added to the definition of the problem. -closureFuncs::Vector{F} # function that holds closure function inside system defined by user

source

Problem construction

The examples of the continuous problem

All the examples that explain the problem construction functions use the following problem. The examples are reproducible as they are shown. To see the problem construction process in one step, add print() statements inside the functions of the package while solving this problem as shown in the tutorial section.

du[1] = u[2]-2.0*u[1]*u[2]
 for k in 2:9  
 du[k]=u[k]*u[k-1];
 end 
-du[10]=u[1]-u[10]
QuantizedSystemSolver.NLodeProblemFuncMethod
NLodeProblemFunc(odeExprs::Expr,::Val{T},::Val{D},::Val{0},initConditions::Vector{Float64},du::Symbol,tspan::Tuple{Float64, Float64},discrVars::Union{Vector{EM}, Tuple{Vararg{EM}}},prbName::Symbol) where {T,D,EM}

This function continues building a continuous problem. it receives an expression and useful info from the main interface. it calls the transform function from the taylorEquationConstruction.jl file to change the AST of all operations to personlized ones and update the needed cache size. It also construct via helper functions the Exact jacobian function, the jacobian dependecy and the state-derivative dependency (opposite of jacobian) as vectors. Finally, it groups all differential equations in one function, and constructs a continous problem from the qssProblemDefinition.jl file.

Arguments

  • odeExprs::Expr: The expression of the whole user code in the function defining the problem with names modified and parameters plugged in.
  • Val{T}: the dimensions of the system of differential equations.
  • Val{0}: No zero-crossing functions. pure continous problem.
  • Val{0}: No events functions. pure continous problem.
  • initConditions::Vector{Float64}: No zero-crossing functions. pure continous problem.
  • du::Symbol: to distinguish the start of a differential equations.
  • symDict::Dict{Symbol,Expr}: maps a reference expression to a symbol (qi->q[i]).
  • tspan::Tuple{Float64, Float64}: stores the initial time and final time of the simulation.
  • prbName::Symbol: The problem name as chosen by the user to be carried to the solution for displaying purposes.
source
QuantizedSystemSolver.NLodeProblemFuncMethod
NLodeProblemFunc(odeExprs::Expr,::Val{T},::Val{D},::Val{Z},initCond::Vector{Float64},du::Symbol,tspan::Tuple{Float64, Float64},discrVars::Union{Vector{EM}, Tuple{Vararg{EM}}},prbName::Symbol) where {T,D,Z,EM} 
+du[10]=u[1]-u[10]
QuantizedSystemSolver.NLodeProblemFuncMethod
NLodeProblemFunc(odeExprs::Expr,::Val{T},::Val{D},::Val{0},initConditions::Vector{Float64},du::Symbol,tspan::Tuple{Float64, Float64},discrVars::Union{Vector{EM}, Tuple{Vararg{EM}}},prbName::Symbol) where {T,D,EM}

This function continues building a continuous problem. it receives an expression and useful info from the main interface. it calls the transform function from the taylorEquationConstruction.jl file to change the AST of all operations to personlized ones and update the needed cache size. It also construct via helper functions the Exact jacobian function, the jacobian dependecy and the state-derivative dependency (opposite of jacobian) as vectors. Finally, it groups all differential equations in one function, and constructs a continous problem from the qssProblemDefinition.jl file.

Arguments

  • odeExprs::Expr: The expression of the whole user code in the function defining the problem with names modified and parameters plugged in.
  • Val{T}: the dimensions of the system of differential equations.
  • Val{0}: No zero-crossing functions. pure continous problem.
  • Val{0}: No events functions. pure continous problem.
  • initConditions::Vector{Float64}: No zero-crossing functions. pure continous problem.
  • du::Symbol: to distinguish the start of a differential equations.
  • symDict::Dict{Symbol,Expr}: maps a reference expression to a symbol (qi->q[i]).
  • tspan::Tuple{Float64, Float64}: stores the initial time and final time of the simulation.
  • prbName::Symbol: The problem name as chosen by the user to be carried to the solution for displaying purposes.
source
QuantizedSystemSolver.NLodeProblemFuncMethod
NLodeProblemFunc(odeExprs::Expr,::Val{T},::Val{D},::Val{Z},initCond::Vector{Float64},du::Symbol,tspan::Tuple{Float64, Float64},discrVars::Union{Vector{EM}, Tuple{Vararg{EM}}},prbName::Symbol) where {T,D,Z,EM} 
 
     continues building a discrete problem. 
-It receives an expression and useful info from the main interface. It calls the transform function from the taylorEquationConstruction.jl file to change the AST of all operations to personlized ones and update the needed cache size. It also construct via helper functions the Exact jacobian function, the jacobian dependecy (jac) and the state-derivative dependency (SD:opposite of jacobian), the state to zero-crossing dependency (SZ) and events to derivative and zero-crossing (HD and HZ) as vectors. Finally, it groups all differential equations and events in one function, and constructs a discrete problem from the qssProblemDefinition.jl file.
source

Problem construction helpers

QuantizedSystemSolver.prepareInfoMethod
prepareInfo(odeExprs::Expr,stateVarName::Symbol,discrParamName::Symbol)

Prepares information about the ODE problem by replacing symbols and parameters, and extracting information about size, symbols, and initial conditions.

Arguments

  • odeExprs::Expr: The expressions defining the ODE.
  • stateVarName::Symbol: The symbol representing the continuous variables.

Returns

  • A probInfo struct containing the number of zero-crossings (numZC) and a dictionary of symbols and expressions (symDict).
source
QuantizedSystemSolver.probHelperType
probHelper

In old interface, this holds information about the ODE problem. It helps the arrangeProb function to return the number of zero-crossings, a dictionary of symbols and expressions, and other information.

Fields

  • problemSize::Int: The size of the problem.
  • discreteSize::Int: The size of the discrete variables.
  • numZC::Int: The number of zero-crossings.
  • savedInitCond::Dict{Union{Int,Expr},Float64}: A dictionary of initial conditions.
  • initConditions::Vector{Float64}: The initial conditions.
  • du::Symbol: The symbol representing the derivative of the continuous variables.
  • symDict::Dict{Symbol,Expr}: A dictionary of symbols and expressions.
source
QuantizedSystemSolver.arrangeProbMethod
arrangeProb(x::Expr)

in old interface, this prepares information about the ODE problem by replacing symbols and parameters, and extracting information about size, symbols, and initial conditions.

Returns

  • A probHelper struct containing the number of zero-crossings (numZC), a dictionary of symbols and expressions (symDict), .
source
QuantizedSystemSolver.changeExprToFirstValueMethod
changeExprToFirstValue(ex::Expr)

changes an expression in the form u[1] to an expression in the form u[1][0] inside exact jacobian expressions and inside events, because linear coefficients (a_{ii}) do not have derivatives, and updates in events affect the value of a variable directly and there is no need to update its higher derivatives. It is called by the restoreRef function for jacobian expressions, and called by the handleEvents function for events.

Example:

using QuantizedSystemSolver 
+It receives an expression and useful info from the main interface. It calls the transform function from the taylorEquationConstruction.jl file to change the AST of all operations to personlized ones and update the needed cache size. It also construct via helper functions the Exact jacobian function, the jacobian dependecy (jac) and the state-derivative dependency (SD:opposite of jacobian), the state to zero-crossing dependency (SZ) and events to derivative and zero-crossing (HD and HZ) as vectors. Finally, it groups all differential equations and events in one function, and constructs a discrete problem from the qssProblemDefinition.jl file.
source

Problem construction helpers

QuantizedSystemSolver.prepareInfoMethod
prepareInfo(odeExprs::Expr,stateVarName::Symbol,discrParamName::Symbol)

Prepares information about the ODE problem by replacing symbols and parameters, and extracting information about size, symbols, and initial conditions.

Arguments

  • odeExprs::Expr: The expressions defining the ODE.
  • stateVarName::Symbol: The symbol representing the continuous variables.

Returns

  • A probInfo struct containing the number of zero-crossings (numZC) and a dictionary of symbols and expressions (symDict).
source
QuantizedSystemSolver.probHelperType
probHelper

In old interface, this holds information about the ODE problem. It helps the arrangeProb function to return the number of zero-crossings, a dictionary of symbols and expressions, and other information.

Fields

  • problemSize::Int: The size of the problem.
  • discreteSize::Int: The size of the discrete variables.
  • numZC::Int: The number of zero-crossings.
  • savedInitCond::Dict{Union{Int,Expr},Float64}: A dictionary of initial conditions.
  • initConditions::Vector{Float64}: The initial conditions.
  • du::Symbol: The symbol representing the derivative of the continuous variables.
  • symDict::Dict{Symbol,Expr}: A dictionary of symbols and expressions.
source
QuantizedSystemSolver.arrangeProbMethod
arrangeProb(x::Expr)

in old interface, this prepares information about the ODE problem by replacing symbols and parameters, and extracting information about size, symbols, and initial conditions.

Returns

  • A probHelper struct containing the number of zero-crossings (numZC), a dictionary of symbols and expressions (symDict), .
source
QuantizedSystemSolver.changeExprToFirstValueMethod
changeExprToFirstValue(ex::Expr)

changes an expression in the form u[1] to an expression in the form u[1][0] inside exact jacobian expressions and inside events, because linear coefficients (a_{ii}) do not have derivatives, and updates in events affect the value of a variable directly and there is no need to update its higher derivatives. It is called by the restoreRef function for jacobian expressions, and called by the handleEvents function for events.

Example:

using QuantizedSystemSolver 
 ex=:(q[i - 1]) 
 newEx=QuantizedSystemSolver.changeExprToFirstValue(ex)
 
 # output
 
-:((q[i - 1])[0])
source
QuantizedSystemSolver.restoreRefMethod
restoreRef(coefExpr,symDict)

This function is the opposite of symbolFromRef. After using the symbols in symbolic differentiation, it gets back expressions like p[i+Number] and q[i+Number][0] from symbols diplusNumber and qiplusNumber. Adding a zero to q variables is beacause q is a taylor variable while p is a vector.

arguments:

  • coefExpr::Expr: the expression to be changed
  • symDict::Dict{Symbol,Expr}: the dictionary to store the translation of symbols of continous and discrete variables (q[i] <-> qi)

Example:

using QuantizedSystemSolver
+(:(i - 1), :qiminus1)
source
QuantizedSystemSolver.restoreRefMethod
restoreRef(coefExpr,symDict)

This function is the opposite of symbolFromRef. After using the symbols in symbolic differentiation, it gets back expressions like p[i+Number] and q[i+Number][0] from symbols diplusNumber and qiplusNumber. Adding a zero to q variables is beacause q is a taylor variable while p is a vector.

arguments:

  • coefExpr::Expr: the expression to be changed
  • symDict::Dict{Symbol,Expr}: the dictionary to store the translation of symbols of continous and discrete variables (q[i] <-> qi)

Example:

using QuantizedSystemSolver
 
 symDict= Dict{Symbol, Expr}(:qi => :(q[i]), :q10 => :(q[10]), :q2 => :(q[2]), :qiminus1 => :(q[i - 1]), :q1 => :(q[1]))
 coefExpr=:(1.5qiminus1) 
@@ -32,7 +32,7 @@
 
 # output
 
-:(1.5 * (q[i - 1])[0]) 
source
QuantizedSystemSolver.changeVarNames_paramsMethod
changeVarNames_params(ex::Expr,stateVarName::Symbol,discrParamName::Symbol,muteVar::Symbol,param::Dict{Symbol,Union{Float64,Int64,Expr,Symbol}})

As the name suggests, this changes the continuous variables names to :q and the discrete variable name to :p and any mute variables to :i. It also plugs the parameters values from a parameter dictionary into the differential equations. The function changeVarNames_params has three methods. One for RHS of equations, one for if-statements when RHS is an expression, and one for if-statements when RHS is a symbol. This is method one. It has an additional symDict::Dict{Symbol,Expr} to collect the translation of symbols of continous and discrete variables (q[i] <-> qi).

arguments:

  • ex::Expr: the expression to be changed
  • stateVarName::Symbol: the name of the state variable
  • muteVar::Symbol: the name of the mute variable
  • param::Dict{Symbol,Union{Float64,Int64,Expr,Symbol}}: the dictionary of parameters

Example:

using QuantizedSystemSolver
+:(1.5 * (q[i - 1])[0]) 
source
QuantizedSystemSolver.changeVarNames_paramsMethod
changeVarNames_params(ex::Expr,stateVarName::Symbol,discrParamName::Symbol,muteVar::Symbol,param::Dict{Symbol,Union{Float64,Int64,Expr,Symbol}})

As the name suggests, this changes the continuous variables names to :q and the discrete variable name to :p and any mute variables to :i. It also plugs the parameters values from a parameter dictionary into the differential equations. The function changeVarNames_params has three methods. One for RHS of equations, one for if-statements when RHS is an expression, and one for if-statements when RHS is a symbol. This is method one. It has an additional symDict::Dict{Symbol,Expr} to collect the translation of symbols of continous and discrete variables (q[i] <-> qi).

arguments:

  • ex::Expr: the expression to be changed
  • stateVarName::Symbol: the name of the state variable
  • muteVar::Symbol: the name of the mute variable
  • param::Dict{Symbol,Union{Float64,Int64,Expr,Symbol}}: the dictionary of parameters

Example:

using QuantizedSystemSolver
 
 (ex, stateVarName, discrParamName,muteVar, param) = (:(du[k] = u[k] * u[k - 1] * coef2), :u,:p, :k, Dict{Symbol, Union{Float64, Int64,Expr,Symbol}}(:coef1 => 2.0, :coef2 => 1.5))
 
@@ -40,7 +40,7 @@
 (newEx, stateVarName, muteVar, param)
 # output
 
-(:(du[i] = q[i] * q[i - 1] * 1.5), :u, :k, Dict{Symbol, Union{Float64, Int64, Expr, Symbol}}(:coef1 => 2.0, :coef2 => 1.5))
source
QuantizedSystemSolver.changeVarNames_paramsMethod
changeVarNames_params(element::Symbol,stateVarName::Symbol,discrParamName::Symbol,muteVar::Symbol,param::Dict{Symbol,Union{Float64,Int64,Expr,Symbol}})

This is method three of the function changeVarNames_params. It is for if-statements when RHS is a symbol. Again, it changes the symbol to :q if it is a continuous variable, to :p if it is a discrete variable, to :i if it is a mute variable, and to its corresponding value if it is a parameter. It is called by the prepareInfo function.

source
QuantizedSystemSolver.handleEventsMethod

handleEvents(argI::Expr,eventequs::Vector{Expr},length_zcequs::Int64,evsArr::Vector{EventDependencyStruct})

Handles events in the quantized system solver.

Arguments

  • argI::Expr: An expression representing the 'if-statement'.
  • eventequs::Vector{Expr}: A vector of expressions representing the event equations.
  • length_zcequs::Int64: current number of treated zero-crossing equations. Usezd as index to store the events in order.
  • evsArr: An array containing EventDependencyStruct objects.
source
QuantizedSystemSolver.transformFSimplecaseMethod
transformFSimplecase(ex::Union{Float64,Int64,Expr,Symbol})

transforms expressions of the right hand side of differential equations and zero-crossing functions to personalized ones that use caching to a form that can be used in the createT function. The right hand side of the equations should be a number or a q[i] term.

Example:

using QuantizedSystemSolver
+(:(du[i] = q[i] * q[i - 1] * 1.5), :u, :k, Dict{Symbol, Union{Float64, Int64, Expr, Symbol}}(:coef1 => 2.0, :coef2 => 1.5))
source
QuantizedSystemSolver.changeVarNames_paramsMethod
changeVarNames_params(element::Symbol,stateVarName::Symbol,discrParamName::Symbol,muteVar::Symbol,param::Dict{Symbol,Union{Float64,Int64,Expr,Symbol}})

This is method three of the function changeVarNames_params. It is for if-statements when RHS is a symbol. Again, it changes the symbol to :q if it is a continuous variable, to :p if it is a discrete variable, to :i if it is a mute variable, and to its corresponding value if it is a parameter. It is called by the prepareInfo function.

source
QuantizedSystemSolver.handleEventsMethod

handleEvents(argI::Expr,eventequs::Vector{Expr},length_zcequs::Int64,evsArr::Vector{EventDependencyStruct})

Handles events in the quantized system solver.

Arguments

  • argI::Expr: An expression representing the 'if-statement'.
  • eventequs::Vector{Expr}: A vector of expressions representing the event equations.
  • length_zcequs::Int64: current number of treated zero-crossing equations. Usezd as index to store the events in order.
  • evsArr: An array containing EventDependencyStruct objects.
source
QuantizedSystemSolver.transformFSimplecaseMethod
transformFSimplecase(ex::Union{Float64,Int64,Expr,Symbol})

transforms expressions of the right hand side of differential equations and zero-crossing functions to personalized ones that use caching to a form that can be used in the createT function. The right hand side of the equations should be a number or a q[i] term.

Example:

using QuantizedSystemSolver
 ex=:(q[2])
 newEx=QuantizedSystemSolver.transformFSimplecase(ex);
 
@@ -48,7 +48,7 @@
 # output
 
 :(createT(q[2], cache[1])) 
-
source
QuantizedSystemSolver.transformFMethod
transformF(ex::Expr)

transforms expressions of the right hand side of differential equations and zero-crossing functions to personalized ones that use caching to a form that can be used in functions like addT, subT, mulT, muladdT. The right hand side of the equations can be any form of expression.

Example:

using QuantizedSystemSolver
+
source
QuantizedSystemSolver.transformFMethod
transformF(ex::Expr)

transforms expressions of the right hand side of differential equations and zero-crossing functions to personalized ones that use caching to a form that can be used in functions like addT, subT, mulT, muladdT. The right hand side of the equations can be any form of expression.

Example:

using QuantizedSystemSolver
 ex=:(q[2] - 2.0*q[1]*q[2],1)
 newEx=QuantizedSystemSolver.transformF(ex);
 
@@ -56,7 +56,7 @@
 # output
 
 :((subT(q[2], mulTT(2.0, q[1], q[2], cache[2], cache[3]), cache[1]), 3))
-
source
QuantizedSystemSolver.extractJacDepNormalMethod
extractJacDepNormal(varNum::Int,rhs::Union{Int,Expr},jac :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}}, exactJacExpr :: Dict{Expr,Union{Float64,Int,Symbol,Expr}},symDict::Dict{Symbol,Expr})

Extract the jacobian dependency as well as the exacte symbolic jacobian expression, in the form of dictionaries, from the simple differential equations.

The function sarts by looking for the 'i' in q[i] in the RHS and storing this 'i' in a jacSet for the varNum. Then, it changes q[i] to qi for symbolic differentiation. After finding $\frac{\partial f_i}{\partial q_i}$ as the exact jacobian entry, it changes back qi to q[i]. Also, any mute variable from the differential equations is changed to 'i' and the symbol for the variable is changed to 'q'.

example:

using QuantizedSystemSolver
+
source
QuantizedSystemSolver.extractJacDepNormalMethod
extractJacDepNormal(varNum::Int,rhs::Union{Int,Expr},jac :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}}, exactJacExpr :: Dict{Expr,Union{Float64,Int,Symbol,Expr}},symDict::Dict{Symbol,Expr})

Extract the jacobian dependency as well as the exacte symbolic jacobian expression, in the form of dictionaries, from the simple differential equations.

The function sarts by looking for the 'i' in q[i] in the RHS and storing this 'i' in a jacSet for the varNum. Then, it changes q[i] to qi for symbolic differentiation. After finding $\frac{\partial f_i}{\partial q_i}$ as the exact jacobian entry, it changes back qi to q[i]. Also, any mute variable from the differential equations is changed to 'i' and the symbol for the variable is changed to 'q'.

example:

using QuantizedSystemSolver
 jac = Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}}()
 exacteJacExpr = Dict{Expr,Union{Float64,Int,Symbol,Expr}}()
 symDict=Dict(:q2 => :(q[2]), :q1 => :(q[1]))
@@ -66,7 +66,7 @@
 
 # output
 
-(Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(1 => Set([2, 1])), Dict{Expr, Union{Float64, Int64, Expr, Symbol}}(:((1, 1)) => :(-2.0 * (q[2])[0]), :((1, 2)) => :(1 - 2.0 * (q[1])[0])))
source
QuantizedSystemSolver.extractJacDepLoopMethod
extractJacDepLoop(b::Int,niter::Int,rhs::Union{Int,Expr},jac :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}} ,exactJacExpr :: Dict{Expr,Union{Float64,Int,Symbol,Expr}},symDict::Dict{Symbol,Expr})

This function is similar to the extractJacDepNormal function by using the tuple (b,niter) instead of the integer varNum. It extracts the jacobian dependency as well as the exacte symbolic jacobian expression, in the form of dictionaries, from the differential equations that are written in a loop.

The keys of the exactJacExpr dictionary are more complex than in the case of simple differential equations. This complexity accounts for the fact the 'for' loop contains many simple differential equations. This approach makes parsing of the problem agnostic of the problem size. This function sarts by looking for the 'i' in q[i] in the RHS and storing this 'i' in a jacSet. Then, it changes q[i] to qi for symbolic differentiation. After finding $\frac{\partial rhs}{\partial qi}$ as the exact jacobian entry, it changes back qi to q[i].

Example:

using QuantizedSystemSolver
+(Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(1 => Set([2, 1])), Dict{Expr, Union{Float64, Int64, Expr, Symbol}}(:((1, 1)) => :(-2.0 * (q[2])[0]), :((1, 2)) => :(1 - 2.0 * (q[1])[0])))
source
QuantizedSystemSolver.extractJacDepLoopMethod
extractJacDepLoop(b::Int,niter::Int,rhs::Union{Int,Expr},jac :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}} ,exactJacExpr :: Dict{Expr,Union{Float64,Int,Symbol,Expr}},symDict::Dict{Symbol,Expr})

This function is similar to the extractJacDepNormal function by using the tuple (b,niter) instead of the integer varNum. It extracts the jacobian dependency as well as the exacte symbolic jacobian expression, in the form of dictionaries, from the differential equations that are written in a loop.

The keys of the exactJacExpr dictionary are more complex than in the case of simple differential equations. This complexity accounts for the fact the 'for' loop contains many simple differential equations. This approach makes parsing of the problem agnostic of the problem size. This function sarts by looking for the 'i' in q[i] in the RHS and storing this 'i' in a jacSet. Then, it changes q[i] to qi for symbolic differentiation. After finding $\frac{\partial rhs}{\partial qi}$ as the exact jacobian entry, it changes back qi to q[i].

Example:

using QuantizedSystemSolver
 jac = Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}}()
 exacteJacExpr = Dict{Expr,Union{Float64,Int,Symbol,Expr}}()
 b,niter=2,9;
@@ -77,7 +77,7 @@
 
 # output
 
-(Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(:((2, 9)) => Set([:(i - 1), :i])), Dict{Expr, Union{Float64, Int64, Expr, Symbol}}(:(((2, 9), i - 1)) => :((q[i])[0]), :(((2, 9), i)) => :((q[i - 1])[0])))
source
QuantizedSystemSolver.createJacVectMethod
createJacVect(jac:: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}},::Val{T}) where {T}

constructs the jacobian dependency as a vector from the existing dictionary jac resulted from extractJacDepNormal and extractJacDepLoop functions.

This function just collects the data from the value of the dictionary if the key of the dictionary is an integer. (a dictionary contains(key=>value),...). In the case it is an expression :(b,niter), the function uses a 'for' loop to replace each 'b' by its corresponding integer. This approach depends on the size of the problem, but it runs one time.

Example:

using QuantizedSystemSolver
+(Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(:((2, 9)) => Set([:(i - 1), :i])), Dict{Expr, Union{Float64, Int64, Expr, Symbol}}(:(((2, 9), i - 1)) => :((q[i])[0]), :(((2, 9), i)) => :((q[i - 1])[0])))
source
QuantizedSystemSolver.createJacVectMethod
createJacVect(jac:: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}},::Val{T}) where {T}

constructs the jacobian dependency as a vector from the existing dictionary jac resulted from extractJacDepNormal and extractJacDepLoop functions.

This function just collects the data from the value of the dictionary if the key of the dictionary is an integer. (a dictionary contains(key=>value),...). In the case it is an expression :(b,niter), the function uses a 'for' loop to replace each 'b' by its corresponding integer. This approach depends on the size of the problem, but it runs one time.

Example:

using QuantizedSystemSolver
 jac=Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(1 => Set([2, 1]),:((2, 9)) => Set([:(i - 1), :i]),10 => Set([1, 10]))
 jacVect=QuantizedSystemSolver.createJacVect(jac,Val(10) )
 string(jacVect)
@@ -85,7 +85,7 @@
 # output
 
 "[[2, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [10, 1]]"
-
source
QuantizedSystemSolver.createSDVectMethod
createSDVect(jac:: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}},::Val{T}) where {T}

constructs the State to derivative dependency (opposite of jacobian dependency) as a vector from the existing dictionary jac resulted from the extractJacDepNormal and the extractJacDepLoop functions. It is the opposite in the sense that here we collect the keys into some vectors whereas in the jacobian dependency we collect the values of the dictionary in some vectors.

If the key of the dictionary is an integer, then for all elements 'k' in the value of the dictionary (a set), the key is pushed into a new vector indexed at 'k'. In the case the key is an expression :(b,niter), the function uses a 'for' loop to replace each 'b' by its corresponding integer. This approach depends on the size of the problem, but it runs one time.

Example:

using QuantizedSystemSolver
+
source
QuantizedSystemSolver.createSDVectMethod
createSDVect(jac:: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}},::Val{T}) where {T}

constructs the State to derivative dependency (opposite of jacobian dependency) as a vector from the existing dictionary jac resulted from the extractJacDepNormal and the extractJacDepLoop functions. It is the opposite in the sense that here we collect the keys into some vectors whereas in the jacobian dependency we collect the values of the dictionary in some vectors.

If the key of the dictionary is an integer, then for all elements 'k' in the value of the dictionary (a set), the key is pushed into a new vector indexed at 'k'. In the case the key is an expression :(b,niter), the function uses a 'for' loop to replace each 'b' by its corresponding integer. This approach depends on the size of the problem, but it runs one time.

Example:

using QuantizedSystemSolver
 jac=Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(1 => Set([2, 1]),:((2, 9)) => Set([:(i - 1), :i]),10 => Set([1, 10]));
 SD=QuantizedSystemSolver.createSDVect(jac,Val(10) );
 string(SD)
@@ -93,7 +93,7 @@
 # output
 
 "[[10, 2, 1], [2, 3, 1], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9], [10]]"
-
source
QuantizedSystemSolver.createExactJacFunMethod
createExactJacFun(otherCode::Expr,Exactjac:: Dict{Expr,Union{Float64,Int,Symbol,Expr}},funName::Symbol,f::F) where{F}

constructs the exact jacobian entries as a function from the existing dictionary Exactjac resulted from extractJacDepNormal and extractJacDepLoop functions.

From the input dictionary exactJac, we see that the key is always a expression that hold a tuple of size 2: the first element is going to be the index 'i' and the second element if the index 'j'. The value corresponding to this key, which is the exact jacobian entry, is put in a cache. i.e the function maps the keys of the dictionary to their values using an 'if-statement.. This approach does not depend on the size of the problem. # Example:

using QuantizedSystemSolver
+
source
QuantizedSystemSolver.createExactJacFunMethod
createExactJacFun(otherCode::Expr,Exactjac:: Dict{Expr,Union{Float64,Int,Symbol,Expr}},funName::Symbol,f::F) where{F}

constructs the exact jacobian entries as a function from the existing dictionary Exactjac resulted from extractJacDepNormal and extractJacDepLoop functions.

From the input dictionary exactJac, we see that the key is always a expression that hold a tuple of size 2: the first element is going to be the index 'i' and the second element if the index 'j'. The value corresponding to this key, which is the exact jacobian entry, is put in a cache. i.e the function maps the keys of the dictionary to their values using an 'if-statement.. This approach does not depend on the size of the problem. # Example:

using QuantizedSystemSolver
 exacteJacExpr=Dict{Expr,Union{Float64,Int,Symbol,Expr}}(:((1, 1)) => :(-2.0 * (q[2])[0]), :((1, 2)) => :(1 - 2.0 * (q[1])[0]),:(((2, 9), i - 1)) => :((q[i])[0]), :(((2, 9), i)) => :((q[i - 1])[0]),:((10, 10)) => -1, :((10, 1)) => 1);
 exactJac=QuantizedSystemSolver.createExactJacFun(:(),exacteJacExpr,:f,0);
 exactJac
@@ -122,7 +122,7 @@
               cache[1] = 1
               return nothing
           end,)
-  end)
source
QuantizedSystemSolver.createContEqFunMethod
createContEqFun(otherCode::Expr,equs::Dict{Union{Int,Expr},Union{Int,Symbol,Expr}},fname::Symbol,f::F) where{F}

constructs one function from all differential equations in the problem, which are transformed and stored in a dictionary in the NLodeProblemFunc function.

The function maps the keys of the dictionary to their values using an 'if-statement. # Example:

using QuantizedSystemSolver
+  end)
source
QuantizedSystemSolver.createContEqFunMethod
createContEqFun(otherCode::Expr,equs::Dict{Union{Int,Expr},Union{Int,Symbol,Expr}},fname::Symbol,f::F) where{F}

constructs one function from all differential equations in the problem, which are transformed and stored in a dictionary in the NLodeProblemFunc function.

The function maps the keys of the dictionary to their values using an 'if-statement. # Example:

using QuantizedSystemSolver
 equs = Dict{Union{Int,Expr},Union{Int,Symbol,Expr}}(10 => :(subT(q[1], q[10], cache[1])), :((2, 9)) => :(mulT(q[i], q[i - 1], cache[1])), 1 => :(subT(q[2], mulTT(2.0, q[1], q[2], cache[2], cache[3]), cache[1])));
 diffEqfun=QuantizedSystemSolver.createContEqFun(:(),equs,:f,0); 
 diffEqfun 
@@ -142,60 +142,60 @@
               subT(q[2], mulTT(2.0, q[1], q[2], cache[2], cache[3]), cache[1])
               return nothing
           end,)
-  end)
source
QuantizedSystemSolver.extractJacDepNormalDiscreteMethod
extractJacDepNormalDiscrete(varNum::Int,rhs::Union{Symbol,Int,Expr},jac :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}},exactJacExpr :: Dict{Expr,Union{Float64,Int,Symbol,Expr}},symDict::Dict{Symbol,Expr},dD :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}})

Extracts the jacobian dependency (jac) as well as the exacte symbolic jacobian expression (exactJacExpr) and the dependency of state derivatives to discrete variables (dD), in the form of dictionaries, from the simple differential equations.

For the continuous part, similar to extractJacDepNormal function, this function sarts by looking for the 'i' in q[i] in the RHS and storing this 'i' in a jacSet for the varNum. Then, it changes q[i] to qi for symbolic differentiation. After finding $\frac{\partial f_i}{\partial q_i}$ as the exact jacobian entry, it changes back qi to q[i]. Also, any mute variable from the differential equations is changed to 'i'.

For the discrete part, the function puts the index of the differential equation in a set, and stores this set in a dictionary dD with the key being the index of the discrete variable.

Example:

using QuantizedSystemSolver
+  end)
source
QuantizedSystemSolver.extractJacDepNormalDiscreteMethod
extractJacDepNormalDiscrete(varNum::Int,rhs::Union{Symbol,Int,Expr},jac :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}},exactJacExpr :: Dict{Expr,Union{Float64,Int,Symbol,Expr}},symDict::Dict{Symbol,Expr},dD :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}})

Extracts the jacobian dependency (jac) as well as the exacte symbolic jacobian expression (exactJacExpr) and the dependency of state derivatives to discrete variables (dD), in the form of dictionaries, from the simple differential equations.

For the continuous part, similar to extractJacDepNormal function, this function sarts by looking for the 'i' in q[i] in the RHS and storing this 'i' in a jacSet for the varNum. Then, it changes q[i] to qi for symbolic differentiation. After finding $\frac{\partial f_i}{\partial q_i}$ as the exact jacobian entry, it changes back qi to q[i]. Also, any mute variable from the differential equations is changed to 'i'.

For the discrete part, the function puts the index of the differential equation in a set, and stores this set in a dictionary dD with the key being the index of the discrete variable.

Example:

using QuantizedSystemSolver
 (varNum, rhs, jac, exactJacExpr, symDict, dD) = (1, :(p[2] - 2.0 * q[1] * p[2]), Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(), Dict{Expr, Union{Float64, Int64, Expr, Symbol}}(), Dict{Symbol, Expr}(:q10 => :(q[10]), :p2 => :(p[2]), :qiminus1 => :(q[i - 1]), :p1 => :(p[1]), :q1 => :(q[1])), Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}())
 QuantizedSystemSolver.extractJacDepNormalDiscrete(varNum, rhs, jac, exactJacExpr, symDict, dD )
 (jac, exactJacExpr, dD) 
 
 # output
 
-(Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(1 => Set([1])), Dict{Expr, Union{Float64, Int64, Expr, Symbol}}(:((1, 1)) => :(-2.0 * p[2])), Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(2 => Set([1])))
source
QuantizedSystemSolver.extractJacDepLoopDiscreteMethod
extractJacDepLoopDiscrete(b::Int,niter::Int,rhs::Union{Symbol,Int,Expr},jac :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}},exactJacExpr :: Dict{Expr,Union{Float64,Int,Symbol,Expr}},symDict::Dict{Symbol,Expr},dD :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}})

This function is similar to the extractJacDepNormalDiscrete function by using the tuple (b,niter) instead of the integer varNum. Itextracts the jacobian dependency (jac) as well as the exacte symbolic jacobian expression (exactJacExpr) and the dependency of state derivatives to discrete variables (dD), in the form of dictionaries, from the differential equations that are written in a loop.

For the continuous part, it sarts by looking for the 'i' in q[i] in the RHS and storing this 'i' in a jacSet. Then, it changes q[i] to qi for symbolic differentiation. After finding $\frac{\partial f_i}{\partial q_i}$ as the exact jacobian entry, it changes back qi to q[i]. Also, any mute variable from the differential equations is changed to 'i'.

For the discrete part, the function puts the the tuple (b,niter) in a set, and stores this set in a dictionary dD with the key being the index of the discrete variable. # Example:

using QuantizedSystemSolver
+(Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(1 => Set([1])), Dict{Expr, Union{Float64, Int64, Expr, Symbol}}(:((1, 1)) => :(-2.0 * p[2])), Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(2 => Set([1])))
source
QuantizedSystemSolver.extractJacDepLoopDiscreteMethod
extractJacDepLoopDiscrete(b::Int,niter::Int,rhs::Union{Symbol,Int,Expr},jac :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}},exactJacExpr :: Dict{Expr,Union{Float64,Int,Symbol,Expr}},symDict::Dict{Symbol,Expr},dD :: Dict{Union{Int,Expr},Set{Union{Int,Symbol,Expr}}})

This function is similar to the extractJacDepNormalDiscrete function by using the tuple (b,niter) instead of the integer varNum. Itextracts the jacobian dependency (jac) as well as the exacte symbolic jacobian expression (exactJacExpr) and the dependency of state derivatives to discrete variables (dD), in the form of dictionaries, from the differential equations that are written in a loop.

For the continuous part, it sarts by looking for the 'i' in q[i] in the RHS and storing this 'i' in a jacSet. Then, it changes q[i] to qi for symbolic differentiation. After finding $\frac{\partial f_i}{\partial q_i}$ as the exact jacobian entry, it changes back qi to q[i]. Also, any mute variable from the differential equations is changed to 'i'.

For the discrete part, the function puts the the tuple (b,niter) in a set, and stores this set in a dictionary dD with the key being the index of the discrete variable. # Example:

using QuantizedSystemSolver
 (b, niter, rhs, jac, exactJacExpr, symDict, dD) = (2, 9, :(p[1] * q[i - 1] * 1.5), Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(1 => Set([1])), Dict{Expr, Union{Float64, Int64, Expr, Symbol}}(:((1, 1)) => :(-2.0 * p[2])), Dict{Symbol, Expr}(:q10 => :(q[10]), :p2 => :(p[2]), :qiminus1 => :(q[i - 1]), :p1 => :(p[1]), :q1 => :(q[1])), Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(2 => Set([1])))
 QuantizedSystemSolver.extractJacDepLoopDiscrete(b, niter, rhs, jac, exactJacExpr, symDict, dD )
 (jac, exactJacExpr, dD) 
 
 # output
 
-(Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(:((2, 9)) => Set([:(i - 1)]), 1 => Set([1])), Dict{Expr, Union{Float64, Int64, Expr, Symbol}}(:((1, 1)) => :(-2.0 * p[2]), :(((2, 9), i - 1)) => :(1.5 * p[1])), Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(2 => Set([1]), 1 => Set([:((2, 9))])))
source
QuantizedSystemSolver.extractZCJacDepNormalMethod
extractZCJacDepNormal(counter::Int,zcf::Expr,zcjac :: Vector{Vector{Int}},SZ ::Dict{Int,Set{Int}},dZ :: Dict{Int,Set{Int}})

Extracts the zero-crossing jacobian dependency as a vector (zcjac), the dependency of the zero-crossing functions to continuous (SZ) and discrete variables (dZ) in the form of dictionaries, from the 'if-statements' (zcf).

The zcjac is a vector of vectors, where each vector contains the indices of the continuous variables that the zero-crossing function depends on. The SZ dictionary contains the indices of the zero-crossing functions as values and the indices of the continuous variables as keys. Similarly, the dZ dictionary contains the indices of the zero-crossing functions as values and the indices of the discrete variables as keys.

Example:

using QuantizedSystemSolver
+(Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(:((2, 9)) => Set([:(i - 1)]), 1 => Set([1])), Dict{Expr, Union{Float64, Int64, Expr, Symbol}}(:((1, 1)) => :(-2.0 * p[2]), :(((2, 9), i - 1)) => :(1.5 * p[1])), Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(2 => Set([1]), 1 => Set([:((2, 9))])))
source
QuantizedSystemSolver.extractZCJacDepNormalMethod
extractZCJacDepNormal(counter::Int,zcf::Expr,zcjac :: Vector{Vector{Int}},SZ ::Dict{Int,Set{Int}},dZ :: Dict{Int,Set{Int}})

Extracts the zero-crossing jacobian dependency as a vector (zcjac), the dependency of the zero-crossing functions to continuous (SZ) and discrete variables (dZ) in the form of dictionaries, from the 'if-statements' (zcf).

The zcjac is a vector of vectors, where each vector contains the indices of the continuous variables that the zero-crossing function depends on. The SZ dictionary contains the indices of the zero-crossing functions as values and the indices of the continuous variables as keys. Similarly, the dZ dictionary contains the indices of the zero-crossing functions as values and the indices of the discrete variables as keys.

Example:

using QuantizedSystemSolver
 (counter, zcf, zcjac, SZ, dZ) = (2, :(q[2] - p[1]), [[1]], Dict{Int64, Set{Int64}}(1 => Set([1])), Dict{Int64, Set{Int64}}())
 QuantizedSystemSolver.extractZCJacDepNormal(counter, zcf, zcjac, SZ, dZ)
 (zcjac, SZ, dZ) 
 
 # output
 
-([[1], [2]], Dict{Int64, Set{Int64}}(2 => Set([2]), 1 => Set([1])), Dict{Int64, Set{Int64}}(1 => Set([2])))
source
QuantizedSystemSolver.EventDependencyStructType
EventDependencyStruct

A struct that holds the event dependency information. It has the following fields:

  • id::Int: the id of the event
  • evCont::Vector{Int}: the index tracking used for HD & HZ. Also it is used to update q,quantum,recomputeNext when x is modified in an event
  • evDisc::Vector{Int}: the index tracking used for HD & HZ.
  • evContRHS::Vector{Int}: the index tracking used to update other Qs before executing the event
source
QuantizedSystemSolver.createSZVectMethod
createSZVect(SZ :: Dict{Int64, Set{Int64}},::Val{T}) where {T}

constructs the zero-crossing dependency to state variables as a vector from the existing dictionary SZ resulted from the extractZCJacDepNormal function. The continuous variables are the keys and the zero-crossing are the values.

Example:

using QuantizedSystemSolver
+([[1], [2]], Dict{Int64, Set{Int64}}(2 => Set([2]), 1 => Set([1])), Dict{Int64, Set{Int64}}(1 => Set([2])))
source
QuantizedSystemSolver.EventDependencyStructType
EventDependencyStruct

A struct that holds the event dependency information. It has the following fields:

  • id::Int: the id of the event
  • evCont::Vector{Int}: the index tracking used for HD & HZ. Also it is used to update q,quantum,recomputeNext when x is modified in an event
  • evDisc::Vector{Int}: the index tracking used for HD & HZ.
  • evContRHS::Vector{Int}: the index tracking used to update other Qs before executing the event
source
QuantizedSystemSolver.createSZVectMethod
createSZVect(SZ :: Dict{Int64, Set{Int64}},::Val{T}) where {T}

constructs the zero-crossing dependency to state variables as a vector from the existing dictionary SZ resulted from the extractZCJacDepNormal function. The continuous variables are the keys and the zero-crossing are the values.

Example:

using QuantizedSystemSolver
 (SZ, T) = (Dict{Int64, Set{Int64}}(2 => Set([2]), 1 => Set([1])), 10)
 szVec=QuantizedSystemSolver.createSZVect(SZ, Val(T))
 string(szVec)
 
 # output
 
-"[[1], [2], Int64[], Int64[], Int64[], Int64[], Int64[], Int64[], Int64[], Int64[]]"
source
QuantizedSystemSolver.createdDVectMethod
createdDVect(dD::Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}},::Val{D}) where {D}

constructs the State to derivative dependency to discrete variables as a vector from the existing dictionary dD resulted from the extractJacDepNormalDiscrete and the extractJacDepLoopDiscrete functions. The discrete variables are the keys and the differential equations are the values. This dependency is needed only in createDependencyToEventsDiscr .

Example:

using QuantizedSystemSolver
+"[[1], [2], Int64[], Int64[], Int64[], Int64[], Int64[], Int64[], Int64[], Int64[]]"
source
QuantizedSystemSolver.createdDVectMethod
createdDVect(dD::Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}},::Val{D}) where {D}

constructs the State to derivative dependency to discrete variables as a vector from the existing dictionary dD resulted from the extractJacDepNormalDiscrete and the extractJacDepLoopDiscrete functions. The discrete variables are the keys and the differential equations are the values. This dependency is needed only in createDependencyToEventsDiscr .

Example:

using QuantizedSystemSolver
 (dD, D) = (Dict{Union{Int64, Expr}, Set{Union{Int64, Expr, Symbol}}}(2 => Set([10, 1]), 1 => Set([:((2, 9))])), 2)
 dDVect=QuantizedSystemSolver.createdDVect(dD, Val(D) )
 string(dDVect)
 
 # output
 
-"[[2, 3, 4, 5, 6, 7, 8, 9], [10, 1]]"
source
QuantizedSystemSolver.createDependencyToEventsDiscrMethod
createDependencyToEventsDiscr(dD::Vector{Vector{Int}},dZ::Dict{Int64, Set{Int64}},eventDep::Vector{EventDependencyStruct})

constructs the dependency of zero-crossing functions and state derivatives to events using only discrete variables.

arguments

  • dD::Vector{Vector{Int}}: the dependency of state derivatives to discrete variables as a vector
  • dZ::Dict{Int64, Set{Int64}}: the dependency of zero-crossing functions to discrete variables as a dictionary
  • eventDep::Vector{EventDependencyStruct}: the event dependency information as a vector of structs

returns

  • HZ1::Vector{Vector{Int}}: the dependency of zero-crossing functions to events using only discrete variables

  • HD1::Vector{Vector{Int}}: the dependency of differential equations to events using only discrete variables

    Example:

using QuantizedSystemSolver
+"[[2, 3, 4, 5, 6, 7, 8, 9], [10, 1]]"
source
QuantizedSystemSolver.createDependencyToEventsDiscrMethod
createDependencyToEventsDiscr(dD::Vector{Vector{Int}},dZ::Dict{Int64, Set{Int64}},eventDep::Vector{EventDependencyStruct})

constructs the dependency of zero-crossing functions and state derivatives to events using only discrete variables.

arguments

  • dD::Vector{Vector{Int}}: the dependency of state derivatives to discrete variables as a vector
  • dZ::Dict{Int64, Set{Int64}}: the dependency of zero-crossing functions to discrete variables as a dictionary
  • eventDep::Vector{EventDependencyStruct}: the event dependency information as a vector of structs

returns

  • HZ1::Vector{Vector{Int}}: the dependency of zero-crossing functions to events using only discrete variables

  • HD1::Vector{Vector{Int}}: the dependency of differential equations to events using only discrete variables

    Example:

using QuantizedSystemSolver
 (dD, dZ, eventDep) = ([[2, 3, 4, 5, 6, 7, 8, 9], [10, 1]], Dict{Int64, Set{Int64}}(1 => Set([2])), QuantizedSystemSolver.EventDependencyStruct[QuantizedSystemSolver.EventDependencyStruct(1, Int64[], [1], Int64[]), QuantizedSystemSolver.EventDependencyStruct(2, Int64[], Int64[], Int64[]), QuantizedSystemSolver.EventDependencyStruct(3, [3], [2], [3, 1, 2]), QuantizedSystemSolver.EventDependencyStruct(4, Int64[], Int64[], Int64[])])
 (HZ1, HD1) =QuantizedSystemSolver.createDependencyToEventsDiscr(dD, dZ, eventDep )
 (HZ1, HD1) 
 
 # output
 
-([[2], Int64[], Int64[], Int64[]], [[5, 4, 6, 7, 2, 9, 8, 3], Int64[], [10, 1], Int64[]])
source
QuantizedSystemSolver.createDependencyToEventsContMethod
createDependencyToEventsCont(SD::Vector{Vector{Int}},sZ::Dict{Int64, Set{Int64}},eventDep::Vector{EventDependencyStruct})

constructs the dependency of zero-crossing functions and state derivatives to events using only continuous variables.

arguments

  • SD::Vector{Vector{Int}}: the dependency of state derivatives to continuous variables as a vector
  • sZ::Dict{Int64, Set{Int64}}: the dependency of zero-crossing functions to continuous variables as a dictionary
  • eventDep::Vector{EventDependencyStruct}: the event dependency information as a vector of structs

returns

  • HZ2::Vector{Vector{Int}}: the dependency of zero-crossing functions to events using only continuous variables

  • HD2::Vector{Vector{Int}}: the dependency of differential equations to events using only continuous variables

    Example:

using QuantizedSystemSolver
+([[2], Int64[], Int64[], Int64[]], [[5, 4, 6, 7, 2, 9, 8, 3], Int64[], [10, 1], Int64[]])
source
QuantizedSystemSolver.createDependencyToEventsContMethod
createDependencyToEventsCont(SD::Vector{Vector{Int}},sZ::Dict{Int64, Set{Int64}},eventDep::Vector{EventDependencyStruct})

constructs the dependency of zero-crossing functions and state derivatives to events using only continuous variables.

arguments

  • SD::Vector{Vector{Int}}: the dependency of state derivatives to continuous variables as a vector
  • sZ::Dict{Int64, Set{Int64}}: the dependency of zero-crossing functions to continuous variables as a dictionary
  • eventDep::Vector{EventDependencyStruct}: the event dependency information as a vector of structs

returns

  • HZ2::Vector{Vector{Int}}: the dependency of zero-crossing functions to events using only continuous variables

  • HD2::Vector{Vector{Int}}: the dependency of differential equations to events using only continuous variables

    Example:

using QuantizedSystemSolver
 (SD, sZ, eventDep) = ([[10, 2, 1], [3], [4], [5], [6], [7], [8], [9], Int64[], [10]], Dict{Int64, Set{Int64}}(2 => Set([2]), 1 => Set([1])), QuantizedSystemSolver.EventDependencyStruct[QuantizedSystemSolver.EventDependencyStruct(1, Int64[], [1], Int64[]), QuantizedSystemSolver.EventDependencyStruct(2, Int64[], Int64[], Int64[]), QuantizedSystemSolver.EventDependencyStruct(3, [3], [2], [3, 1, 2]), QuantizedSystemSolver.EventDependencyStruct(4, Int64[], Int64[], Int64[])])
 (HZ2, HD2) =QuantizedSystemSolver.createDependencyToEventsCont(SD, sZ, eventDep)
 (HZ2, HD2) 
 
 # output
 
-([Int64[], Int64[], Int64[], Int64[]], [Int64[], Int64[], [4], Int64[]])
source
QuantizedSystemSolver.unionDependencyMethod
unionDependency(HZD1::Vector{Vector{Int}},HZD2::Vector{Vector{Int}})

merges the state derivatives and zero-crossing functions dependencies to events using both continuous and discrete variables.

Example:

using QuantizedSystemSolver
+([Int64[], Int64[], Int64[], Int64[]], [Int64[], Int64[], [4], Int64[]])
source
QuantizedSystemSolver.unionDependencyMethod
unionDependency(HZD1::Vector{Vector{Int}},HZD2::Vector{Vector{Int}})

merges the state derivatives and zero-crossing functions dependencies to events using both continuous and discrete variables.

Example:

using QuantizedSystemSolver
 (HD1, HD2) = ([[5, 4, 6, 7, 2, 9, 8, 3], Int64[], [10, 1], Int64[]], [Int64[], Int64[], [4], Int64[]])
 HD=QuantizedSystemSolver.unionDependency(HD1, HD2)
 string(HD)
 
 # output
 
-"[[5, 4, 6, 7, 2, 9, 8, 3], Int64[], [4, 10, 1], Int64[]]"
source

Index

+"[[5, 4, 6, 7, 2, 9, 8, 3], Int64[], [4, 10, 1], Int64[]]"
source

Index

diff --git a/dev/developer/quantizer/index.html b/dev/developer/quantizer/index.html index 580d722..94e6902 100644 --- a/dev/developer/quantizer/index.html +++ b/dev/developer/quantizer/index.html @@ -1,2 +1,2 @@ -Quantizer · Quantized System Solver

Quantizer

The Quantizer functions

The system handles different quantizer orders (Order 1 and Order 2...). It defines methods for state integration, derivative computation, event time computation, updating quantized values, and cycle detection updates.

computeNextTime: for first-order, the state of the system changes at a constant rate. The core calculation takes place when the first derivative of the state, represented by $x[i][1]$, is non-zero. In this case, the function determines the time to the next event by dividing a quantum threshold by this derivative. Additionally, to prevent numerical issues, it ensures that this calculated time-step does not fall below a predefined minimum value, $absDeltaT$. If the first derivative is extremely small or essentially zero, the function adjusts it to avoid potential numerical instabilities that could arise from very small time increments.

For second-order, the system state evolves with both a rate of change (first derivative) and acceleration (second derivative). The core calculation occurs when the second derivative of the state, represented by $x[i][2]$, is non-zero. In this case, the function computes the time to the next event by using the square root of the ratio between a quantum threshold and the second derivative. This ensures that the time-step reflects the influence of the system's acceleration. Additionally, to prevent numerical issues (such as division by zero or overly small time-steps), a minimum delta time (absDeltaT) is enforced. If the computed time-step is smaller than this threshold, the function adjusts the second derivative to maintain stability. If the second derivative is zero but the first derivative is non-zero, the time to the next event is calculated based on the first derivative. The function ensures that the time-step does not drop below absDeltaT, adjusting the first derivative if necessary. If both derivatives are zero, the system is assumed to have no change, and the next event time is set to infinity (Inf).

recomputeNextTime: The reComputeNextTime functions are used in the explicit QSS algorithms to enable the recalculation of the next time after interactions between different variables, such as variable i and variable j. These functions determine the time until the system crosses the quantum threshold by solving polynomial equations derived from the difference between the quantized state and the actual state. In situations where the quantum threshold has already been surpassed, they promptly return a very small time increment (e.g., simt + 1e-12) to trigger an immediate update of the system's state.

LiqssrecomputeNextTime: In the LIQSS methods of first-order, the recomputeNextTime function calculates the next event time based on the current state (x), its first derivative (x1), and the quantized state (q). First, if the difference between the current state and the quantized state exceeds twice the quantum size, the next event is scheduled almost immediately with a small time-step. Otherwise, if the derivative is non-zero, the function computes the time-step by dividing the state difference by the derivative. If the result is positive, this time is added to the current simulation time (simt). If negative, it adjusts the time-step by either adding or subtracting twice the quantum size based on the direction of change. If the derivative is zero, indicating no change, the event time is set to infinity. Lastly, if the computed time is in the past, the function resets it to a far future time to prevent any premature events. This ensures that the system evolves smoothly and accurately.

In the second-order LIQSS method, the recomputeNextTime function calculates the next event time by considering both the state (x) and its first (x1) and second (x2) derivatives, along with the quantized state (q). The function constructs a polynomial using the current state, derivative values, and the second derivative, then calculates the next event time by finding the smallest positive root of this polynomial.

computeNextInputTime: The computeNextInputTime functions focus on computing the next action when derivatives depend only on time. They assess changes in the derivatives over a specified elapsed time to compute the time increment until the next input action. If the derivatives are null, the function reverts to handling the system in a lower-order thus simplifying the calculation.

computeNextEventTime: The computeNextEventTime function calculates the next event time based on the zero-crossing function ($ZCFun$) of a system. It first checks if a sign change has occurred in the zero-crossing function, indicating that the system is leaving zero and should be considered an event, provided the previous value is significantly different from zero (to prevent duplicate events). If a sign change is detected, the function updates the event time to the current simulation time. If both the old and new values of the zero-crossing function are zero, it sets the next event time to infinity, indicating no event should occur. For cases where the old and new values have the same sign, it calculates the minimum positive root of the zero-crossing function, representing the time of the next event, ensuring that this time is not too close to zero to avoid spurious events. The function then updates the old sign values for future comparisons.

Quantizer references

QuantizedSystemSolver.integrateStateMethod
integrateState(::Val{0}, x::Taylor0, elapsed::Float64)

does nothing: created for elapse-updating q in order1 which does not happen. This is needed in order to have one integrator function for all orders.

source
QuantizedSystemSolver.integrateStateMethod
integrateState(::Val{1}, x::Taylor0, elapsed::Float64)

Integrates the state for a first-order quantized system.

Arguments

  • ::Val{1}: A type parameter indicating the order of the quantized system.
  • x::Taylor0: The current state variable x represented as a Taylor0 object.
  • elapsed::Float64: The elapsed time since the last integration step of this variable x.
source
QuantizedSystemSolver.integrateStateMethod
integrateState(::Val{2}, x::Taylor0, elapsed::Float64)

Integrates a state variable x and its first derivative using a second-order Taylor series approximation

Arguments

  • ::Val{2}: A type parameter indicating the order of the Taylor series (second-order in this case).
  • x::Taylor0: The current state variable x represented as a Taylor0 object.
  • elapsed::Float64: The elapsed time over which to integrate the state x.
source
QuantizedSystemSolver.computeDerivativeMethod
computeDerivative(::Val{1}, x::Taylor0, f::Taylor0)

copies the derivative from f to the first derivative of x for the first order.

Arguments

  • ::Val{1}: A type parameter indicating the order of the derivative.
  • x::Taylor0: The state variable .
  • f::Taylor0: The Taylor series function that corresponds to the derivative.
source
QuantizedSystemSolver.computeDerivativeMethod
computeDerivative(::Val{2}, x::Taylor0, f::Taylor0)

copies the first and second derivatives from f to the derivatives of x for the second-order quantizer.

Arguments

  • ::Val{2}: A type parameter indicating the order of the quantizer.
  • x::Taylor0: The state variable .
  • f::Taylor0: The Taylor series function that corresponds to the derivative.
source
QuantizedSystemSolver.computeNextTimeMethod
computeNextTime(::Val{1}, i::Int, simt::Float64, nextTime::Vector{Float64}, x::Vector{Taylor0}, quantum::Vector{Float64})

Compute the next time of change for a given state variable.

Arguments

  • ::Val{1}: A type parameter indicating a first order quantization method.
  • i::Int: The index of the current state variable.
  • simt::Float64: The current simulation time.
  • nextTime::Vector{Float64}: A vector containing the next time values for each state variable.
  • x::Vector{Taylor0}: A vector of Taylor series coefficients representing the state variables and their derivatives.
  • quantum::Vector{Float64}: A vector containing the quantum values for the state variables.

Returns

  • The function updates the nextTime vector with the computed next time values for the state variables.
source
QuantizedSystemSolver.computeNextTimeMethod
computeNextTime(::Val{2}, i::Int, simt::Float64, nextTime::Vector{Float64}, x::Vector{Taylor0}, quantum::Vector{Float64})

Compute the next time for a given state variable i in a second-order quantized system.

Arguments

  • ::Val{2}: A type parameter indicating the order of the quantized system (second-order).
  • i::Int: The index of variable for which the next time is being computed.
  • simt::Float64: The current simulation time.
  • nextTime::Vector{Float64}: A vector containing the next times for all variables.
  • x::Vector{Taylor0}: A vector of Taylor series coefficients representing the state variables and their derivatives.
  • quantum::Vector{Float64}: A vector of quantum values for the state variables.

Returns

  • Nothing: This function updates the nextTime vector in place.
source
QuantizedSystemSolver.reComputeNextTimeMethod
reComputeNextTime(::Val{1}, index::Int, simt::Float64, nextTime::Vector{Float64}, x::Vector{Taylor0}, q::Vector{Taylor0}, quantum::Vector{Float64})

Recomputes the next time for a given state variable i in a first-order quantized system after the derivative has changed. similar to computeNextTime but it also account for the first derivative change.

source
QuantizedSystemSolver.reComputeNextTimeMethod
reComputeNextTime(::Val{2}, index::Int, simt::Float64, nextTime::Vector{Float64}, x::Vector{Taylor0}, q::Vector{Taylor0}, quantum::Vector{Float64})

Recomputes the next time for a given state variable i in a second-order quantized system after the derivatives have changed. similar to computeNextTime but it also account for the first and second derivatives changes.

source
QuantizedSystemSolver.computeNextInputTimeMethod
computeNextInputTime(::Val{1}, i::Int, simt::Float64, elapsed::Float64, tt::Taylor0, nextInputTime::Vector{Float64}, x::Vector{Taylor0}, quantum::Vector{Float64})

Compute the next input time for a given state variable in a first order method. This is needed when the differential equation depends on time only (i.e. does not depend on other state variables). It uses a prediction of the derivatives.

Arguments

  • ::Val{1}: A type parameter indicating the specific method to use.
  • i::Int: The index of the current state variable.
  • simt::Float64: The current simulation time.
  • elapsed::Float64: The elapsed time since the last update.
  • tt::Taylor0: The Taylor series expansion of the state variable in a small time advance.
  • nextInputTime::Vector{Float64}: A vector to store the computed next input times.
  • x::Vector{Taylor0}: A vector of Taylor series expansions of the state variables.
  • quantum::Vector{Float64}: A vector of quantum values for the state variables.

Returns

  • Nothing, it updates the nextInputTime vector with the next input times for the state variables.
source
QuantizedSystemSolver.computeNextInputTimeMethod
computeNextInputTime(::Val{2}, i::Int, simt::Float64, elapsed::Float64, tt::Taylor0, nextInputTime::Vector{Float64}, x::Vector{Taylor0}, quantum::Vector{Float64})

Compute the next input time for a given state variable in a second order method. This is needed when the differential equation depends on time only (i.e. does not depend on other state variables). It uses a prediction of the derivatives.

source
QuantizedSystemSolver.computeNextEventTimeMethod
computeNextEventTime(::Val{O},j::Int,ZCFun::Taylor0,oldsignValue::MMatrix{Z,2} ,simt::Float64,  nextEventTime :: MVector{Z,Float64}, quantum::Vector{Float64},absQ::Float64) where {O, Z}

Compute the next event time for a given zero-crossing function.

Arguments

  • ::Val{O}: A type parameter indicating the order of the quantizer.
  • j::Int: The index of the zero-crossing function being processed.
  • ZCFun::Taylor0: the value of the zero-crossing function of type Taylor0.
  • oldsignValue::MMatrix{Z,2}: The previous sign and value of the zero-crossing function.
  • simt::Float64: The current simulation time.
  • nextEventTime:: MVector{Z,Float64}: Vector contains the next event time for all zero-crossing functions.
  • quantum::Vector{Float64}: A vector of quantum values for the state variables.
  • absQ::Float64: The absolute quantum value.

Returns

  • The computed next event time for the state variable j.
source
QuantizedSystemSolver.updateQMethod
updateQ(::Val{1}, i::Int, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64}, exactA::Function, d::Vector{Float64}, cacheA::MVector{1,Float64}, dxaux::Vector{MVector{1,Float64}}, qaux::Vector{MVector{1,Float64}}, tx::Vector{Float64}, tq::Vector{Float64}, simt::Float64, ft::Float64, nextStateTime::Vector{Float64},f::F) where{F}

Update the quantized state for the LIQSS1 (Linearly Implicit Quantized State System 1) method.

Arguments

  • ::Val{1}: Type parameter indicating the LIQSS1 method.
  • i::Int: Index of the state variable to update.
  • xv::Vector{Taylor0}: Vector of current state values.
  • qv::Vector{Taylor0}: Vector of quantized state values.
  • quantum::Vector{Float64}: Vector of quantum values for the state variables.
  • exactA::Function: Function to compute the exact value of a jacobian entry.
  • d::Vector{Float64}: Vector of discrete variables.
  • cacheA::MVector{1,Float64}: Cache for jacobian entry computation.
  • dxaux::Vector{MVector{1,Float64}}: Auxiliary vector for saving old x values.
  • qaux::Vector{MVector{1,Float64}}: Auxiliary vector for saving old quantized values.
  • tx::Vector{Float64}: Vector of times at which the state variables were updated.
  • tq::Vector{Float64}: Vector of times at which the quantized state variables were updated.
  • simt::Float64: Current simulation time.
  • ft::Float64: Final time of the simulation.
  • nextStateTime::Vector{Float64}: Vector of times at which the state variables will be updated next.

Returns

  • None. The function updates the quantized state and other info in place.
source
QuantizedSystemSolver.updateQInitMethod
updateQInit(::Val{1}, i::Int, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64}, exactA::Function, d::Vector{Float64}, cacheA::MVector{1,Float64}, dxaux::Vector{MVector{1,Float64}}, qaux::Vector{MVector{1,Float64}}, tx::Vector{Float64}, tq::Vector{Float64}, simt::Float64, ft::Float64, nextStateTime::Vector{Float64},f::F) where{F}

Initialize the quantized state for the LIQSS1 method.

Arguments

  • ::Val{1}: Type parameter indicating the LIQSS1 method.
  • i::Int: Index of the state variable to update.
  • xv::Vector{Taylor0}: Vector of state variables.
  • qv::Vector{Taylor0}: Vector of quantized state variables.
  • quantum::Vector{Float64}: Vector of quantum values for the state variables.
  • exactA::Function: Function to compute the exact value of the state variable.
  • d::Vector{Float64}: Vector of derivatives of the state variables.
  • cacheA::MVector{1,Float64}: Cache for intermediate computations.
  • dxaux::Vector{MVector{1,Float64}}: Auxiliary vector for derivatives.
  • qaux::Vector{MVector{1,Float64}}: Auxiliary vector for quantized states.
  • tx::Vector{Float64}: Vector of times at which state variables were last updated.
  • tq::Vector{Float64}: Vector of times at which quantized state variables were last updated.
  • simt::Float64: Current simulation time.
  • ft::Float64: Final simulation time.
  • nextStateTime::Vector{Float64}: Vector of times at which the next state update is scheduled.

Description

This function initializes the quantized state for the LIQSS1 method by updating the quantized state variables and their associated times based on the provided state variables, derivatives, and quantum values.

source
QuantizedSystemSolver.Liqss_reComputeNextTimeMethod
Liqss_reComputeNextTime(::Val{1}, i::Int, simt::Float64, nextStateTime::Vector{Float64}, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64})

Recomputes the next time for the LIQSS1 quantizer.

Arguments

  • ::Val{1}: Type parameter indicating the LIQSS1 method.
  • i::Int: Index of the state variable.
  • simt::Float64: Current simulation time.
  • nextStateTime::Vector{Float64}: Vector containing the next state times for each state variable.
  • xv::Vector{Taylor0}: Vector of current state values represented as Taylor series.
  • qv::Vector{Taylor0}: Vector of quantized state values represented as Taylor series.
  • quantum::Vector{Float64}: Vector of quantum values for the state variables.

Returns

  • Updates the nextStateTime vector with the recomputed next time for the specified state variable.
source
QuantizedSystemSolver.nmisCycle_and_simulUpdateMethod
nmisCycle_and_simulUpdate(aij::Float64,aji::Float64,trackSimul,::Val{1},Val(M),index::Int,j::Int,dirI::Float64, x::Vector{Taylor0},q::Vector{Taylor0}, quantum::Vector{Float64},exactA::Function,d::Vector{Float64},cacheA::MVector{1,Float64},dxaux::Vector{MVector{1,Float64}},qaux::Vector{MVector{1,Float64}},tx::Vector{Float64},tq::Vector{Float64},simt::Float64,ft::Float64,f::F) where {M,F}

Performs a simultaneous update of two quantized variables qi and qj if cycle conditions are met.

Arguments

  • aij::Float64: linear approximation Coefficient for the jacobian entry between variable i and variable j.
  • aji::Float64: linear approximation Coefficient for the jacobian entry between variable j and variable i.
  • trackSimul: A tracking object for the simulataneous update.
  • ::Val{1}: A type parameter indicating the method order is order 1.
  • ::Val{M}: A type parameter indicating the detection mechanism.
  • index::Int: The index of the current variable.
  • j::Int: The index of the interacting variable.
  • dirI::Float64: Direction of variable i.
  • x::Vector{Taylor0}: State vector of Taylor series coefficients for the variables.
  • q::Vector{Taylor0}: Quantized state vector of Taylor series coefficients for the variables.
  • quantum::Vector{Float64}: Quantum levels for the variables.
  • exactA::Function: Function to compute the exact value of a jacobian entry.
  • d::Vector{Float64}: discrete variables.
  • cacheA::MVector{1,Float64}: Cache for jacobian entry computation.
  • dxaux::Vector{MVector{1,Float64}}: Auxiliary vector for old x values.
  • qaux::Vector{MVector{1,Float64}}: Auxiliary vector for old quantized values.
  • tx::Vector{Float64}: Time vector for state updates.
  • tq::Vector{Float64}: Time vector for quantized state updates.
  • simt::Float64: Current simulation time.
  • ft::Float64: Final time for the simulation.

Returns

  • None. The function performs in-place updates on the quantized state vectors.
source
QuantizedSystemSolver.updateQMethod
updateQ(::Val{2}, i::Int, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64}, exactA::Function, d::Vector{Float64}, cacheA::MVector{1,Float64}, dxaux::Vector{MVector{2,Float64}}, qaux::Vector{MVector{2,Float64}}, tx::Vector{Float64}, tq::Vector{Float64}, simt::Float64, ft::Float64, nextStateTime::Vector{Float64},f::F) where{F}

Update the quantized state for the second-order quantizer.

Arguments

  • ::Val{2}: Type parameter indicating the second-order quantizer.
  • i::Int: Index of the state variable to update.
  • xv::Vector{Taylor0}: Vector of state variables.
  • qv::Vector{Taylor0}: Vector of quantized state variables.
  • quantum::Vector{Float64}: Vector of quantum values of the state variables.
  • exactA::Function: Function to compute the exact value of a jacobian entry.
  • d::Vector{Float64}: Vector of discrete variables.
  • cacheA::MVector{1,Float64}: Cache for jacobian entry computation.
  • dxaux::Vector{MVector{2,Float64}}: Auxiliary vector for saving old x values.
  • qaux::Vector{MVector{2,Float64}}: Auxiliary vector for saving old quantized values.
  • tx::Vector{Float64}: Vector of state update times.
  • tq::Vector{Float64}: Vector of quantized state update times.
  • simt::Float64: Current simulation time.
  • ft::Float64: Final time of the simulation.
  • nextStateTime::Vector{Float64}: Vector of times for the next state updates.
source
QuantizedSystemSolver.updateQInitMethod
updateQInit(::Val{2}, i::Int, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64}, exactA::Function, d::Vector{Float64}, cacheA::MVector{1,Float64}, dxaux::Vector{MVector{2,Float64}}, qaux::Vector{MVector{2,Float64}}, tx::Vector{Float64}, tq::Vector{Float64}, simt::Float64, ft::Float64, nextStateTime::Vector{Float64},f::F) where{F}

Initialize the quantized state variables for the LIQSS2 method. It is similar to the updateQ function but does not accept q to be set to x when all derivatives are zero, which is the case when an equilibrium ocurrs during the simulation.

source
QuantizedSystemSolver.Liqss_reComputeNextTimeMethod
Liqss_reComputeNextTime(::Val{2}, i::Int, simt::Float64, nextStateTime::Vector{Float64}, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64})

Recomputes the next time for a given state in a second-order quantized state system.

Arguments

  • ::Val{2}: A type parameter indicating the order of the quantized state system (second-order in this case).
  • i::Int: The index of the state for which the next time is being recomputed.
  • simt::Float64: The current simulation time.
  • nextStateTime::Vector{Float64}: A vector containing the next state times for all states.
  • xv::Vector{Taylor0}: A vector containing the current state values represented as Taylor series.
  • qv::Vector{Taylor0}: A vector containing the quantized state values represented as Taylor series.
  • quantum::Vector{Float64}: A vector containing the quantum values the states.

Returns

  • This function does not return a value. It updates the nextStateTime vector in place.
source
QuantizedSystemSolver.nmisCycle_and_simulUpdateMethod
nmisCycle_and_simulUpdate(aij::Float64,aji::Float64,trackSimul,::Val{2},Val(M),index::Int,j::Int,dirI::Float64, x::Vector{Taylor0},q::Vector{Taylor0}, quantum::Vector{Float64},exactA::Function,d::Vector{Float64},cacheA::MVector{1,Float64},dxaux::Vector{MVector{2,Float64}},qaux::Vector{MVector{2,Float64}},tx::Vector{Float64},tq::Vector{Float64},simt::Float64,ft::Float64,f::F) where {M,F}

Performs a simultaneous update of two quantized variables qi and qj and their derivatives if cycle conditions are met. This is similar to the nmisCycle_and_simulUpdate order 1 function.

source

Index

+Quantizer · Quantized System Solver

Quantizer

The Quantizer functions

The system handles different quantizer orders (Order 1 and Order 2...). It defines methods for state integration, derivative computation, event time computation, updating quantized values, and cycle detection updates.

computeNextTime: for first-order, the state of the system changes at a constant rate. The core calculation takes place when the first derivative of the state, represented by $x[i][1]$, is non-zero. In this case, the function determines the time to the next event by dividing a quantum threshold by this derivative. Additionally, to prevent numerical issues, it ensures that this calculated time-step does not fall below a predefined minimum value, $absDeltaT$. If the first derivative is extremely small or essentially zero, the function adjusts it to avoid potential numerical instabilities that could arise from very small time increments.

For second-order, the system state evolves with both a rate of change (first derivative) and acceleration (second derivative). The core calculation occurs when the second derivative of the state, represented by $x[i][2]$, is non-zero. In this case, the function computes the time to the next event by using the square root of the ratio between a quantum threshold and the second derivative. This ensures that the time-step reflects the influence of the system's acceleration. Additionally, to prevent numerical issues (such as division by zero or overly small time-steps), a minimum delta time (absDeltaT) is enforced. If the computed time-step is smaller than this threshold, the function adjusts the second derivative to maintain stability. If the second derivative is zero but the first derivative is non-zero, the time to the next event is calculated based on the first derivative. The function ensures that the time-step does not drop below absDeltaT, adjusting the first derivative if necessary. If both derivatives are zero, the system is assumed to have no change, and the next event time is set to infinity (Inf).

recomputeNextTime: The reComputeNextTime functions are used in the explicit QSS algorithms to enable the recalculation of the next time after interactions between different variables, such as variable i and variable j. These functions determine the time until the system crosses the quantum threshold by solving polynomial equations derived from the difference between the quantized state and the actual state. In situations where the quantum threshold has already been surpassed, they promptly return a very small time increment (e.g., simt + 1e-12) to trigger an immediate update of the system's state.

LiqssrecomputeNextTime: In the LIQSS methods of first-order, the recomputeNextTime function calculates the next event time based on the current state (x), its first derivative (x1), and the quantized state (q). First, if the difference between the current state and the quantized state exceeds twice the quantum size, the next event is scheduled almost immediately with a small time-step. Otherwise, if the derivative is non-zero, the function computes the time-step by dividing the state difference by the derivative. If the result is positive, this time is added to the current simulation time (simt). If negative, it adjusts the time-step by either adding or subtracting twice the quantum size based on the direction of change. If the derivative is zero, indicating no change, the event time is set to infinity. Lastly, if the computed time is in the past, the function resets it to a far future time to prevent any premature events. This ensures that the system evolves smoothly and accurately.

In the second-order LIQSS method, the recomputeNextTime function calculates the next event time by considering both the state (x) and its first (x1) and second (x2) derivatives, along with the quantized state (q). The function constructs a polynomial using the current state, derivative values, and the second derivative, then calculates the next event time by finding the smallest positive root of this polynomial.

computeNextInputTime: The computeNextInputTime functions focus on computing the next action when derivatives depend only on time. They assess changes in the derivatives over a specified elapsed time to compute the time increment until the next input action. If the derivatives are null, the function reverts to handling the system in a lower-order thus simplifying the calculation.

computeNextEventTime: The computeNextEventTime function calculates the next event time based on the zero-crossing function ($ZCFun$) of a system. It first checks if a sign change has occurred in the zero-crossing function, indicating that the system is leaving zero and should be considered an event, provided the previous value is significantly different from zero (to prevent duplicate events). If a sign change is detected, the function updates the event time to the current simulation time. If both the old and new values of the zero-crossing function are zero, it sets the next event time to infinity, indicating no event should occur. For cases where the old and new values have the same sign, it calculates the minimum positive root of the zero-crossing function, representing the time of the next event, ensuring that this time is not too close to zero to avoid spurious events. The function then updates the old sign values for future comparisons.

Quantizer references

QuantizedSystemSolver.integrateStateMethod
integrateState(::Val{0}, x::Taylor0, elapsed::Float64)

does nothing: created for elapse-updating q in order1 which does not happen. This is needed in order to have one integrator function for all orders.

source
QuantizedSystemSolver.integrateStateMethod
integrateState(::Val{1}, x::Taylor0, elapsed::Float64)

Integrates the state for a first-order quantized system.

Arguments

  • ::Val{1}: A type parameter indicating the order of the quantized system.
  • x::Taylor0: The current state variable x represented as a Taylor0 object.
  • elapsed::Float64: The elapsed time since the last integration step of this variable x.
source
QuantizedSystemSolver.integrateStateMethod
integrateState(::Val{2}, x::Taylor0, elapsed::Float64)

Integrates a state variable x and its first derivative using a second-order Taylor series approximation

Arguments

  • ::Val{2}: A type parameter indicating the order of the Taylor series (second-order in this case).
  • x::Taylor0: The current state variable x represented as a Taylor0 object.
  • elapsed::Float64: The elapsed time over which to integrate the state x.
source
QuantizedSystemSolver.computeDerivativeMethod
computeDerivative(::Val{1}, x::Taylor0, f::Taylor0)

copies the derivative from f to the first derivative of x for the first order.

Arguments

  • ::Val{1}: A type parameter indicating the order of the derivative.
  • x::Taylor0: The state variable .
  • f::Taylor0: The Taylor series function that corresponds to the derivative.
source
QuantizedSystemSolver.computeDerivativeMethod
computeDerivative(::Val{2}, x::Taylor0, f::Taylor0)

copies the first and second derivatives from f to the derivatives of x for the second-order quantizer.

Arguments

  • ::Val{2}: A type parameter indicating the order of the quantizer.
  • x::Taylor0: The state variable .
  • f::Taylor0: The Taylor series function that corresponds to the derivative.
source
QuantizedSystemSolver.computeNextTimeMethod
computeNextTime(::Val{1}, i::Int, simt::Float64, nextTime::Vector{Float64}, x::Vector{Taylor0}, quantum::Vector{Float64})

Compute the next time of change for a given state variable.

Arguments

  • ::Val{1}: A type parameter indicating a first order quantization method.
  • i::Int: The index of the current state variable.
  • simt::Float64: The current simulation time.
  • nextTime::Vector{Float64}: A vector containing the next time values for each state variable.
  • x::Vector{Taylor0}: A vector of Taylor series coefficients representing the state variables and their derivatives.
  • quantum::Vector{Float64}: A vector containing the quantum values for the state variables.

Returns

  • The function updates the nextTime vector with the computed next time values for the state variables.
source
QuantizedSystemSolver.computeNextTimeMethod
computeNextTime(::Val{2}, i::Int, simt::Float64, nextTime::Vector{Float64}, x::Vector{Taylor0}, quantum::Vector{Float64})

Compute the next time for a given state variable i in a second-order quantized system.

Arguments

  • ::Val{2}: A type parameter indicating the order of the quantized system (second-order).
  • i::Int: The index of variable for which the next time is being computed.
  • simt::Float64: The current simulation time.
  • nextTime::Vector{Float64}: A vector containing the next times for all variables.
  • x::Vector{Taylor0}: A vector of Taylor series coefficients representing the state variables and their derivatives.
  • quantum::Vector{Float64}: A vector of quantum values for the state variables.

Returns

  • Nothing: This function updates the nextTime vector in place.
source
QuantizedSystemSolver.reComputeNextTimeMethod
reComputeNextTime(::Val{1}, index::Int, simt::Float64, nextTime::Vector{Float64}, x::Vector{Taylor0}, q::Vector{Taylor0}, quantum::Vector{Float64})

Recomputes the next time for a given state variable i in a first-order quantized system after the derivative has changed. similar to computeNextTime but it also account for the first derivative change.

source
QuantizedSystemSolver.reComputeNextTimeMethod
reComputeNextTime(::Val{2}, index::Int, simt::Float64, nextTime::Vector{Float64}, x::Vector{Taylor0}, q::Vector{Taylor0}, quantum::Vector{Float64})

Recomputes the next time for a given state variable i in a second-order quantized system after the derivatives have changed. similar to computeNextTime but it also account for the first and second derivatives changes.

source
QuantizedSystemSolver.computeNextInputTimeMethod
computeNextInputTime(::Val{1}, i::Int, simt::Float64, elapsed::Float64, tt::Taylor0, nextInputTime::Vector{Float64}, x::Vector{Taylor0}, quantum::Vector{Float64})

Compute the next input time for a given state variable in a first order method. This is needed when the differential equation depends on time only (i.e. does not depend on other state variables). It uses a prediction of the derivatives.

Arguments

  • ::Val{1}: A type parameter indicating the specific method to use.
  • i::Int: The index of the current state variable.
  • simt::Float64: The current simulation time.
  • elapsed::Float64: The elapsed time since the last update.
  • tt::Taylor0: The Taylor series expansion of the state variable in a small time advance.
  • nextInputTime::Vector{Float64}: A vector to store the computed next input times.
  • x::Vector{Taylor0}: A vector of Taylor series expansions of the state variables.
  • quantum::Vector{Float64}: A vector of quantum values for the state variables.

Returns

  • Nothing, it updates the nextInputTime vector with the next input times for the state variables.
source
QuantizedSystemSolver.computeNextInputTimeMethod
computeNextInputTime(::Val{2}, i::Int, simt::Float64, elapsed::Float64, tt::Taylor0, nextInputTime::Vector{Float64}, x::Vector{Taylor0}, quantum::Vector{Float64})

Compute the next input time for a given state variable in a second order method. This is needed when the differential equation depends on time only (i.e. does not depend on other state variables). It uses a prediction of the derivatives.

source
QuantizedSystemSolver.computeNextEventTimeMethod
computeNextEventTime(::Val{O},j::Int,ZCFun::Taylor0,oldsignValue::MMatrix{Z,2} ,simt::Float64,  nextEventTime :: MVector{Z,Float64}, quantum::Vector{Float64},absQ::Float64) where {O, Z}

Compute the next event time for a given zero-crossing function.

Arguments

  • ::Val{O}: A type parameter indicating the order of the quantizer.
  • j::Int: The index of the zero-crossing function being processed.
  • ZCFun::Taylor0: the value of the zero-crossing function of type Taylor0.
  • oldsignValue::MMatrix{Z,2}: The previous sign and value of the zero-crossing function.
  • simt::Float64: The current simulation time.
  • nextEventTime:: MVector{Z,Float64}: Vector contains the next event time for all zero-crossing functions.
  • quantum::Vector{Float64}: A vector of quantum values for the state variables.
  • absQ::Float64: The absolute quantum value.

Returns

  • The computed next event time for the state variable j.
source
QuantizedSystemSolver.updateQMethod
updateQ(::Val{1}, i::Int, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64}, exactA::Function, d::Vector{Float64}, cacheA::MVector{1,Float64}, dxaux::Vector{MVector{1,Float64}}, qaux::Vector{MVector{1,Float64}}, tx::Vector{Float64}, tq::Vector{Float64}, simt::Float64, ft::Float64, nextStateTime::Vector{Float64},f::F) where{F}

Update the quantized state for the LIQSS1 (Linearly Implicit Quantized State System 1) method.

Arguments

  • ::Val{1}: Type parameter indicating the LIQSS1 method.
  • i::Int: Index of the state variable to update.
  • xv::Vector{Taylor0}: Vector of current state values.
  • qv::Vector{Taylor0}: Vector of quantized state values.
  • quantum::Vector{Float64}: Vector of quantum values for the state variables.
  • exactA::Function: Function to compute the exact value of a jacobian entry.
  • d::Vector{Float64}: Vector of discrete variables.
  • cacheA::MVector{1,Float64}: Cache for jacobian entry computation.
  • dxaux::Vector{MVector{1,Float64}}: Auxiliary vector for saving old x values.
  • qaux::Vector{MVector{1,Float64}}: Auxiliary vector for saving old quantized values.
  • tx::Vector{Float64}: Vector of times at which the state variables were updated.
  • tq::Vector{Float64}: Vector of times at which the quantized state variables were updated.
  • simt::Float64: Current simulation time.
  • ft::Float64: Final time of the simulation.
  • nextStateTime::Vector{Float64}: Vector of times at which the state variables will be updated next.

Returns

  • None. The function updates the quantized state and other info in place.
source
QuantizedSystemSolver.updateQInitMethod
updateQInit(::Val{1}, i::Int, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64}, exactA::Function, d::Vector{Float64}, cacheA::MVector{1,Float64}, dxaux::Vector{MVector{1,Float64}}, qaux::Vector{MVector{1,Float64}}, tx::Vector{Float64}, tq::Vector{Float64}, simt::Float64, ft::Float64, nextStateTime::Vector{Float64},f::F) where{F}

Initialize the quantized state for the LIQSS1 method.

Arguments

  • ::Val{1}: Type parameter indicating the LIQSS1 method.
  • i::Int: Index of the state variable to update.
  • xv::Vector{Taylor0}: Vector of state variables.
  • qv::Vector{Taylor0}: Vector of quantized state variables.
  • quantum::Vector{Float64}: Vector of quantum values for the state variables.
  • exactA::Function: Function to compute the exact value of the state variable.
  • d::Vector{Float64}: Vector of derivatives of the state variables.
  • cacheA::MVector{1,Float64}: Cache for intermediate computations.
  • dxaux::Vector{MVector{1,Float64}}: Auxiliary vector for derivatives.
  • qaux::Vector{MVector{1,Float64}}: Auxiliary vector for quantized states.
  • tx::Vector{Float64}: Vector of times at which state variables were last updated.
  • tq::Vector{Float64}: Vector of times at which quantized state variables were last updated.
  • simt::Float64: Current simulation time.
  • ft::Float64: Final simulation time.
  • nextStateTime::Vector{Float64}: Vector of times at which the next state update is scheduled.

Description

This function initializes the quantized state for the LIQSS1 method by updating the quantized state variables and their associated times based on the provided state variables, derivatives, and quantum values.

source
QuantizedSystemSolver.Liqss_reComputeNextTimeMethod
Liqss_reComputeNextTime(::Val{1}, i::Int, simt::Float64, nextStateTime::Vector{Float64}, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64})

Recomputes the next time for the LIQSS1 quantizer.

Arguments

  • ::Val{1}: Type parameter indicating the LIQSS1 method.
  • i::Int: Index of the state variable.
  • simt::Float64: Current simulation time.
  • nextStateTime::Vector{Float64}: Vector containing the next state times for each state variable.
  • xv::Vector{Taylor0}: Vector of current state values represented as Taylor series.
  • qv::Vector{Taylor0}: Vector of quantized state values represented as Taylor series.
  • quantum::Vector{Float64}: Vector of quantum values for the state variables.

Returns

  • Updates the nextStateTime vector with the recomputed next time for the specified state variable.
source
QuantizedSystemSolver.nmisCycle_and_simulUpdateMethod
nmisCycle_and_simulUpdate(aij::Float64,aji::Float64,trackSimul,::Val{1},Val(M),index::Int,j::Int,dirI::Float64, x::Vector{Taylor0},q::Vector{Taylor0}, quantum::Vector{Float64},exactA::Function,d::Vector{Float64},cacheA::MVector{1,Float64},dxaux::Vector{MVector{1,Float64}},qaux::Vector{MVector{1,Float64}},tx::Vector{Float64},tq::Vector{Float64},simt::Float64,ft::Float64,f::F) where {M,F}

Performs a simultaneous update of two quantized variables qi and qj if cycle conditions are met.

Arguments

  • aij::Float64: linear approximation Coefficient for the jacobian entry between variable i and variable j.
  • aji::Float64: linear approximation Coefficient for the jacobian entry between variable j and variable i.
  • trackSimul: A tracking object for the simulataneous update.
  • ::Val{1}: A type parameter indicating the method order is order 1.
  • ::Val{M}: A type parameter indicating the detection mechanism.
  • index::Int: The index of the current variable.
  • j::Int: The index of the interacting variable.
  • dirI::Float64: Direction of variable i.
  • x::Vector{Taylor0}: State vector of Taylor series coefficients for the variables.
  • q::Vector{Taylor0}: Quantized state vector of Taylor series coefficients for the variables.
  • quantum::Vector{Float64}: Quantum levels for the variables.
  • exactA::Function: Function to compute the exact value of a jacobian entry.
  • d::Vector{Float64}: discrete variables.
  • cacheA::MVector{1,Float64}: Cache for jacobian entry computation.
  • dxaux::Vector{MVector{1,Float64}}: Auxiliary vector for old x values.
  • qaux::Vector{MVector{1,Float64}}: Auxiliary vector for old quantized values.
  • tx::Vector{Float64}: Time vector for state updates.
  • tq::Vector{Float64}: Time vector for quantized state updates.
  • simt::Float64: Current simulation time.
  • ft::Float64: Final time for the simulation.

Returns

  • None. The function performs in-place updates on the quantized state vectors.
source
QuantizedSystemSolver.updateQMethod
updateQ(::Val{2}, i::Int, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64}, exactA::Function, d::Vector{Float64}, cacheA::MVector{1,Float64}, dxaux::Vector{MVector{2,Float64}}, qaux::Vector{MVector{2,Float64}}, tx::Vector{Float64}, tq::Vector{Float64}, simt::Float64, ft::Float64, nextStateTime::Vector{Float64},f::F) where{F}

Update the quantized state for the second-order quantizer.

Arguments

  • ::Val{2}: Type parameter indicating the second-order quantizer.
  • i::Int: Index of the state variable to update.
  • xv::Vector{Taylor0}: Vector of state variables.
  • qv::Vector{Taylor0}: Vector of quantized state variables.
  • quantum::Vector{Float64}: Vector of quantum values of the state variables.
  • exactA::Function: Function to compute the exact value of a jacobian entry.
  • d::Vector{Float64}: Vector of discrete variables.
  • cacheA::MVector{1,Float64}: Cache for jacobian entry computation.
  • dxaux::Vector{MVector{2,Float64}}: Auxiliary vector for saving old x values.
  • qaux::Vector{MVector{2,Float64}}: Auxiliary vector for saving old quantized values.
  • tx::Vector{Float64}: Vector of state update times.
  • tq::Vector{Float64}: Vector of quantized state update times.
  • simt::Float64: Current simulation time.
  • ft::Float64: Final time of the simulation.
  • nextStateTime::Vector{Float64}: Vector of times for the next state updates.
source
QuantizedSystemSolver.updateQInitMethod
updateQInit(::Val{2}, i::Int, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64}, exactA::Function, d::Vector{Float64}, cacheA::MVector{1,Float64}, dxaux::Vector{MVector{2,Float64}}, qaux::Vector{MVector{2,Float64}}, tx::Vector{Float64}, tq::Vector{Float64}, simt::Float64, ft::Float64, nextStateTime::Vector{Float64},f::F) where{F}

Initialize the quantized state variables for the LIQSS2 method. It is similar to the updateQ function but does not accept q to be set to x when all derivatives are zero, which is the case when an equilibrium ocurrs during the simulation.

source
QuantizedSystemSolver.Liqss_reComputeNextTimeMethod
Liqss_reComputeNextTime(::Val{2}, i::Int, simt::Float64, nextStateTime::Vector{Float64}, xv::Vector{Taylor0}, qv::Vector{Taylor0}, quantum::Vector{Float64})

Recomputes the next time for a given state in a second-order quantized state system.

Arguments

  • ::Val{2}: A type parameter indicating the order of the quantized state system (second-order in this case).
  • i::Int: The index of the state for which the next time is being recomputed.
  • simt::Float64: The current simulation time.
  • nextStateTime::Vector{Float64}: A vector containing the next state times for all states.
  • xv::Vector{Taylor0}: A vector containing the current state values represented as Taylor series.
  • qv::Vector{Taylor0}: A vector containing the quantized state values represented as Taylor series.
  • quantum::Vector{Float64}: A vector containing the quantum values the states.

Returns

  • This function does not return a value. It updates the nextStateTime vector in place.
source
QuantizedSystemSolver.nmisCycle_and_simulUpdateMethod
nmisCycle_and_simulUpdate(aij::Float64,aji::Float64,trackSimul,::Val{2},Val(M),index::Int,j::Int,dirI::Float64, x::Vector{Taylor0},q::Vector{Taylor0}, quantum::Vector{Float64},exactA::Function,d::Vector{Float64},cacheA::MVector{1,Float64},dxaux::Vector{MVector{2,Float64}},qaux::Vector{MVector{2,Float64}},tx::Vector{Float64},tq::Vector{Float64},simt::Float64,ft::Float64,f::F) where {M,F}

Performs a simultaneous update of two quantized variables qi and qj and their derivatives if cycle conditions are met. This is similar to the nmisCycle_and_simulUpdate order 1 function.

source

Index

diff --git a/dev/developer/solution/index.html b/dev/developer/solution/index.html index 6471b0c..bacd163 100644 --- a/dev/developer/solution/index.html +++ b/dev/developer/solution/index.html @@ -1,7 +1,7 @@ -Solution · Quantized System Solver

Solution

This is where the results of the simulation are stored, including: Settings, Time points (times[]), Variables (vars[]), Statistics (stats).

Problem extension

The Solution entity can be extended by subclassing:

QuantizedSystemSolver.SolType
Sol{T,O}

This is a superclass for all QSS solutions. It is parametric on:

  • The number of continuous variables T
  • The order of the algorithm O
source

What is needed with a new Solution:

Extending a solution is easier than extending the Problem and the Algorithm. Some cases are presented as follows:

  • Creating a new feature: no extra work is needed except the feature itself.
  • Creating a new solution similar to the LightSol: no extra work is needed except the definition of the new type subclassing Sol.
  • Creating a solution that differs from the LightSol: extend all functions that refer to fields that do not exist in the new type.

Example

struct HeavySol{T,O}<:Sol{T,O}
+Solution · Quantized System Solver

Solution

This is where the results of the simulation are stored, including: Settings, Time points (times[]), Variables (vars[]), Statistics (stats).

Problem extension

The Solution entity can be extended by subclassing:

QuantizedSystemSolver.SolType
Sol{T,O}

This is a superclass for all QSS solutions. It is parametric on:

  • The number of continuous variables T
  • The order of the algorithm O
source

What is needed with a new Solution:

Extending a solution is easier than extending the Problem and the Algorithm. Some cases are presented as follows:

  • Creating a new feature: no extra work is needed except the feature itself.
  • Creating a new solution similar to the LightSol: no extra work is needed except the definition of the new type subclassing Sol.
  • Creating a solution that differs from the LightSol: extend all functions that refer to fields that do not exist in the new type.

Example

struct HeavySol{T,O}<:Sol{T,O}
   size::Val{T}
   order::Val{O}
   savedTimes::Vector{Vector{Float64}}
   savedVars::Vector{Vector{Taylor0}}
-end

Here, the heavy solution contains all variables and their derivatives. The evaluateSol function can be reimplemented to use the derivatives for interpolation.

Define and create a solution

An implemented concrete solution type is:

QuantizedSystemSolver.LightSolType
LightSol{T,O}

A struct that holds the solution of a system of ODEs. It has the following fields:

  • size: The number of continuous variables T
  • order: The order of the algorithm O
  • savedTimes: A vector of vectors of Float64 that holds the times at which the continuous variables were saved
  • savedVars: A vector of vectors of Float64 that holds the values of the continuous variables at the times they were saved
  • algName: The name of the algorithm used to solve the system
  • sysName: The name of the system
  • absQ: The absolute tolerance used in the simulation
  • stats: A Stats struct that holds the statistics of the simulation
  • ft: The final time of the simulation
source
QuantizedSystemSolver.createSolMethod
createSol(::Val{T}, ::Val{O}, savedTimes::Vector{Vector{Float64}}, savedVars::Vector{Vector{Float64}}, solver::String, nameof_F::String, absQ::Float64, stats::Stats, ft::Float64) where {T,O}

Creates a LightSol struct with the given parameters.

Arguments

  • ::Val{T}: The number of continuous variables.
  • ::Val{O}: The order of the algorithm.
  • savedTimes::Vector{Vector{Float64}}: A vector of vectors of times at which the continuous variables were saved.
  • savedVars::Vector{Vector{Float64}}: A vector of vectors of values of the continuous variables at the times they were saved.
  • solver::String: The name of the algorithm used to solve the system.
  • nameof_F::String: The name of the system.
  • absQ::Float64: The absolute tolerance used in the simulation.
  • stats::Stats: A Stats struct that holds the statistics of the simulation.
  • ft::Float64: The final time of the simulation.

Returns

  • A LightSol struct.
source

Further reading

The solution Struct The LightSol struct is specifically designed to hold the solution of a system of ODEs. It contains several fields, including size and order, which denote the number of continuous variables and the order of the algorithm used, respectively. The savedTimes and savedVars fields are vectors that store the time steps and corresponding values of the continuous variables at which they were recorded during the simulation. Other fields include algName and sysName, which specify the names of the algorithm and system being solved, alongside absQ, the absolute tolerance used during the simulation. The stats field contains an instance of the Stats struct, providing access to the performance metrics, while ft holds the final time of the simulation. The Stats struct includes fields for totalSteps, which counts the total number of steps taken throughout the simulation, simulStepCount, representing the number of simultaneous updates during the simulation, and evCount, which tallies the number of events that occurred. Additionally, the numSteps vector keeps track of the number of steps taken for each continuous variable involved in the simulation, allowing for detailed analysis of the performance for individual components.

The functions defined in conjunction with these structs enable various operations related to the simulation's solutions. The createSol function initializes a LightSol instance with the specified parameters, while the getindex function provides a helper to access either the saved times or variables easily. The evaluateSol function allows for the evaluation of the solution at a specified time, supporting linear interpolation between saved points. Furthermore, the solInterpolated functions enable the generation of interpolated solutions across specified intervals, creating new solution objects based on the interpolated values and times. The show function is tailored to present the statistics in a user-friendly format, offering insights into the performance of the simulation. Overall, these constructs provide a robust framework for managing and analyzing the outcomes of simulations involving ODEs.

Plotting the Solution: The plotSol function is designed to visually represent the solution of a system of ODEs stored in the solution object. It accepts a variety of optional parameters, allowing users to customize their plots significantly. The function takes in a solution object sol along with indices for the variables to be plotted (xvars). Users can also specify a title, axis limits (xlims and ylims), and visual styles, such as marker types and whether to display a legend. If a title is not provided, it defaults to a composite of various parameters, including the system name, algorithm name, absolute tolerance, total steps taken, and more.Within the function, each selected variable is plotted against its corresponding saved time, utilizing different line styles for better distinction. If no specific variables are selected, all variables in the solution are plotted by default. After constructing the plot, the function checks for specified axis limits and applies them accordingly. Finally, the function returns the plot object, which can be further modified or saved. In addition to basic plotting, the saveSol function allows users to save their plots as PNG files, automatically generating filenames based on relevant parameters and timestamps. This functionality is crucial for documentation and sharing results in a reproducible manner. This comprehensive plotting capability ensures that users can effectively visualize the behavior of their systems, making the analysis of results intuitive and informative.

Finding the Error: The getError function computes the relative error of a solution compared to a specified reference function, enabling users to assess the accuracy of their numerical results. The function iterates over the saved time points, and it calculates the sum of the squares of the differences between the numerical solution and the true values provided by the reference function, as well as the sum of the squares of the true values. The relative error is then derived as the square root of the ratio of these sums, providing a quantitative measure of the solution's deviation from the expected results. This comprehensive error analysis is essential for validating the performance of numerical methods and ensuring that the solutions produced are both reliable and precise. By comparing the numerical results to known reference values, users can gain insights into the accuracy and effectiveness of the solver, enabling them to make informed decisions about their simulations and analyses.

+end

Here, the heavy solution contains all variables and their derivatives. The evaluateSol function can be reimplemented to use the derivatives for interpolation.

Define and create a solution

An implemented concrete solution type is:

QuantizedSystemSolver.LightSolType
LightSol{T,O}

A struct that holds the solution of a system of ODEs. It has the following fields:

  • size: The number of continuous variables T
  • order: The order of the algorithm O
  • savedTimes: A vector of vectors of Float64 that holds the times at which the continuous variables were saved
  • savedVars: A vector of vectors of Float64 that holds the values of the continuous variables at the times they were saved
  • algName: The name of the algorithm used to solve the system
  • sysName: The name of the system
  • absQ: The absolute tolerance used in the simulation
  • stats: A Stats struct that holds the statistics of the simulation
  • ft: The final time of the simulation
source
QuantizedSystemSolver.createSolMethod
createSol(::Val{T}, ::Val{O}, savedTimes::Vector{Vector{Float64}}, savedVars::Vector{Vector{Float64}}, solver::String, nameof_F::String, absQ::Float64, stats::Stats, ft::Float64) where {T,O}

Creates a LightSol struct with the given parameters.

Arguments

  • ::Val{T}: The number of continuous variables.
  • ::Val{O}: The order of the algorithm.
  • savedTimes::Vector{Vector{Float64}}: A vector of vectors of times at which the continuous variables were saved.
  • savedVars::Vector{Vector{Float64}}: A vector of vectors of values of the continuous variables at the times they were saved.
  • solver::String: The name of the algorithm used to solve the system.
  • nameof_F::String: The name of the system.
  • absQ::Float64: The absolute tolerance used in the simulation.
  • stats::Stats: A Stats struct that holds the statistics of the simulation.
  • ft::Float64: The final time of the simulation.

Returns

  • A LightSol struct.
source

Further reading

The solution Struct The LightSol struct is specifically designed to hold the solution of a system of ODEs. It contains several fields, including size and order, which denote the number of continuous variables and the order of the algorithm used, respectively. The savedTimes and savedVars fields are vectors that store the time steps and corresponding values of the continuous variables at which they were recorded during the simulation. Other fields include algName and sysName, which specify the names of the algorithm and system being solved, alongside absQ, the absolute tolerance used during the simulation. The stats field contains an instance of the Stats struct, providing access to the performance metrics, while ft holds the final time of the simulation. The Stats struct includes fields for totalSteps, which counts the total number of steps taken throughout the simulation, simulStepCount, representing the number of simultaneous updates during the simulation, and evCount, which tallies the number of events that occurred. Additionally, the numSteps vector keeps track of the number of steps taken for each continuous variable involved in the simulation, allowing for detailed analysis of the performance for individual components.

The functions defined in conjunction with these structs enable various operations related to the simulation's solutions. The createSol function initializes a LightSol instance with the specified parameters, while the getindex function provides a helper to access either the saved times or variables easily. The evaluateSol function allows for the evaluation of the solution at a specified time, supporting linear interpolation between saved points. Furthermore, the solInterpolated functions enable the generation of interpolated solutions across specified intervals, creating new solution objects based on the interpolated values and times. The show function is tailored to present the statistics in a user-friendly format, offering insights into the performance of the simulation. Overall, these constructs provide a robust framework for managing and analyzing the outcomes of simulations involving ODEs.

Plotting the Solution: The plotSol function is designed to visually represent the solution of a system of ODEs stored in the solution object. It accepts a variety of optional parameters, allowing users to customize their plots significantly. The function takes in a solution object sol along with indices for the variables to be plotted (xvars). Users can also specify a title, axis limits (xlims and ylims), and visual styles, such as marker types and whether to display a legend. If a title is not provided, it defaults to a composite of various parameters, including the system name, algorithm name, absolute tolerance, total steps taken, and more.Within the function, each selected variable is plotted against its corresponding saved time, utilizing different line styles for better distinction. If no specific variables are selected, all variables in the solution are plotted by default. After constructing the plot, the function checks for specified axis limits and applies them accordingly. Finally, the function returns the plot object, which can be further modified or saved. In addition to basic plotting, the saveSol function allows users to save their plots as PNG files, automatically generating filenames based on relevant parameters and timestamps. This functionality is crucial for documentation and sharing results in a reproducible manner. This comprehensive plotting capability ensures that users can effectively visualize the behavior of their systems, making the analysis of results intuitive and informative.

Finding the Error: The getError function computes the relative error of a solution compared to a specified reference function, enabling users to assess the accuracy of their numerical results. The function iterates over the saved time points, and it calculates the sum of the squares of the differences between the numerical solution and the true values provided by the reference function, as well as the sum of the squares of the true values. The relative error is then derived as the square root of the ratio of these sums, providing a quantitative measure of the solution's deviation from the expected results. This comprehensive error analysis is essential for validating the performance of numerical methods and ensuring that the solutions produced are both reliable and precise. By comparing the numerical results to known reference values, users can gain insights into the accuracy and effectiveness of the solver, enabling them to make informed decisions about their simulations and analyses.

diff --git a/dev/developer/solve/index.html b/dev/developer/solve/index.html index 5fe3493..865b692 100644 --- a/dev/developer/solve/index.html +++ b/dev/developer/solve/index.html @@ -1,2 +1,2 @@ -Solve · Quantized System Solver

Solve

The solve function is the primary interface for solving non-linear ODE problems using various QSS (Quantized State Systems) algorithms. It does this by dispatching on the problem and algorithm types to select the right solver.

Based on the QSS Algorithm provided, the solve function either selects a basic QSS integration method or, in the case of LiQSS, constructs additional data structures needed for implicit integration. The method defaults to sparse handling as false (Val(false)), tolerances (abstol=1e-4 and reltol=1e-3), and a maximum number of iterations (maxiters=1e7). These parameters can be adjusted based on the problem's complexity and desired accuracy. When a user doesn't provide a solver explicitly, the solve function defaults to using the modified second-order implicit algorith (mLiQSS2).

Helper Functions:

createCommonData: Sets up the common data required by the QSS solver. It initializes all necessary vectors (x, q, tx, tq, nextStateTime, etc.) used in the integration process, and it pre-allocates a cache of Taylor series to avoid repeated memory allocation during integration (taylorOpsCache).

getClosure: Creates a closure for the Jacobian and the dependency matrices, allowing in a flexible in a way that enables easy extension. The closure is used to access the Jacobian matrix during the integration process.

createLiqssData: For LiQSS solvers, this function sets up additional data structures and auxiliary variables used for storing linear approximation coefficients.

Internals

QuantizedSystemSolver.custom_SolveMethod
custom_Solve(prob::NLODEProblem{F,PRTYPE,T,D,Z,CS},al::QSSAlgorithm{Solver, Order},::Val{M},finalTime::Float64,saveat::Float64,initialTime::Float64,abstol::Float64,reltol::Float64,maxErr::Float64,maxiters::Int) where{F,PRTYPE,T,D,Z,CS,Solver,Order,M}

calls the integrator to solve the nonlinear ODE problem.

Arguments

  • prob::NLODEProblem{F,PRTYPE,T,D,Z,CS}: The nonlinear ODE problem to solve.
  • al::QSSAlgorithm{Solver, Order}: The QSS algorithm to use for solving the problem.
  • ::Val{M}: A type parameter indicating which detection mechanism to use.
  • finalTime::Float64: The final time for the simulation.
  • saveat::Float64: The time interval at which to save the solution.
  • initialTime::Float64: The initial time for the simulation.
  • abstol::Float64: The absolute tolerance for the solver.
  • reltol::Float64: The relative tolerance for the solver.
  • maxErr::Float64: The maximum allowable error.
  • maxiters::Int: The maximum number of iterations.
source
QuantizedSystemSolver.createCommonDataMethod
createCommonData(prob::NLODEProblem{F,PRTYPE,T,D,Z,CS},::Val{Order},finalTime::Float64,saveat::Float64,initialTime::Float64,abstol::Float64,reltol::Float64,maxErr::Float64,maxiters::Int) where{F,PRTYPE,T,D,Z,CS,Order}

creates the necessary data for the simulation and stores it in a CommonQSS_Data struct.

Arguments

  • prob::NLODEProblem{F,PRTYPE,T,D,Z,CS}: The nonlinear ODE problem to solve.
  • ::Val{Order}: The order of the algorithm.
  • finalTime::Float64: The final time for the simulation.
  • saveat::Float64: The time interval at which to save the solution.
  • initialTime::Float64: The initial time for the simulation.
  • abstol::Float64: The absolute tolerance for the solver.
  • reltol::Float64: The relative tolerance for the solver.
  • maxErr::Float64: The maximum allowable error.
  • maxiters::Int: The maximum number of iterations.

Returns

  • A data structure containing common data required for the QSS algorithm.
source
QuantizedSystemSolver.createLiqssDataMethod
createLiqssData(::Val{M},::Val{T},::Val{Order}) where {T,Order}

Creates LIQSS-specific data required for solving an ODE problem.

Arguments

  • ::Val{M}: A type parameter indicating which detection mechanism to use.
  • ::Val{T}: The number of continuous variables.
  • ::Val{Order}: The order of the algorithm.

Returns

  • A data structure containing LIQSS-specific data required for liQSS algorithms.
source
QuantizedSystemSolver.LiQSS_DataType
LiQSS_Data{O,M}

helper datastructures needed only for implicit case The field variables are:

  • cd::Val{M} #
  • cacheA::MVector{1,Float64}
  • qaux::Vector{MVector{O,Float64}}
  • dxaux::Vector{MVector{O,Float64}}
source
+Solve · Quantized System Solver

Solve

The solve function is the primary interface for solving non-linear ODE problems using various QSS (Quantized State Systems) algorithms. It does this by dispatching on the problem and algorithm types to select the right solver.

Based on the QSS Algorithm provided, the solve function either selects a basic QSS integration method or, in the case of LiQSS, constructs additional data structures needed for implicit integration. The method defaults to sparse handling as false (Val(false)), tolerances (abstol=1e-4 and reltol=1e-3), and a maximum number of iterations (maxiters=1e7). These parameters can be adjusted based on the problem's complexity and desired accuracy. When a user doesn't provide a solver explicitly, the solve function defaults to using the modified second-order implicit algorith (mLiQSS2).

Helper Functions:

createCommonData: Sets up the common data required by the QSS solver. It initializes all necessary vectors (x, q, tx, tq, nextStateTime, etc.) used in the integration process, and it pre-allocates a cache of Taylor series to avoid repeated memory allocation during integration (taylorOpsCache).

getClosure: Creates a closure for the Jacobian and the dependency matrices, allowing in a flexible in a way that enables easy extension. The closure is used to access the Jacobian matrix during the integration process.

createLiqssData: For LiQSS solvers, this function sets up additional data structures and auxiliary variables used for storing linear approximation coefficients.

Internals

QuantizedSystemSolver.custom_SolveMethod
custom_Solve(prob::NLODEProblem{F,PRTYPE,T,D,Z,CS},al::QSSAlgorithm{Solver, Order},::Val{M},finalTime::Float64,saveat::Float64,initialTime::Float64,abstol::Float64,reltol::Float64,maxErr::Float64,maxiters::Int) where{F,PRTYPE,T,D,Z,CS,Solver,Order,M}

calls the integrator to solve the nonlinear ODE problem.

Arguments

  • prob::NLODEProblem{F,PRTYPE,T,D,Z,CS}: The nonlinear ODE problem to solve.
  • al::QSSAlgorithm{Solver, Order}: The QSS algorithm to use for solving the problem.
  • ::Val{M}: A type parameter indicating which detection mechanism to use.
  • finalTime::Float64: The final time for the simulation.
  • saveat::Float64: The time interval at which to save the solution.
  • initialTime::Float64: The initial time for the simulation.
  • abstol::Float64: The absolute tolerance for the solver.
  • reltol::Float64: The relative tolerance for the solver.
  • maxErr::Float64: The maximum allowable error.
  • maxiters::Int: The maximum number of iterations.
source
QuantizedSystemSolver.createCommonDataMethod
createCommonData(prob::NLODEProblem{F,PRTYPE,T,D,Z,CS},::Val{Order},finalTime::Float64,saveat::Float64,initialTime::Float64,abstol::Float64,reltol::Float64,maxErr::Float64,maxiters::Int) where{F,PRTYPE,T,D,Z,CS,Order}

creates the necessary data for the simulation and stores it in a CommonQSS_Data struct.

Arguments

  • prob::NLODEProblem{F,PRTYPE,T,D,Z,CS}: The nonlinear ODE problem to solve.
  • ::Val{Order}: The order of the algorithm.
  • finalTime::Float64: The final time for the simulation.
  • saveat::Float64: The time interval at which to save the solution.
  • initialTime::Float64: The initial time for the simulation.
  • abstol::Float64: The absolute tolerance for the solver.
  • reltol::Float64: The relative tolerance for the solver.
  • maxErr::Float64: The maximum allowable error.
  • maxiters::Int: The maximum number of iterations.

Returns

  • A data structure containing common data required for the QSS algorithm.
source
QuantizedSystemSolver.createLiqssDataMethod
createLiqssData(::Val{M},::Val{T},::Val{Order}) where {T,Order}

Creates LIQSS-specific data required for solving an ODE problem.

Arguments

  • ::Val{M}: A type parameter indicating which detection mechanism to use.
  • ::Val{T}: The number of continuous variables.
  • ::Val{Order}: The order of the algorithm.

Returns

  • A data structure containing LIQSS-specific data required for liQSS algorithms.
source
QuantizedSystemSolver.LiQSS_DataType
LiQSS_Data{O,M}

helper datastructures needed only for implicit case The field variables are:

  • cd::Val{M} #
  • cacheA::MVector{1,Float64}
  • qaux::Vector{MVector{O,Float64}}
  • dxaux::Vector{MVector{O,Float64}}
source
diff --git a/dev/developer/taylor/index.html b/dev/developer/taylor/index.html index c58e4cf..4ead245 100644 --- a/dev/developer/taylor/index.html +++ b/dev/developer/taylor/index.html @@ -8,7 +8,7 @@ function addT(a::Taylor0, b::Taylor0, cache::Taylor0) @__dot__ cache.coeffs = (+)(a.coeffs, b.coeffs) return cache -end

The first function (+) from the TaylorSeries.jl creates a new Taylor variable every time, while the customized arithmetic operation addT uses an existing cache.

Taylor references

Taylor0 is defined for many functions. However, other functions can also be added.

QuantizedSystemSolver.Taylor0Type
Taylor0

defines a Taylor Variable. It has the following fields:

  • coeffs: An array of Float64 that holds the coefficients of the Taylor series
  • order: The order of the Taylor series
source

non-allocation operations

QuantizedSystemSolver.createTMethod
createT(a::Taylor0, cache::Taylor0)

puts the coefficients of a into cache and returns cache.

using QuantizedSystemSolver
+end

The first function (+) from the TaylorSeries.jl creates a new Taylor variable every time, while the customized arithmetic operation addT uses an existing cache.

Taylor references

Taylor0 is defined for many functions. However, other functions can also be added.

QuantizedSystemSolver.Taylor0Type
Taylor0

defines a Taylor Variable. It has the following fields:

  • coeffs: An array of Float64 that holds the coefficients of the Taylor series
  • order: The order of the Taylor series
source

non-allocation operations

QuantizedSystemSolver.createTMethod
createT(a::Taylor0, cache::Taylor0)

puts the coefficients of a into cache and returns cache.

using QuantizedSystemSolver
 a = Taylor0([1.0, 1.0])
 cache = Taylor0([0.0, 0.0])
 createT(a, cache)
@@ -16,6 +16,6 @@
 
 # output
 
-1.0
source
QuantizedSystemSolver.addsubMethod
addsub(a::Taylor0, b::Taylor0, c::T, cache::Taylor0) where {T<:Number}

Performs an addition and subtraction operation on Taylor series objects.

Arguments

  • a::Taylor0: The first Taylor series object.
  • b::Taylor0: The second Taylor series object.
  • c::T: A scalar value to be subtracted from the constant term of b.
  • cache::Taylor0: A Taylor series object used as a cache to store the result.

Returns

  • cache::Taylor0: The result of the operation, stored in the cache object.

Description

This function performs the following operations:

  1. Copies the coefficients of b into cache.
  2. Subtracts the scalar c from the constant term of cache.
  3. Adds the coefficients of a to cache.

The result is stored in the cache object and returned.

source
QuantizedSystemSolver.addsubMethod
addsub(a::T, b::Taylor0,c::Taylor0,cache::Taylor0) where {T<:Number}

Example:

Order2 case: cache=[a+b[0]-c[0],b[1]-c[1],b[2]-c[2]]

source
QuantizedSystemSolver.powerTMethod
powerT(a::T, r::S, cache1::Taylor0) where {S<:Real,T<:Number}

Raises a to the power r and stores the result in cache1.

Arguments

  • a::T: The base, a number.
  • r::S: The exponent, a real number.
  • cache1::Taylor0: The cache to store the result.

Returns

  • cache1::Taylor0: The result of a^r.
source
QuantizedSystemSolver.squareMethod
square(a::Taylor0, cache1::Taylor0)

Calculates the square of a and stores the result in cache1.

Arguments

  • a::Taylor0: The input Taylor series.
  • cache1::Taylor0: The cache to store the result.

Returns

  • cache1::Taylor0: The result of a^2.
source

non-allocation functions

Base.sqrtMethod
sqrt(a::Taylor0, cache1::Taylor0)

Calculates the square root of a and stores the result in cache1.

Arguments

  • a::Taylor0: The input Taylor series.
  • cache1::Taylor0: The cache to store the result.

Returns

  • cache1::Taylor0: The result of sqrt(a).
source
Base.sqrtMethod
sqrt(a::T, cache1::Taylor0) where {T<:Number}

Calculates the square root of a and stores the result in cache1.

Arguments

  • a::T: The input number.
  • cache1::Taylor0: The cache to store the result.

Returns

  • cache1::Taylor0: The result of sqrt(a).
source
Base.expMethod
exp(a::Taylor0, c::Taylor0)

Calculates the exponential of a and stores the result in c.

Arguments

  • a::Taylor0: The input Taylor series.
  • c::Taylor0: The cache to store the result.

Returns

  • c::Taylor0: The result of exp(a).
source
Base.expMethod
exp(a::T, c::Taylor0) where {T<:Number}

Calculates the exponential of a and stores the result in c.

Arguments

  • a::T: The input number.
  • c::Taylor0: The cache to store the result.

Returns

  • c::Taylor0: The result of exp(a).
source
Base.logMethod
log(a::Taylor0, c::Taylor0)

Compute the logarithm of a Taylor0 object a and stores the result in Taylor0 object c.

Arguments

  • a::Taylor0: The Taylor0 object for which the logarithm is to be computed.
  • c::Taylor0: to store the result

Returns

  • object c .
source
Base.sinMethod
sin(a::T, s::Taylor0, c::Taylor0) where {T<:Number}

Calculates the sine of the number a and stores the result in the Taylor series s.

Arguments

  • a::T: The input number.
  • s::Taylor0: The Taylor series to store the result.
  • c::Taylor0: An auxiliary Taylor series (not used in this function).

Returns

  • s::Taylor0: The result of sin(a).
source
Base.cosMethod
cos(a::T, s::Taylor0, c::Taylor0) where {T<:Number}

Calculates the cosine of the number a and stores the result in the Taylor series s.

Arguments

  • a::T: The input number.
  • s::Taylor0: The Taylor series to store the result.
  • c::Taylor0: An auxiliary Taylor series (not used in this function).

Returns

  • s::Taylor0: The result of cos(a).
source
Base.tanMethod
tan(a::Taylor0, c::Taylor0, c2::Taylor0)

Calculates the tangent of the Taylor series a and stores the result in c.

Arguments

  • a::Taylor0: The input Taylor series.
  • c::Taylor0: The Taylor series to store the result.
  • c2::Taylor0: An auxiliary Taylor series used in the calculation.

Returns

  • c::Taylor0: The result of tan(a).
source
Base.asinMethod
asin(a::Taylor0, c::Taylor0, r::Taylor0, cache3::Taylor0)

Calculates the arcsine of a and stores the result in c.

Arguments

  • a::Taylor0: The input Taylor series.
  • c::Taylor0: The cache to store the result.
  • r::Taylor0: An auxiliary Taylor series.
  • cache3::Taylor0: Another auxiliary Taylor series.

Returns

  • c::Taylor0: The result of acos(a).
source
Base.acosMethod
acos(a::Taylor0, c::Taylor0, r::Taylor0, cache3::Taylor0)

Calculates the arccosine of a and stores the result in c.

Arguments

  • a::Taylor0: The input Taylor series.
  • c::Taylor0: The cache to store the result.
  • r::Taylor0: An auxiliary Taylor series.
  • cache3::Taylor0: Another auxiliary Taylor series.

Returns

  • c::Taylor0: The result of acos(a).
source
Base.atanMethod
atan(a::Taylor0, c::Taylor0, r::Taylor0)

Calculates the arctangent of a and stores the result in c.

Arguments

  • a::Taylor0: The input Taylor series.
  • c::Taylor0: The cache to store the result.
  • r::Taylor0: An auxiliary Taylor series.

Returns

  • c::Taylor0: The result of atan(a).
source
Base.absMethod
abs(a::Taylor0, cache1::Taylor0)

Compute the absolute value of a Taylor0 object a and store the result in cache1.

Arguments

  • a::Taylor0: The input Taylor0 object whose absolute value is to be computed.
  • cache1::Taylor0: A Taylor0 object to store the result of the absolute value computation.

Returns

  • cache1::Taylor0: The Taylor0 object containing the absolute value of a.
source

Internals

All internals functions of the TaylorSeries.jl are used with the exception of the following two functions, which are rewritten to avoid one allocation.

QuantizedSystemSolver.asin!Function
asin!(c::Taylor0, a::Taylor0, r::Taylor0, cache3::Taylor0, k::Int)

Compute the arcsine of a Taylor series a and store the result in c. The computation uses intermediate results stored in r and cache3. The parameter k specifies the order of the Taylor series expansion. This is a copy of the function asin! as written in the package TaylorSeries.jl but with an added cache to avoid allocation.

Arguments

  • c::Taylor0: The Taylor series where the result will be stored.
  • a::Taylor0: The input Taylor series for which the arcsine is computed.
  • r::Taylor0: An intermediate Taylor series used in the computation.
  • cache3::Taylor0: Another intermediate Taylor series used in the computation to avoid one allocation of function square inside.
  • k::Int: The order of the Taylor series expansion.

Returns

  • nothing: The result of the arcsine computation stored in c.
source
QuantizedSystemSolver.acos!Function
    acos!(c::Taylor0, a::Taylor0, r::Taylor0, cache3::Taylor0, k::Int)

Compute the arccosine of a Taylor series a and store the result in c. The computation uses intermediate results stored in r and cache3. The parameter k specifies the order of the Taylor series expansion. This is a copy of the function acos! as written in the package TaylorSeries.jl but with an added cache to avoid one allocation.

Arguments

  • c::Taylor0: The Taylor series where the result will be stored.
  • a::Taylor0: The input Taylor series for which the arcsine is computed.
  • r::Taylor0: An intermediate Taylor series used in the computation.
  • cache3::Taylor0: Another intermediate Taylor series used in the computation to avoid allocation of function square inside.
  • k::Int: The order of the Taylor series expansion.

Returns

  • nothing: The result of the arcsine computation stored in c.
source
Allocating TaylorSeries functions

As a fallback all TaylorSeries functions are used in case an expression is not transformed to one of the existing personalized functions above.

Index

+creates a Taylor0 from a constant. In case of order 2, cache=[a,0,0]source
QuantizedSystemSolver.addTMethod
addT(a::Taylor0, b::Taylor0,cache::Taylor0)

cache=a+b

source
QuantizedSystemSolver.subTMethod
subT(a::Taylor0, b::Taylor0,cache::Taylor0)

cache=a-b

source
QuantizedSystemSolver.mulTMethod
mulT(a::Taylor0, b::Taylor0,cache1::Taylor0)

cache1=a*b

source
QuantizedSystemSolver.divTMethod
divT(a::Taylor0, b::Taylor0,cache1::Taylor0)

cache1=a/b

source
QuantizedSystemSolver.addsubMethod
addsub(a::Taylor0, b::Taylor0,c::Taylor0,cache::Taylor0)

cache=a+b-c

source
QuantizedSystemSolver.addsubMethod
addsub(a::Taylor0, b::Taylor0, c::T, cache::Taylor0) where {T<:Number}

Performs an addition and subtraction operation on Taylor series objects.

Arguments

  • a::Taylor0: The first Taylor series object.
  • b::Taylor0: The second Taylor series object.
  • c::T: A scalar value to be subtracted from the constant term of b.
  • cache::Taylor0: A Taylor series object used as a cache to store the result.

Returns

  • cache::Taylor0: The result of the operation, stored in the cache object.

Description

This function performs the following operations:

  1. Copies the coefficients of b into cache.
  2. Subtracts the scalar c from the constant term of cache.
  3. Adds the coefficients of a to cache.

The result is stored in the cache object and returned.

source
QuantizedSystemSolver.addsubMethod
addsub(a::T, b::Taylor0,c::Taylor0,cache::Taylor0) where {T<:Number}

Example:

Order2 case: cache=[a+b[0]-c[0],b[1]-c[1],b[2]-c[2]]

source
QuantizedSystemSolver.subsubMethod
subsub(a::Taylor0, b::Taylor0,c::Taylor0,cache::Taylor0)

cache=a-b-c

source
QuantizedSystemSolver.mulsubMethod
mulsub(a::P,b::Q,c::R,cache1::Taylor0) where {P,Q,R <:Union{Taylor0,Number}}

cache1=a*b-c

source
QuantizedSystemSolver.muladdTMethod
muladdT(a::P,b::Q,c::R,cache1::Taylor0) where {P,Q,R <:Union{Taylor0,Number}}

cache1=a*b+c

source
QuantizedSystemSolver.negateTMethod
negateT(a::Taylor0,cache::Taylor0)

cache=-a

source
QuantizedSystemSolver.powerTMethod
powerT(a::T, r::S, cache1::Taylor0) where {S<:Real,T<:Number}

Raises a to the power r and stores the result in cache1.

Arguments

  • a::T: The base, a number.
  • r::S: The exponent, a real number.
  • cache1::Taylor0: The cache to store the result.

Returns

  • cache1::Taylor0: The result of a^r.
source
QuantizedSystemSolver.squareMethod
square(a::Taylor0, cache1::Taylor0)

Calculates the square of a and stores the result in cache1.

Arguments

  • a::Taylor0: The input Taylor series.
  • cache1::Taylor0: The cache to store the result.

Returns

  • cache1::Taylor0: The result of a^2.
source

non-allocation functions

Base.sqrtMethod
sqrt(a::Taylor0, cache1::Taylor0)

Calculates the square root of a and stores the result in cache1.

Arguments

  • a::Taylor0: The input Taylor series.
  • cache1::Taylor0: The cache to store the result.

Returns

  • cache1::Taylor0: The result of sqrt(a).
source
Base.sqrtMethod
sqrt(a::T, cache1::Taylor0) where {T<:Number}

Calculates the square root of a and stores the result in cache1.

Arguments

  • a::T: The input number.
  • cache1::Taylor0: The cache to store the result.

Returns

  • cache1::Taylor0: The result of sqrt(a).
source
Base.expMethod
exp(a::Taylor0, c::Taylor0)

Calculates the exponential of a and stores the result in c.

Arguments

  • a::Taylor0: The input Taylor series.
  • c::Taylor0: The cache to store the result.

Returns

  • c::Taylor0: The result of exp(a).
source
Base.expMethod
exp(a::T, c::Taylor0) where {T<:Number}

Calculates the exponential of a and stores the result in c.

Arguments

  • a::T: The input number.
  • c::Taylor0: The cache to store the result.

Returns

  • c::Taylor0: The result of exp(a).
source
Base.logMethod
log(a::Taylor0, c::Taylor0)

Compute the logarithm of a Taylor0 object a and stores the result in Taylor0 object c.

Arguments

  • a::Taylor0: The Taylor0 object for which the logarithm is to be computed.
  • c::Taylor0: to store the result

Returns

  • object c .
source
Base.sinMethod
sin(a::T, s::Taylor0, c::Taylor0) where {T<:Number}

Calculates the sine of the number a and stores the result in the Taylor series s.

Arguments

  • a::T: The input number.
  • s::Taylor0: The Taylor series to store the result.
  • c::Taylor0: An auxiliary Taylor series (not used in this function).

Returns

  • s::Taylor0: The result of sin(a).
source
Base.cosMethod
cos(a::T, s::Taylor0, c::Taylor0) where {T<:Number}

Calculates the cosine of the number a and stores the result in the Taylor series s.

Arguments

  • a::T: The input number.
  • s::Taylor0: The Taylor series to store the result.
  • c::Taylor0: An auxiliary Taylor series (not used in this function).

Returns

  • s::Taylor0: The result of cos(a).
source
Base.tanMethod
tan(a::Taylor0, c::Taylor0, c2::Taylor0)

Calculates the tangent of the Taylor series a and stores the result in c.

Arguments

  • a::Taylor0: The input Taylor series.
  • c::Taylor0: The Taylor series to store the result.
  • c2::Taylor0: An auxiliary Taylor series used in the calculation.

Returns

  • c::Taylor0: The result of tan(a).
source
Base.asinMethod
asin(a::Taylor0, c::Taylor0, r::Taylor0, cache3::Taylor0)

Calculates the arcsine of a and stores the result in c.

Arguments

  • a::Taylor0: The input Taylor series.
  • c::Taylor0: The cache to store the result.
  • r::Taylor0: An auxiliary Taylor series.
  • cache3::Taylor0: Another auxiliary Taylor series.

Returns

  • c::Taylor0: The result of acos(a).
source
Base.acosMethod
acos(a::Taylor0, c::Taylor0, r::Taylor0, cache3::Taylor0)

Calculates the arccosine of a and stores the result in c.

Arguments

  • a::Taylor0: The input Taylor series.
  • c::Taylor0: The cache to store the result.
  • r::Taylor0: An auxiliary Taylor series.
  • cache3::Taylor0: Another auxiliary Taylor series.

Returns

  • c::Taylor0: The result of acos(a).
source
Base.atanMethod
atan(a::Taylor0, c::Taylor0, r::Taylor0)

Calculates the arctangent of a and stores the result in c.

Arguments

  • a::Taylor0: The input Taylor series.
  • c::Taylor0: The cache to store the result.
  • r::Taylor0: An auxiliary Taylor series.

Returns

  • c::Taylor0: The result of atan(a).
source
Base.absMethod
abs(a::Taylor0, cache1::Taylor0)

Compute the absolute value of a Taylor0 object a and store the result in cache1.

Arguments

  • a::Taylor0: The input Taylor0 object whose absolute value is to be computed.
  • cache1::Taylor0: A Taylor0 object to store the result of the absolute value computation.

Returns

  • cache1::Taylor0: The Taylor0 object containing the absolute value of a.
source

Internals

All internals functions of the TaylorSeries.jl are used with the exception of the following two functions, which are rewritten to avoid one allocation.

QuantizedSystemSolver.asin!Function
asin!(c::Taylor0, a::Taylor0, r::Taylor0, cache3::Taylor0, k::Int)

Compute the arcsine of a Taylor series a and store the result in c. The computation uses intermediate results stored in r and cache3. The parameter k specifies the order of the Taylor series expansion. This is a copy of the function asin! as written in the package TaylorSeries.jl but with an added cache to avoid allocation.

Arguments

  • c::Taylor0: The Taylor series where the result will be stored.
  • a::Taylor0: The input Taylor series for which the arcsine is computed.
  • r::Taylor0: An intermediate Taylor series used in the computation.
  • cache3::Taylor0: Another intermediate Taylor series used in the computation to avoid one allocation of function square inside.
  • k::Int: The order of the Taylor series expansion.

Returns

  • nothing: The result of the arcsine computation stored in c.
source
QuantizedSystemSolver.acos!Function
    acos!(c::Taylor0, a::Taylor0, r::Taylor0, cache3::Taylor0, k::Int)

Compute the arccosine of a Taylor series a and store the result in c. The computation uses intermediate results stored in r and cache3. The parameter k specifies the order of the Taylor series expansion. This is a copy of the function acos! as written in the package TaylorSeries.jl but with an added cache to avoid one allocation.

Arguments

  • c::Taylor0: The Taylor series where the result will be stored.
  • a::Taylor0: The input Taylor series for which the arcsine is computed.
  • r::Taylor0: An intermediate Taylor series used in the computation.
  • cache3::Taylor0: Another intermediate Taylor series used in the computation to avoid allocation of function square inside.
  • k::Int: The order of the Taylor series expansion.

Returns

  • nothing: The result of the arcsine computation stored in c.
source
Allocating TaylorSeries functions

As a fallback all TaylorSeries functions are used in case an expression is not transformed to one of the existing personalized functions above.

Index

diff --git a/dev/developer/utils/index.html b/dev/developer/utils/index.html index 83e9a57..2ecd91b 100644 --- a/dev/developer/utils/index.html +++ b/dev/developer/utils/index.html @@ -1,2 +1,2 @@ -Utils references · Quantized System Solver

Utils references

Root finding

These methods find the minimum positive root of a linear and quadratic equations for order 1 and 2 respectively. For order 3, similar methods should be added to solve the cubic equation.

QuantizedSystemSolver.minPosRootMethod
minPosRoot(c::Float64,b::Float64, ::Val{1})

Finds the minimum positive root for a linear equation represented by the coefficients.

Returns

  • The minimum positive root of the linear equation.
source
QuantizedSystemSolver.minPosRootMethod
minPosRoot(c::Float64,b::Float64,a::Float64,::Val{2})

Finds the minimum positive root for a quadratic equation represented by the coefficients.

Returns

  • The minimum positive root of the quadratic equation.
source
QuantizedSystemSolver.minPosRootMethod
minPosRoot(coeff::Taylor0, ::Val{1})

Finds the minimum positive root for a linear equation represented by the Taylor series coefficients.

Arguments

  • coeff::Taylor0: The Taylor series coefficients of the linear equation.
  • ::Val{1}: A type parameter indicating the order.

Returns

  • The minimum positive root of the linear equation.
source
QuantizedSystemSolver.minPosRootMethod
minPosRoot(coeff::Taylor0, ::Val{2})

Finds the minimum positive root for a quadratic equation represented by the Taylor series coefficients.

Arguments

  • coeff::Taylor0: The Taylor series coefficients of the quadratic equation.
  • ::Val{2}: A type parameter indicating the order.

Returns

  • The minimum positive root of the quadratic equation.
source

Scheduler

The scheduler component retrieves the next index (a state change or an event) for processing. It determines the next action by comparing three types of timing events: state updates, events, and input updates. It initializes minimum time variables for each action type to infinity and iterates through the provided vectors to find the minimum times and their corresponding indices. Based on these comparisons, it decides whether the next scheduled action is an input update, an event, or a state update. If no valid actions are found (indicated by a zero index), the function assigns a default state indicating the next action is a state update at time infinity. Finally, it returns a tuple containing the index of the next action, its time, and a symbol representing the type of action to take next (:STINPUT, :STEVENT, or :STSTATE). This structure ensures that the simulation progresses accurately and efficiently.

QuantizedSystemSolver.updateSchedulerMethod
updateScheduler(::Val{T}, nextStateTime::Vector{Float64}, nextEventTime::MVector{Z,Float64}, nextInputTime::Vector{Float64}) where {T, Z}

Updates the scheduler by finding the minimum times among state, event, and input transitions.

Arguments

  • ::Val{T}: A type parameter indicating the number of state transitions.
  • nextStateTime::Vector{Float64}: A vector of times for the next state transitions.
  • nextEventTime::MVector{Z,Float64}: A mutable vector of times for the next event transitions.
  • nextInputTime::Vector{Float64}: A vector of times for the next input transitions.

Returns

  • A tuple containing the minimum (state index,state time), (event index, event tim, or (input index, input time).
source
+Utils references · Quantized System Solver

Utils references

Root finding

These methods find the minimum positive root of a linear and quadratic equations for order 1 and 2 respectively. For order 3, similar methods should be added to solve the cubic equation.

QuantizedSystemSolver.minPosRootMethod
minPosRoot(c::Float64,b::Float64, ::Val{1})

Finds the minimum positive root for a linear equation represented by the coefficients.

Returns

  • The minimum positive root of the linear equation.
source
QuantizedSystemSolver.minPosRootMethod
minPosRoot(c::Float64,b::Float64,a::Float64,::Val{2})

Finds the minimum positive root for a quadratic equation represented by the coefficients.

Returns

  • The minimum positive root of the quadratic equation.
source
QuantizedSystemSolver.minPosRootMethod
minPosRoot(coeff::Taylor0, ::Val{1})

Finds the minimum positive root for a linear equation represented by the Taylor series coefficients.

Arguments

  • coeff::Taylor0: The Taylor series coefficients of the linear equation.
  • ::Val{1}: A type parameter indicating the order.

Returns

  • The minimum positive root of the linear equation.
source
QuantizedSystemSolver.minPosRootMethod
minPosRoot(coeff::Taylor0, ::Val{2})

Finds the minimum positive root for a quadratic equation represented by the Taylor series coefficients.

Arguments

  • coeff::Taylor0: The Taylor series coefficients of the quadratic equation.
  • ::Val{2}: A type parameter indicating the order.

Returns

  • The minimum positive root of the quadratic equation.
source

Scheduler

The scheduler component retrieves the next index (a state change or an event) for processing. It determines the next action by comparing three types of timing events: state updates, events, and input updates. It initializes minimum time variables for each action type to infinity and iterates through the provided vectors to find the minimum times and their corresponding indices. Based on these comparisons, it decides whether the next scheduled action is an input update, an event, or a state update. If no valid actions are found (indicated by a zero index), the function assigns a default state indicating the next action is a state update at time infinity. Finally, it returns a tuple containing the index of the next action, its time, and a symbol representing the type of action to take next (:STINPUT, :STEVENT, or :STSTATE). This structure ensures that the simulation progresses accurately and efficiently.

QuantizedSystemSolver.updateSchedulerMethod
updateScheduler(::Val{T}, nextStateTime::Vector{Float64}, nextEventTime::MVector{Z,Float64}, nextInputTime::Vector{Float64}) where {T, Z}

Updates the scheduler by finding the minimum times among state, event, and input transitions.

Arguments

  • ::Val{T}: A type parameter indicating the number of state transitions.
  • nextStateTime::Vector{Float64}: A vector of times for the next state transitions.
  • nextEventTime::MVector{Z,Float64}: A mutable vector of times for the next event transitions.
  • nextInputTime::Vector{Float64}: A vector of times for the next input transitions.

Returns

  • A tuple containing the minimum (state index,state time), (event index, event tim, or (input index, input time).
source
diff --git a/dev/examples/adr/index.html b/dev/examples/adr/index.html index c9a355e..ecd4b88 100644 --- a/dev/examples/adr/index.html +++ b/dev/examples/adr/index.html @@ -44,4 +44,4 @@ end BSON.@load "test/solVectAdvection_N1000d01_Feagin14e-12.bson" solFeagin14VectorN1000d01 sol=solve(odeprob,ImplicitEuler(),saveat=0.01,abstol=1e-2,reltol=1e-1) -err2=getAverageErrorByRefs(sol.u,solFeagin14VectorN1000d01,1000,1000)

References

[1] F. Bergero, J. Fernandez, E. Kofman, and M. Portapila. Time discretization versus state ´ quantization in the simulation of a 1d advection-diffusion-reaction equation. Simulation: Transactions of the Society for Modeling and Simulation International, vol.92(no.1):pp.47– 61, 2016.

[2] F. Pietro, G. Migoni, and E. Kofman. Improving linearly implicit quantized state system methods. Simulation: Transactions of the Society for Modeling and Simulation International, vol.95(no.2):pp.127–144, 2019.

+err2=getAverageErrorByRefs(sol.u,solFeagin14VectorN1000d01,1000,1000)

References

[1] F. Bergero, J. Fernandez, E. Kofman, and M. Portapila. Time discretization versus state ´ quantization in the simulation of a 1d advection-diffusion-reaction equation. Simulation: Transactions of the Society for Modeling and Simulation International, vol.92(no.1):pp.47– 61, 2016.

[2] F. Pietro, G. Migoni, and E. Kofman. Improving linearly implicit quantized state system methods. Simulation: Transactions of the Society for Modeling and Simulation International, vol.95(no.2):pp.127–144, 2019.

diff --git a/dev/examples/dosing/index.html b/dev/examples/dosing/index.html index 3ced888..d0bc9c5 100644 --- a/dev/examples/dosing/index.html +++ b/dev/examples/dosing/index.html @@ -34,4 +34,4 @@ @btime sol=solve($odeprob,Rosenbrock23(),abstol=1e-3,reltol=1e-2) #22.500 μs (251 allocations: 16.89 KiB) @btime sol=solve($odeprob,Tsit5(),abstol=1e-3,reltol=1e-2) -#7.775 μs (165 allocations: 12.33 KiB) +#7.775 μs (165 allocations: 12.33 KiB) diff --git a/dev/examples/linearTimeInvariantSystem/index.html b/dev/examples/linearTimeInvariantSystem/index.html index 7b9a2f4..aa97547 100644 --- a/dev/examples/linearTimeInvariantSystem/index.html +++ b/dev/examples/linearTimeInvariantSystem/index.html @@ -29,4 +29,4 @@ # output (843, 833, 84) - + diff --git a/dev/examples/linearTimeInvariantSystemEvents/index.html b/dev/examples/linearTimeInvariantSystemEvents/index.html index 2c973c7..b102c24 100644 --- a/dev/examples/linearTimeInvariantSystemEvents/index.html +++ b/dev/examples/linearTimeInvariantSystemEvents/index.html @@ -82,4 +82,4 @@ cb2 = ContinuousCallback(condition2, affect2!,nothing; ) cbs = CallbackSet(cb1, cb2) solRosenbrock23 = solve(prob,Rosenbrock23(),callback = cbs,abstol = 1e-4, reltol = 1e-2) -p1=plot!(solRosenbrock23,title="Rosenbrock23")

The plots are displayed below:

LTI with events using QuantizedSystemSolver.jl

LTI_events plot with nmliqss2

LTI with events using DifferentialEquation.jl

LTI_events plot with Rosenbrock23

LTI with events using the analytic solution

LTI_events Analytic plot

+p1=plot!(solRosenbrock23,title="Rosenbrock23")

The plots are displayed below:

LTI with events using QuantizedSystemSolver.jl

LTI_events plot with nmliqss2

LTI with events using DifferentialEquation.jl

LTI_events plot with Rosenbrock23

LTI with events using the analytic solution

LTI_events Analytic plot

diff --git a/dev/examples/tysonModel/index.html b/dev/examples/tysonModel/index.html index b5a5f3a..bca41f8 100644 --- a/dev/examples/tysonModel/index.html +++ b/dev/examples/tysonModel/index.html @@ -22,4 +22,4 @@ #Solve the problem sol=solve(odeprob,nmliqss2()) p1=plot(sol); -savefig(p1, "tyson_$(nmliqss2())")

Replace nmliqss2 by ABDF2() from the DifferentialEquations.jl, to obtain the following plots.

plot_tyson_nmliqss2 plot_tyson_abdf

References

[1] J. Tyson. Modeling the cell division cycle: cdc2 and cyclin interactions. Proceedings of the National Academy of Sciences, vol.88:pp.7328–7332, 1991.

[2] F. Pietro, G. Migoni, and E. Kofman. Improving linearly implicit quantized state system methods. Simulation: Transactions of the Society for Modeling and Simulation International, vol.95(no.2):pp.127–144, 2019.

+savefig(p1, "tyson_$(nmliqss2())")

Replace nmliqss2 by ABDF2() from the DifferentialEquations.jl, to obtain the following plots.

plot_tyson_nmliqss2 plot_tyson_abdf

References

[1] J. Tyson. Modeling the cell division cycle: cdc2 and cyclin interactions. Proceedings of the National Academy of Sciences, vol.88:pp.7328–7332, 1991.

[2] F. Pietro, G. Migoni, and E. Kofman. Improving linearly implicit quantized state system methods. Simulation: Transactions of the Society for Modeling and Simulation International, vol.95(no.2):pp.127–144, 2019.

diff --git a/dev/examples/vanderpol/index.html b/dev/examples/vanderpol/index.html index 793f78b..830249c 100644 --- a/dev/examples/vanderpol/index.html +++ b/dev/examples/vanderpol/index.html @@ -13,4 +13,4 @@ #Solve the problem sol=solve(odeprob,nmliqss2()) p1=plot(sol); -savefig(p1, "vanderpol_$(nmliqss2())")

Replace nmliqss2 by ABDF2() from the DifferentialEquations.jl, to obtain the following plots.

plot_vanderpol_nmliqss2 plot_vanderpol_nmliqss2

Variable 2 can viewed wrt variable 1 using:

p1=plot(sol,idxs=(1,2),title="...");

plot_vanderpol_nmliqss2 plot_vanderpol_nmliqss2

+savefig(p1, "vanderpol_$(nmliqss2())")

Replace nmliqss2 by ABDF2() from the DifferentialEquations.jl, to obtain the following plots.

plot_vanderpol_nmliqss2 plot_vanderpol_nmliqss2

Variable 2 can viewed wrt variable 1 using:

p1=plot(sol,idxs=(1,2),title="...");

plot_vanderpol_nmliqss2 plot_vanderpol_nmliqss2

diff --git a/dev/guide/userAPI/index.html b/dev/guide/userAPI/index.html index c839b53..8c10658 100644 --- a/dev/guide/userAPI/index.html +++ b/dev/guide/userAPI/index.html @@ -1,12 +1,12 @@ -User API · Quantized System Solver

User API

Problem definition

QuantizedSystemSolver.ODEProblemMethod
ODEProblem(f::Function, u::Vector{Float64}, tspan::Tuple{Float64,Float64}, p::Union{Vector{EM}, Tuple{Vararg{EM}}}) where{EM}

Creates an ODE problem with the given function f, initial conditions u, parameters p, and time span tspan.

Arguments

  • f::Function: The function defining the ODE.
  • u::Vector{Float64}: The initial conditions.
  • p::Vector{Float64}: The parameters.
  • tspan::Tuple{Float64,Float64}: The time span for the ODE.

Returns

  • An ODE problem.
source
QuantizedSystemSolver.ODEProblemMethod
ODEProblem(f::Function, u::Vector{Float64}, tspan::Tuple{Float64,Float64})

Creates an ODE problem with the given function f, initial conditions u, and time span tspan.

Arguments

  • f::Function: The function defining the ODE.
  • u::Vector{Float64}: The initial conditions.
  • tspan::Tuple{Float64,Float64}: The time span for the ODE.

Returns

  • An ODE problem.
source

The solve function:

QuantizedSystemSolver.solveMethod
solve(prob::NLODEProblem{F,PRTYPE,T,D,Z,CS},al::QSSAlgorithm{SolverType, OrderType};detection::Val{M}=Val(3),saveat=Inf::Float64,abstol=1e-3::Float64,reltol=1e-2::Float64,maxErr=Inf::Float64,maxiters=Int(1e7)::Int) where{F,PRTYPE,T,D,Z,CS,SolverType,OrderType,M}

dispatches on a specific integrator based on the algorithm provided and send a nonlinear ODE problem to the integrator.

Arguments

  • prob::NLODEProblem{F,PRTYPE,T,D,Z,CS}: The nonlinear ODE problem to solve.
  • al::QSSAlgorithm{SolverType, OrderType}: The QSS algorithm to use for solving the problem.
  • detection::Val{M}: A type parameter indicating which detection mechanism to use.
  • saveat::Float64: The time interval at which to save the solution (default: Inf).
  • abstol::Float64: The absolute tolerance for the solver (default: 1e-3).
  • reltol::Float64: The relative tolerance for the solver (default: 1e-2).
  • maxErr::Float64: The maximum allowable error (default: Inf).
  • maxiters::Int: The maximum number of iterations (default: Int(1e7)).
source
QuantizedSystemSolver.solveMethod
solve(prob::NLODEProblem{F,PRTYPE,T,D,Z,CS},al::QSSAlgorithm{SolverType, OrderType},tspan::Tuple{Float64, Float64};detection::Val{M}=Val(3),saveat=Inf::Float64,abstol=1e-3::Float64,reltol=1e-2::Float64,maxErr=Inf::Float64,maxiters=Int(1e7)::Int) where{F,PRTYPE,T,D,Z,CS,SolverType,OrderType,M}

dispatches on a specific integrator based on the algorithm provided and send a nonlinear ODE problem to the integrator.

With the exception of the argument prob and tspan, all other arguments are optional and have default values:

  • The algorithm defaults to nmliqss2, and it is specified by the QSSAlgorithm type, which is a composite type that has a name and an order. It can be extended independently of the solver.
  • The detection argument defaults to 1.
  • The saveat argument defaults to Inf. It specifies the time step at which the integrator will save the solution (not implemented).
  • The abstol argument defaults to 1e-3. It specifies the absolute tolerance of the integrator.
  • The reltol argument defaults to 1e-2. It specifies the relative tolerance of the integrator.
  • The maxErr argument defaults to Inf. It specifies the maximum error allowed by the integrator. This is used as an upper bound for the quantum when a variable goes large.
  • The maxiters argument defaults to 1e7. It specifies the maximum number of steps allowed by the integrator. If the user wants to extend the limit on the maximum number of steps, this argument can be used.

After the simulation, the solution is returned as a Solution object.

source

Algorithms

QuantizedSystemSolver.nmliqss1Method
nmliqss1()

calls the modified imlicit quantized state system solver with order 1. It is efficient when the system contains large entries outside the main diagonal of the Jacobian .

source
QuantizedSystemSolver.nmliqss2Method
nmliqss2()

calls the modified imlicit quantized state system solver with order 2. It is efficient when the system contains large entries outside the main diagonal of the Jacobian .

source

Solution

Query a solution

QuantizedSystemSolver.evaluateSolMethod
evaluateSol(sol::Sol{T,O}, index::Int, t::Float64) where {T,O}

Evaluates the solution at a given time t for a specified variable index.

Arguments

  • sol::Sol{T,O}: The solution struct.
  • index::Int: The index of the variable to evaluate. If index is 0, evaluates all variables.
  • t::Float64: The time at which to evaluate the solution.

Returns

  • The value of the specified variable at time t, or a vector of values if index is 0.

Throws

  • An error if the given time t is outside the solution range.
source
QuantizedSystemSolver.solInterpolatedMethod
solInterpolated(sol::Sol{T,O},step::Float64) where {T,O}

Construct a new solution by interpolating the current solution at each step for all variables.

Arguments

  • sol::Sol{T,O}: The solution struct.
  • step::Float64: the step size at which to generate the new solution.

Returns

  • A new solution that contains information at each step size..
source
QuantizedSystemSolver.solInterpolatedMethod
solInterpolated(sol::Sol{T,O},index::Int,step::Float64) where {T,O}

Constructs a new solution by interpolating the current solution at each step for one variable.

Arguments

  • sol::Sol{T,O}: The solution struct.
  • index::Int: the index of the variable to interpolate.
  • step::Float64: the step size at which to generate the new solution.

Returns

  • A new solution that contains the information of one variable at each step size.
source
Base.showMethod
show(io::IO, a::Stats)

Displays the statistics of the simulation.

Arguments

  • io::IO: The IO stream to write to.
  • a::Stats: The Stats struct containing the simulation statistics.

Prints

  • The total simulation steps.
  • The simultaneous steps.
  • The number of events.
source
QuantizedSystemSolver.StatsType
Stats

A struct that holds the statistics of a simulation. It has the following fields:

  • totalSteps::Int: The total number of simulation steps.
  • simulStepCount::Int: The number of simultaneous steps.
  • evCount::Int: The number of events.
  • numSteps::Vector{Int}: A vector holding the number of steps for each variable.
source

Error with respect to an analytic or reference solution

Finding the error

To find the error, an interpolated solution has to be used as shown in solInterpolated. The reference solution (using saveat for example) and the interpolated solution (passed step to interpolated function) must have the same tspan and the same step size.

QuantizedSystemSolver.getErrorMethod
getError(sol::Sol{T,O},index::Int,f::Function) where{T,O}

calculates the relative error of one variable of the solution with respect to a function of an analytic solution.

\[\begin{equation*} +User API · Quantized System Solver

User API

Problem definition

QuantizedSystemSolver.ODEProblemMethod
ODEProblem(f::Function, u::Vector{Float64}, tspan::Tuple{Float64,Float64}, p::Union{Vector{EM}, Tuple{Vararg{EM}}}) where{EM}

Creates an ODE problem with the given function f, initial conditions u, parameters p, and time span tspan.

Arguments

  • f::Function: The function defining the ODE.
  • u::Vector{Float64}: The initial conditions.
  • p::Vector{Float64}: The parameters.
  • tspan::Tuple{Float64,Float64}: The time span for the ODE.

Returns

  • An ODE problem.
source
QuantizedSystemSolver.ODEProblemMethod
ODEProblem(f::Function, u::Vector{Float64}, tspan::Tuple{Float64,Float64})

Creates an ODE problem with the given function f, initial conditions u, and time span tspan.

Arguments

  • f::Function: The function defining the ODE.
  • u::Vector{Float64}: The initial conditions.
  • tspan::Tuple{Float64,Float64}: The time span for the ODE.

Returns

  • An ODE problem.
source

The solve function:

QuantizedSystemSolver.solveMethod
solve(prob::NLODEProblem{F,PRTYPE,T,D,Z,CS},al::QSSAlgorithm{SolverType, OrderType};detection::Val{M}=Val(3),saveat=Inf::Float64,abstol=1e-3::Float64,reltol=1e-2::Float64,maxErr=Inf::Float64,maxiters=Int(1e7)::Int) where{F,PRTYPE,T,D,Z,CS,SolverType,OrderType,M}

dispatches on a specific integrator based on the algorithm provided and send a nonlinear ODE problem to the integrator.

Arguments

  • prob::NLODEProblem{F,PRTYPE,T,D,Z,CS}: The nonlinear ODE problem to solve.
  • al::QSSAlgorithm{SolverType, OrderType}: The QSS algorithm to use for solving the problem.
  • detection::Val{M}: A type parameter indicating which detection mechanism to use.
  • saveat::Float64: The time interval at which to save the solution (default: Inf).
  • abstol::Float64: The absolute tolerance for the solver (default: 1e-3).
  • reltol::Float64: The relative tolerance for the solver (default: 1e-2).
  • maxErr::Float64: The maximum allowable error (default: Inf).
  • maxiters::Int: The maximum number of iterations (default: Int(1e7)).
source
QuantizedSystemSolver.solveMethod
solve(prob::NLODEProblem{F,PRTYPE,T,D,Z,CS},al::QSSAlgorithm{SolverType, OrderType},tspan::Tuple{Float64, Float64};detection::Val{M}=Val(3),saveat=Inf::Float64,abstol=1e-3::Float64,reltol=1e-2::Float64,maxErr=Inf::Float64,maxiters=Int(1e7)::Int) where{F,PRTYPE,T,D,Z,CS,SolverType,OrderType,M}

dispatches on a specific integrator based on the algorithm provided and send a nonlinear ODE problem to the integrator.

With the exception of the argument prob and tspan, all other arguments are optional and have default values:

  • The algorithm defaults to nmliqss2, and it is specified by the QSSAlgorithm type, which is a composite type that has a name and an order. It can be extended independently of the solver.
  • The detection argument defaults to 1.
  • The saveat argument defaults to Inf. It specifies the time step at which the integrator will save the solution (not implemented).
  • The abstol argument defaults to 1e-3. It specifies the absolute tolerance of the integrator.
  • The reltol argument defaults to 1e-2. It specifies the relative tolerance of the integrator.
  • The maxErr argument defaults to Inf. It specifies the maximum error allowed by the integrator. This is used as an upper bound for the quantum when a variable goes large.
  • The maxiters argument defaults to 1e7. It specifies the maximum number of steps allowed by the integrator. If the user wants to extend the limit on the maximum number of steps, this argument can be used.

After the simulation, the solution is returned as a Solution object.

source

Algorithms

QuantizedSystemSolver.nmliqss1Method
nmliqss1()

calls the modified imlicit quantized state system solver with order 1. It is efficient when the system contains large entries outside the main diagonal of the Jacobian .

source
QuantizedSystemSolver.nmliqss2Method
nmliqss2()

calls the modified imlicit quantized state system solver with order 2. It is efficient when the system contains large entries outside the main diagonal of the Jacobian .

source

Solution

Query a solution

QuantizedSystemSolver.evaluateSolMethod
evaluateSol(sol::Sol{T,O}, index::Int, t::Float64) where {T,O}

Evaluates the solution at a given time t for a specified variable index.

Arguments

  • sol::Sol{T,O}: The solution struct.
  • index::Int: The index of the variable to evaluate. If index is 0, evaluates all variables.
  • t::Float64: The time at which to evaluate the solution.

Returns

  • The value of the specified variable at time t, or a vector of values if index is 0.

Throws

  • An error if the given time t is outside the solution range.
source
QuantizedSystemSolver.solInterpolatedMethod
solInterpolated(sol::Sol{T,O},step::Float64) where {T,O}

Construct a new solution by interpolating the current solution at each step for all variables.

Arguments

  • sol::Sol{T,O}: The solution struct.
  • step::Float64: the step size at which to generate the new solution.

Returns

  • A new solution that contains information at each step size..
source
QuantizedSystemSolver.solInterpolatedMethod
solInterpolated(sol::Sol{T,O},index::Int,step::Float64) where {T,O}

Constructs a new solution by interpolating the current solution at each step for one variable.

Arguments

  • sol::Sol{T,O}: The solution struct.
  • index::Int: the index of the variable to interpolate.
  • step::Float64: the step size at which to generate the new solution.

Returns

  • A new solution that contains the information of one variable at each step size.
source
Base.showMethod
show(io::IO, a::Stats)

Displays the statistics of the simulation.

Arguments

  • io::IO: The IO stream to write to.
  • a::Stats: The Stats struct containing the simulation statistics.

Prints

  • The total simulation steps.
  • The simultaneous steps.
  • The number of events.
source
QuantizedSystemSolver.StatsType
Stats

A struct that holds the statistics of a simulation. It has the following fields:

  • totalSteps::Int: The total number of simulation steps.
  • simulStepCount::Int: The number of simultaneous steps.
  • evCount::Int: The number of events.
  • numSteps::Vector{Int}: A vector holding the number of steps for each variable.
source

Error with respect to an analytic or reference solution

Finding the error

To find the error, an interpolated solution has to be used as shown in solInterpolated. The reference solution (using saveat for example) and the interpolated solution (passed step to interpolated function) must have the same tspan and the same step size.

QuantizedSystemSolver.getErrorMethod
getError(sol::Sol{T,O},index::Int,f::Function) where{T,O}

calculates the relative error of one variable of the solution with respect to a function of an analytic solution.

\[\begin{equation*} err=\sqrt{\frac{\sum(sol_{index}-f_{index})^2}{\sum(f_{index})^2}} -\end{equation*}\]

source
QuantizedSystemSolver.getAverageErrorMethod
getAverageError(sol::Sol{T,O},f::Vector{Function}) where{T,O}

calculates the average relative error of all variables of the solution with respect to a vector of functions of analytic solutions.

\[\begin{align*} +\end{equation*}\]

source
QuantizedSystemSolver.getAverageErrorMethod
getAverageError(sol::Sol{T,O},f::Vector{Function}) where{T,O}

calculates the average relative error of all variables of the solution with respect to a vector of functions of analytic solutions.

\[\begin{align*} & err_{index}=\sqrt{\frac{\sum(sol_{index}-f_{index})^2}{\sum(f_{index})^2}}\ & avgError=\frac{\sum_{index=1}^{T}err_{index}}{T} -\end{align*}\]

source
QuantizedSystemSolver.getErrorByRefsMethod
getErrorByRefs(sol::Sol{T,O},index::Int,solRef::Vector{Any}) where{T,O}

calculates the relative error of one variable of the solution with respect to a vector of values received from a reference solution.

\[\begin{equation*} +\end{align*}\]

source
QuantizedSystemSolver.getErrorByRefsMethod
getErrorByRefs(sol::Sol{T,O},index::Int,solRef::Vector{Any}) where{T,O}

calculates the relative error of one variable of the solution with respect to a vector of values received from a reference solution.

\[\begin{equation*} err=\sqrt{\frac{\sum(sol_{index}-solRef_{index})^2}{\sum(solRef_{index})^2}} -\end{equation*}\]

source
QuantizedSystemSolver.getAverageErrorByRefsMethod
getAverageErrorByRefs(sol::Sol{T,O},solRef::Vector{Any}) where{T,O}

calculates the average relative error of the solution with respect to a reference solution. The relative error is calculated for each variable, and then it is averaged over all variables.

\[\begin{align*} +\end{equation*}\]

source
QuantizedSystemSolver.getAverageErrorByRefsMethod
getAverageErrorByRefs(sol::Sol{T,O},solRef::Vector{Any}) where{T,O}

calculates the average relative error of the solution with respect to a reference solution. The relative error is calculated for each variable, and then it is averaged over all variables.

\[\begin{align*} & err_{index}=\sqrt{\frac{\sum(sol_{index}-solRef_{index})^2}{\sum(solRef_{index})^2}}\ & avgError=\frac{\sum_{index=1}^{T}err_{index}}{T} -\end{align*}\]

source

Plot the solution

RecipesBase.plotMethod
plot(sol::Sol{T,O};idxs=Int[]::Vector{Int},note=" "::String,xlims=(0.0,0.0)::Tuple{Float64, Float64},ylims=(0.0,0.0)::Tuple{Float64, Float64},legend=:true::Bool,marker=:circle::Symbol,title="") where{T,O}

generates a plot of the solution of the system (returned as a plot object). With the exception of the solution object, all arguments are optional.

arguments:

  • sol::Sol{T,O}: The solution struct.
  • xvars::Int...: The indices of the variables to plot. If no indices are provided, all variables are plotted.
  • idxs::::Vector{Float64}: The indices of the variables to plot. If no indices are provided, all variables are plotted.
  • note::String: A note to add to the title of the plot.
  • xlims::Tuple{Float64, Float64}: The x-axis limits of the plot.
  • ylims::Tuple{Float64, Float64}: The y-axis limits of the plot.
  • legend::Bool: A boolean indicating whether to display the legend.
  • marker::Symbol: The marker to use for the plot.
  • title::String: The title of the plot.
source
QuantizedSystemSolver.plot_SolMethod
plot_Sol(sol::Sol{T,O},xvars::Int...;note=" "::String,xlims=(0.0,0.0)::Tuple{Float64, Float64},ylims=(0.0,0.0)::Tuple{Float64, Float64},legend=:true::Bool,marker=:circle::Symbol,title="") where{T,O}

generates a plot of the solution of the system (returned as a plot object). With the exception of the solution object, all arguments are optional.

arguments:

  • sol::Sol{T,O}: The solution struct.
  • xvars::Int...: The indices of the variables to plot. If no indices are provided, all variables are plotted.
  • note::String: A note to add to the title of the plot.
  • xlims::Tuple{Float64, Float64}: The x-axis limits of the plot.
  • ylims::Tuple{Float64, Float64}: The y-axis limits of the plot.
  • legend::Bool: A boolean indicating whether to display the legend.
  • marker::Symbol: The marker to use for the plot.
  • title::String: The title of the plot.
source
QuantizedSystemSolver.plot_SolSumMethod
plot_SolSum(sol::Sol{T,O},xvars::Int...;interp=0.0001,note=" "::String,xlims=(0.0,0.0)::Tuple{Float64, Float64},ylims=(0.0,0.0)::Tuple{Float64, Float64},legend=:true::Bool) where{T,O}

plots of the sum of the variables xvars.

Arguments

  • sol::Sol{T,O}: The solution struct.
  • xvars::Int...: The indices of the variables to sum. If no indices are provided, all variables are summed.
  • interp::Float64: The interpolation step.
  • note::String: A note to add to the title of the plot.
  • xlims::Tuple{Float64, Float64}: The x-axis limits of the plot.
  • ylims::Tuple{Float64, Float64}: The y-axis limits of the plot.
  • legend::Bool: A boolean indicating whether to display the legend.
source
+\end{align*}\]

source

Plot the solution

RecipesBase.plotMethod
plot(sol::Sol{T,O};idxs=Int[]::Vector{Int},note=" "::String,xlims=(0.0,0.0)::Tuple{Float64, Float64},ylims=(0.0,0.0)::Tuple{Float64, Float64},legend=:true::Bool,marker=:circle::Symbol,title="") where{T,O}

generates a plot of the solution of the system (returned as a plot object). With the exception of the solution object, all arguments are optional.

arguments:

  • sol::Sol{T,O}: The solution struct.
  • xvars::Int...: The indices of the variables to plot. If no indices are provided, all variables are plotted.
  • idxs::::Vector{Float64}: The indices of the variables to plot. If no indices are provided, all variables are plotted.
  • note::String: A note to add to the title of the plot.
  • xlims::Tuple{Float64, Float64}: The x-axis limits of the plot.
  • ylims::Tuple{Float64, Float64}: The y-axis limits of the plot.
  • legend::Bool: A boolean indicating whether to display the legend.
  • marker::Symbol: The marker to use for the plot.
  • title::String: The title of the plot.
source
QuantizedSystemSolver.plot_SolMethod
plot_Sol(sol::Sol{T,O},xvars::Int...;note=" "::String,xlims=(0.0,0.0)::Tuple{Float64, Float64},ylims=(0.0,0.0)::Tuple{Float64, Float64},legend=:true::Bool,marker=:circle::Symbol,title="") where{T,O}

generates a plot of the solution of the system (returned as a plot object). With the exception of the solution object, all arguments are optional.

arguments:

  • sol::Sol{T,O}: The solution struct.
  • xvars::Int...: The indices of the variables to plot. If no indices are provided, all variables are plotted.
  • note::String: A note to add to the title of the plot.
  • xlims::Tuple{Float64, Float64}: The x-axis limits of the plot.
  • ylims::Tuple{Float64, Float64}: The y-axis limits of the plot.
  • legend::Bool: A boolean indicating whether to display the legend.
  • marker::Symbol: The marker to use for the plot.
  • title::String: The title of the plot.
source
QuantizedSystemSolver.plot_SolSumMethod
plot_SolSum(sol::Sol{T,O},xvars::Int...;interp=0.0001,note=" "::String,xlims=(0.0,0.0)::Tuple{Float64, Float64},ylims=(0.0,0.0)::Tuple{Float64, Float64},legend=:true::Bool) where{T,O}

plots of the sum of the variables xvars.

Arguments

  • sol::Sol{T,O}: The solution struct.
  • xvars::Int...: The indices of the variables to sum. If no indices are provided, all variables are summed.
  • interp::Float64: The interpolation step.
  • note::String: A note to add to the title of the plot.
  • xlims::Tuple{Float64, Float64}: The x-axis limits of the plot.
  • ylims::Tuple{Float64, Float64}: The y-axis limits of the plot.
  • legend::Bool: A boolean indicating whether to display the legend.
source
diff --git a/dev/guide/userTutorial/index.html b/dev/guide/userTutorial/index.html index cacac16..3a5c0c3 100644 --- a/dev/guide/userTutorial/index.html +++ b/dev/guide/userTutorial/index.html @@ -57,4 +57,4 @@ #0.029546046862124274

Error against an reference solution

Similarly, we compute the error against a reference solution using getErrorByRefs to get the error for one variable and getAverageErrorByRefs to get the average error. Here, the reference solution is stored in a vector that contains the values of all variables. it is the $u$ vector for the case of the solution from the differentialEquations.jl:

solFeagin14 = solve(prob,Feagin14(),saveat=0.01,abstol = 1e-12, reltol = 1e-8)
 solFeagin14Vector=solFeagin14.u
 error1=getErrorByRefs(solInterp,1,solFeagin14Vector)
-avgError=getAverageErrorByRefs(solInterp,solFeagin14Vector)

The results of some solvers of QuantizedSystemSolver.jl are compared against some solvers from DifferentialEquations.jl in the examples section.

+avgError=getAverageErrorByRefs(solInterp,solFeagin14Vector)

The results of some solvers of QuantizedSystemSolver.jl are compared against some solvers from DifferentialEquations.jl in the examples section.

diff --git a/dev/index.html b/dev/index.html index 88f46f4..43113e5 100644 --- a/dev/index.html +++ b/dev/index.html @@ -3,4 +3,4 @@ julia> ] -(@v1.x) pkg> add QuantizedSystemSolver

For new users, take a look at the Tutorial section. If you see something wrong, please open an issue

For developpers, take a look at the Developer Guide section. The, if you have an idea, do a pull request!

+(@v1.x) pkg> add QuantizedSystemSolver

For new users, take a look at the Tutorial section. If you see something wrong, please open an issue

For developpers, take a look at the Developer Guide section. The, if you have an idea, do a pull request!