simulatetraj


Namesimulatetraj JSON
Version 0.0.4 PyPI version JSON
download
home_pagehttp://simulatetraj.rtfd.io/
Summarya class to integrate ordinary differential equation
upload_time2024-06-21 21:19:13
maintainerNone
docs_urlNone
authorsandeep
requires_python<4.0,>=3.10
licenseLGPL V3
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Simulate

[![Documentation Status](https://readthedocs.org/projects/simulatetraj/badge/?version=latest)](https://simulatetraj.readthedocs.io/en/latest/?badge=latest)

Using simulatetraj, initial value problems can be solved numerically. In the backend, an adaptive numerical integration is performed using CVODES from the SUNDIALS suite.

Given initial state $x(t_0)=x_0$ and control inputs $u(t)$ on $t \in [t_0,t_f]$, the state trajectory $x(t)$ is computed for the explicit differential equation $\dot{x}=f(x,u,t,p)$.

|Symbol|Description|Dimensions|
|-|-|-|
|$x(t)$|State vector| $\mathbb{R}^{n_x}$|
|$u(t)$|Control vector| $\mathbb{R}^{n_u}$|
|$p$|Parameter vector| $\mathbb{R}^{n_p}$|
|$t$|time| $\mathbb{R}^{1}$|

## Dependencies

* ```casadi```
* ```matplotlib```

## Installation
Create a virtual environment and install the package using pip.

```
python -m venv sim_env
```

```
pip install simulatetraj
```

Run the scripts from examples folder to verify the installation.

## Usage

Consider the initial value problem given below where the behavior of the
system is studied with respect to given set of inputs and initial condition.
Lets make it parametric by adding a scalar parameter to the ode and setting its value to zero.

### ODE 1

$$
\begin{aligned}
(t_0,t_f,N)&=(0,10,25)\\
x(t_0)&=\begin{bmatrix}
0\\
0
\end{bmatrix}
\\
u(t)&=0.2t-1\\
p&=0\\
\begin{bmatrix}
    \dot{x}_0\\
    \dot{x}_1
\end{bmatrix}&=
\begin{bmatrix}
    (1-x_1^2)x_0-x_1+u\\
    x_0
\end{bmatrix}+p
\end{aligned}
$$

The problem can be solved in 2 ways using Simulate.

1. eliminate controls from the ode
2. supply controls evaluated on the grid points

#### Elimination

Define the number of states and parameter by calling the constructor of the Simulate class. Both the methods are equivalent. Skipping an argument simply sets it to zero.

```python
a=Simulate(n_x=cs.MX(2),n_p=cs.MX(1))
```

```python
a=Simulate(n_x=cs.MX(2),n_u=cs.MX(0),n_p=cs.MX(1))
```

Once the states, controls and parameters are defined, set the numerical grid for integration. The state vector will be computed at these time points. tini, tfin and N are the initial time, final time and number of intervals, respectively.

```python
a.set_grid(tini=cs.MX(0),tfin=cs.MX(10),N=cs.MX(25))
```

The Simulate class has symbolic attributes for the state, control and parameter vector (t,x,u,p) which can be used to define the dynamics of the system. These are MX symbolics offered by casadi. If nonlinear functions like trignometric function are to be applied, they must be imported from the casadi namespace.

```python
f=cs.vertcat((1-a.x[1]**2)*a.x[0]-a.x[1]+0.2*a.t-1,a.x[0])+a.p
a.set_ode(f)
```

Set the initial condition and parameter value and solve the initial value problem. t is the time grid and a.r['xf'] has the state values at the grid point except for the initial time.

```python
x0=cs.DM([0,0])
a.start(X0=cs.horzcat(x0),P=cs.DM(0))
r=a.r
t=a.t_grid
```

Plot the state and control time histories.

```python
a.plot_sol()
```

![alt text](img/image-4.png)
![alt text](img/image-5.png)

#### without control elimination

The control input is approximated as a piecewise constant function.

```python
a=Simulate(n_x=cs.MX(2),n_u=cs.MX(1),n_p=cs.MX(1))
a.set_grid(cs.MX(0),cs.MX(10),cs.MX(25))
f=cs.vertcat((1-a.x[1]**2)*a.x[0]-a.x[1]+a.u,a.x[0])+a.p
a.set_ode(f)
x0=cs.DM([0,0])
a.start(X0=cs.horzcat(x0),U=cs.linspace(-1,1,25).T,P=cs.DM(0))
r=a.r
t=a.t_grid
a.plot_sol()
```

![alt text](img/image.png)
![alt text](img/image-1.png)
![alt text](img/image-2.png)

### $t^2$

$$
\begin{aligned}
(t_0,t_f,N)&=(0,10,100000)\\
x(t_0)&=0\\
\dot{x}&=2t
\end{aligned}
$$

```python
b=Simulate(cs.MX(1))
b.set_grid(tini=cs.MX(0),tfin=cs.MX(10),N=cs.MX(100000))
f=2*b.t
b.set_ode(f)
x0=cs.DM([0])
b.start(x0)
b.plot_sol()
print('Global error x(N+1) for xdot=2t:',cs.evalf(b.r['xf'][-1]-100))
```

```bash
Global error x(N+1) for xdot=2t: 0.0016011
```

![alt text](img/image-6.png)

The default values for cvodes is 0.001 and 0.1 for absolute and relative tolerance, respectively. By increasing the tolerance global error can be reduced.

```python
 b.start(x0,tol=1e-12)
```

```bash
Global error x(N+1) for xdot=2t: 4.81748e-12
```

### Lotka voltera/prey-predator model

$$
\begin{aligned}
(t_0,t_f,N)&=(0,15,1000)\\
(\alpha,\beta)&=(0.01,0.02)\\
x(t_0)&=\begin{bmatrix}
    20\\
    20
\end{bmatrix}\\
\begin{bmatrix}
    \dot{x}_0\\
    \dot{x}_1
\end{bmatrix}&=
\begin{bmatrix}
    x_0-\alpha x_0 x_1\\
    -x_1+\beta x_0 x_1
\end{bmatrix}
\end{aligned}
$$

```python
d=Simulate(n_x=cs.MX(2),n_p=cs.MX(2))
d.set_grid(cs.MX(0),cs.MX(15),cs.MX(1000))
f=cs.vertcat(d.x[0]-d.p[0]*d.x[0]*d.x[1],-d.x[1]+d.p[1]*d.x[0]*d.x[1])
d.set_ode(f)
x0=cs.DM([20,20])
p=cs.DM([0.01,0.02])
d.start(X0=x0,P=p,tol=1e-8)
#d.plot_sol()
plt.plot(cs.evalf(d.r['xf'][0,:]),cs.evalf(d.r['xf'][1,:]),'o')
plt.show()
```

![alt text](img/image-7.png)

## Advanced

The integrator class can be used in conjunction with *trajectory optimization*, where the symbolic primitives can be passed for initial state and control inputs. This can be embedded in an optimization problem and solved for the optimal control input vector. See examples folder where single and multiple shooting methods have been implemented and solved.

```python
c=Simulate(cs.MX(1),cs.MX(1))
c.set_grid(cs.MX.sym('tf',1,1),cs.MX.sym('tf',1,1),cs.MX(10))
f=2*c.t+c.u
c.set_ode(f)
x0=cs.DM([0])
c.start(x0,cs.MX.sym('u',1,10))  
```

            

Raw data

            {
    "_id": null,
    "home_page": "http://simulatetraj.rtfd.io/",
    "name": "simulatetraj",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.10",
    "maintainer_email": null,
    "keywords": null,
    "author": "sandeep",
    "author_email": "rskravi15@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/11/a0/5f999e909108cc19bf8c2a289fdd9beddb3dd2911054a24304984d2a5369/simulatetraj-0.0.4.tar.gz",
    "platform": null,
    "description": "# Simulate\n\n[![Documentation Status](https://readthedocs.org/projects/simulatetraj/badge/?version=latest)](https://simulatetraj.readthedocs.io/en/latest/?badge=latest)\n\nUsing simulatetraj, initial value problems can be solved numerically. In the backend, an adaptive numerical integration is performed using CVODES from the SUNDIALS suite.\n\nGiven initial state $x(t_0)=x_0$ and control inputs $u(t)$ on $t \\in [t_0,t_f]$, the state trajectory $x(t)$ is computed for the explicit differential equation $\\dot{x}=f(x,u,t,p)$.\n\n|Symbol|Description|Dimensions|\n|-|-|-|\n|$x(t)$|State vector| $\\mathbb{R}^{n_x}$|\n|$u(t)$|Control vector| $\\mathbb{R}^{n_u}$|\n|$p$|Parameter vector| $\\mathbb{R}^{n_p}$|\n|$t$|time| $\\mathbb{R}^{1}$|\n\n## Dependencies\n\n* ```casadi```\n* ```matplotlib```\n\n## Installation\nCreate a virtual environment and install the package using pip.\n\n```\npython -m venv sim_env\n```\n\n```\npip install simulatetraj\n```\n\nRun the scripts from examples folder to verify the installation.\n\n## Usage\n\nConsider the initial value problem given below where the behavior of the\nsystem is studied with respect to given set of inputs and initial condition.\nLets make it parametric by adding a scalar parameter to the ode and setting its value to zero.\n\n### ODE 1\n\n$$\n\\begin{aligned}\n(t_0,t_f,N)&=(0,10,25)\\\\\nx(t_0)&=\\begin{bmatrix}\n0\\\\\n0\n\\end{bmatrix}\n\\\\\nu(t)&=0.2t-1\\\\\np&=0\\\\\n\\begin{bmatrix}\n    \\dot{x}_0\\\\\n    \\dot{x}_1\n\\end{bmatrix}&=\n\\begin{bmatrix}\n    (1-x_1^2)x_0-x_1+u\\\\\n    x_0\n\\end{bmatrix}+p\n\\end{aligned}\n$$\n\nThe problem can be solved in 2 ways using Simulate.\n\n1. eliminate controls from the ode\n2. supply controls evaluated on the grid points\n\n#### Elimination\n\nDefine the number of states and parameter by calling the constructor of the Simulate class. Both the methods are equivalent. Skipping an argument simply sets it to zero.\n\n```python\na=Simulate(n_x=cs.MX(2),n_p=cs.MX(1))\n```\n\n```python\na=Simulate(n_x=cs.MX(2),n_u=cs.MX(0),n_p=cs.MX(1))\n```\n\nOnce the states, controls and parameters are defined, set the numerical grid for integration. The state vector will be computed at these time points. tini, tfin and N are the initial time, final time and number of intervals, respectively.\n\n```python\na.set_grid(tini=cs.MX(0),tfin=cs.MX(10),N=cs.MX(25))\n```\n\nThe Simulate class has symbolic attributes for the state, control and parameter vector (t,x,u,p) which can be used to define the dynamics of the system. These are MX symbolics offered by casadi. If nonlinear functions like trignometric function are to be applied, they must be imported from the casadi namespace.\n\n```python\nf=cs.vertcat((1-a.x[1]**2)*a.x[0]-a.x[1]+0.2*a.t-1,a.x[0])+a.p\na.set_ode(f)\n```\n\nSet the initial condition and parameter value and solve the initial value problem. t is the time grid and a.r['xf'] has the state values at the grid point except for the initial time.\n\n```python\nx0=cs.DM([0,0])\na.start(X0=cs.horzcat(x0),P=cs.DM(0))\nr=a.r\nt=a.t_grid\n```\n\nPlot the state and control time histories.\n\n```python\na.plot_sol()\n```\n\n![alt text](img/image-4.png)\n![alt text](img/image-5.png)\n\n#### without control elimination\n\nThe control input is approximated as a piecewise constant function.\n\n```python\na=Simulate(n_x=cs.MX(2),n_u=cs.MX(1),n_p=cs.MX(1))\na.set_grid(cs.MX(0),cs.MX(10),cs.MX(25))\nf=cs.vertcat((1-a.x[1]**2)*a.x[0]-a.x[1]+a.u,a.x[0])+a.p\na.set_ode(f)\nx0=cs.DM([0,0])\na.start(X0=cs.horzcat(x0),U=cs.linspace(-1,1,25).T,P=cs.DM(0))\nr=a.r\nt=a.t_grid\na.plot_sol()\n```\n\n![alt text](img/image.png)\n![alt text](img/image-1.png)\n![alt text](img/image-2.png)\n\n### $t^2$\n\n$$\n\\begin{aligned}\n(t_0,t_f,N)&=(0,10,100000)\\\\\nx(t_0)&=0\\\\\n\\dot{x}&=2t\n\\end{aligned}\n$$\n\n```python\nb=Simulate(cs.MX(1))\nb.set_grid(tini=cs.MX(0),tfin=cs.MX(10),N=cs.MX(100000))\nf=2*b.t\nb.set_ode(f)\nx0=cs.DM([0])\nb.start(x0)\nb.plot_sol()\nprint('Global error x(N+1) for xdot=2t:',cs.evalf(b.r['xf'][-1]-100))\n```\n\n```bash\nGlobal error x(N+1) for xdot=2t: 0.0016011\n```\n\n![alt text](img/image-6.png)\n\nThe default values for cvodes is 0.001 and 0.1 for absolute and relative tolerance, respectively. By increasing the tolerance global error can be reduced.\n\n```python\n b.start(x0,tol=1e-12)\n```\n\n```bash\nGlobal error x(N+1) for xdot=2t: 4.81748e-12\n```\n\n### Lotka voltera/prey-predator model\n\n$$\n\\begin{aligned}\n(t_0,t_f,N)&=(0,15,1000)\\\\\n(\\alpha,\\beta)&=(0.01,0.02)\\\\\nx(t_0)&=\\begin{bmatrix}\n    20\\\\\n    20\n\\end{bmatrix}\\\\\n\\begin{bmatrix}\n    \\dot{x}_0\\\\\n    \\dot{x}_1\n\\end{bmatrix}&=\n\\begin{bmatrix}\n    x_0-\\alpha x_0 x_1\\\\\n    -x_1+\\beta x_0 x_1\n\\end{bmatrix}\n\\end{aligned}\n$$\n\n```python\nd=Simulate(n_x=cs.MX(2),n_p=cs.MX(2))\nd.set_grid(cs.MX(0),cs.MX(15),cs.MX(1000))\nf=cs.vertcat(d.x[0]-d.p[0]*d.x[0]*d.x[1],-d.x[1]+d.p[1]*d.x[0]*d.x[1])\nd.set_ode(f)\nx0=cs.DM([20,20])\np=cs.DM([0.01,0.02])\nd.start(X0=x0,P=p,tol=1e-8)\n#d.plot_sol()\nplt.plot(cs.evalf(d.r['xf'][0,:]),cs.evalf(d.r['xf'][1,:]),'o')\nplt.show()\n```\n\n![alt text](img/image-7.png)\n\n## Advanced\n\nThe integrator class can be used in conjunction with *trajectory optimization*, where the symbolic primitives can be passed for initial state and control inputs. This can be embedded in an optimization problem and solved for the optimal control input vector. See examples folder where single and multiple shooting methods have been implemented and solved.\n\n```python\nc=Simulate(cs.MX(1),cs.MX(1))\nc.set_grid(cs.MX.sym('tf',1,1),cs.MX.sym('tf',1,1),cs.MX(10))\nf=2*c.t+c.u\nc.set_ode(f)\nx0=cs.DM([0])\nc.start(x0,cs.MX.sym('u',1,10))  \n```\n",
    "bugtrack_url": null,
    "license": "LGPL V3",
    "summary": "a class to integrate ordinary differential equation",
    "version": "0.0.4",
    "project_urls": {
        "Homepage": "http://simulatetraj.rtfd.io/",
        "Repository": "https://github.com/sandeep026/simulatetraj"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8fe8909733efb22c30ae34e9ad59b78bd7e66b56248cd54d3cea0bcd5e6fc910",
                "md5": "7731ba46b477d95f7c5d6b29eba6b560",
                "sha256": "3d7d9751d1af6d80fd7836f4a834585a1a8836666342a49a13299d788e9405be"
            },
            "downloads": -1,
            "filename": "simulatetraj-0.0.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7731ba46b477d95f7c5d6b29eba6b560",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.10",
            "size": 18869,
            "upload_time": "2024-06-21T21:19:11",
            "upload_time_iso_8601": "2024-06-21T21:19:11.434434Z",
            "url": "https://files.pythonhosted.org/packages/8f/e8/909733efb22c30ae34e9ad59b78bd7e66b56248cd54d3cea0bcd5e6fc910/simulatetraj-0.0.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "11a05f999e909108cc19bf8c2a289fdd9beddb3dd2911054a24304984d2a5369",
                "md5": "353c10dd47a1859915b0023a17896c4a",
                "sha256": "e8645807caf69326df7c252550694f1fcd5f1dfddc16ee3a818702e01c97a4d3"
            },
            "downloads": -1,
            "filename": "simulatetraj-0.0.4.tar.gz",
            "has_sig": false,
            "md5_digest": "353c10dd47a1859915b0023a17896c4a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.10",
            "size": 18451,
            "upload_time": "2024-06-21T21:19:13",
            "upload_time_iso_8601": "2024-06-21T21:19:13.816022Z",
            "url": "https://files.pythonhosted.org/packages/11/a0/5f999e909108cc19bf8c2a289fdd9beddb3dd2911054a24304984d2a5369/simulatetraj-0.0.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-06-21 21:19:13",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "sandeep026",
    "github_project": "simulatetraj",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "simulatetraj"
}
        
Elapsed time: 0.26322s