# t_span in ode_solver

The definition of the first time in t_span has no effect : [t_0,t_1] has the same effect than [0,t_1]. See the code below.

What to do ?

def f(t,y): return[y[0],y[1]]
T = ode_solver()
T.function=f
T.ode_solve(y_0=[1,1],t_span=[-1,0.5],num_points=100)
sx=[j[1][0] for j in T.solution]
sy=[j[1][1] for j in T.solution]
p=line(zip(sx,sy))
p.show(xmin=-3,xmax=3,ymax=3,ymin=-3)

edit retag close merge delete

Sort by » oldest newest most voted

In order to have a clear question, i have to formulate one and describe what is the mathematical, respective the sage part of the problem. My hope is, this answer is related to the posted question somehow. If not, please ignore. (And reformulate the posted question.)

Mathematical part

Let us consider the following system of differential equations (de) in the "time variable" $t$ with the function $y=(y_0,y_1)$, which is a function of $t$, $y$ defined on $\mathbb R$ (or a connected part of it) with values in $\mathbb R^2$. The (de) is: $$y_0'=y_0\ ,\ y_1'=y_1\ .$$ We further consider also boundary conditions: $$y(t_0)=(1,1)\ .$$ Explicitly, $y_0(t_0)=y_1(t_0)=1$.

It remains to declare $t_0$. This is the left margin (of the interval) specified in the t_span variable. If i more or less guess the right meaning of $t_0$ and the other $t_0$ and $t_1$, then we want to solve the above (de) with two different values of $t_0$:

The one (de), let us call it (de:A) is: $$(de_A)\ y_0'=y_0\ ,\ y_1'=y_1\ ,\ y(t_0)=(1,1)\ ,\ t_0=-1\ .$$ The other (de), let us call it (de:B) is: $$(de_B)\ y_0'=y_0\ ,\ y_1'=y_1\ ,\ y(t_0)=(1,1)\ ,\ t_0=0\ .$$ We solve mathematically, or with sage and get the solutions: $$(de_A)\ y_0(t)=y_1(t)=\exp(t+1)\ ,$$ $$(de_B)\ y_0(t)=y_1(t)=\exp(t)\ .$$ Now we consider these functions numerically, only some $100$ points in between, and plot numerically the line with the $100$ points using the $t$-parametrization $t\to y(t)=(y_0(t),y_1(t))$.

Of course, the plot will land inside the line $X=Y$ in the coordinate system $XOY$.

SAGE part

We consider the code first:

T = ode_solver()
T.function = ( lambda t,y:     [ y[0],y[1] ] )

T.ode_solve( y_0 = [1,1]
, t_span = [-1, 0.5]
, num_points=15 )

for sol in T.solution:    print sol


It is a version of the posted code with clear spacing and an explicit print of the computed numerical solution. There are only $15$ points instead of the $100$ in the post, so that i can print the results below:

(-1, [1, 1])
(-0.9, [1.1051709180721718, 1.1051709180721718])
(-0.8, [1.2214027581508475, 1.2214027581508475])
(-0.7000000000000001, [1.349858807559386, 1.349858807559386])
(-0.6000000000000001, [1.4918246976162504, 1.4918246976162504])
(-0.5000000000000001, [1.6487212706652636, 1.6487212706652636])
(-0.40000000000000013, [1.8221188003441908, 1.8221188003441908])
(-0.30000000000000016, [2.0137527074108474, 2.0137527074108474])
(-0.20000000000000015, [2.225540928417404, 2.225540928417404])
(-0.10000000000000014, [2.4596031110640215, 2.4596031110640215])
(-1.3877787807814457e-16, [2.718281828345476, 2.718281828345476])
(0.09999999999999987, [3.0041660238090535, 3.0041660238090535])
(0.19999999999999987, [3.320116922571744, 3.320116922571744])
(0.2999999999999999, [3.6692966674228997, 3.6692966674228997])
(0.3999999999999999, [4.055199966612103, 4.055199966612103])
(0.4999999999999999, [4.481689070063939, 4.481689070063939])


This is the solution, and the last value fits into the theoretical computation, since

sage: exp( 0.5 + 1 )
4.48168907033806


The lines:

sx = [ j[1][0] for j in T.solution ]
sy = [ j[1][1] for j in T.solution ]

zip( sx, sy )


are now computing the same as the list comprehension:

sage: [ sol[1] for sol in T.solution ]
[[1, 1],
[1.1051709180721718, 1.1051709180721718],
[1.2214027581508475, 1.2214027581508475],
[1.349858807559386, 1.349858807559386],
[1.4918246976162504, 1.4918246976162504],
[1.6487212706652636, 1.6487212706652636],
[1.8221188003441908, 1.8221188003441908],
[2.0137527074108474, 2.0137527074108474],
[2.225540928417404, 2.225540928417404],
[2.4596031110640215, 2.4596031110640215],
[2.718281828345476, 2.718281828345476],
[3.0041660238090535, 3.0041660238090535],
[3.320116922571744, 3.320116922571744],
[3.6692966674228997, 3.6692966674228997],
[4.055199966612103, 4.055199966612103],
[4.481689070063939, 4.481689070063939]]


Now we print the line for these points, but take care to stop at xmax=3 and ymax=3. OK.

p = line( [ sol[1] for sol in T.solution ] )
p.show( xmin=-3, xmax=3, ymax=3, ymin=-3 )


And please observe that the point $(3,3)$ is reached.

Let us now do "the same", but use the t_span = [ 0, 0.5 ].

T = ode_solver()
T.function = ( lambda t,y:     [ y[0],y[1] ] )

T.ode_solve( y_0 = [1,1]
, t_span = [ 0 , 0.5]    # WE START IN ZERO
, num_points=5 )         # ONLY FIVE POINTS

for sol in T.solution:    print sol

p = line( [ sol[1] for sol in T.solution ] )
p.show( xmin=-3, xmax=3, ymax=3, ymin=-3 )


This gives:

(0, [1, 1])
(0.1, [1.1051709180721718, 1.1051709180721718])
(0.2, [1.2214027581508475, 1.2214027581508475])
(0.30000000000000004, [1.349858807559386, 1.349858807559386])
(0.4, [1.4918246976162504, 1.4918246976162504])
(0.5, [1.6487212706652636, 1.6487212706652636])
Launched png viewer for Graphics object consisting of 1 graphics primitive


and in the launched viewer the line segment starts in $(1,1)$ but does not reach $(2,2)$.

If we have "the same effect", there is still some difference - the second parametric solution does not go "as far as the first one".

more

Thanks for explanations !

In fact, I was also puzzled by the ode_solver feature giving solution only for positive times : t_1>t_0 if t_span=t_0,t_1] (for negative times (t_1<t_0) ,="" consider="" the="" ode="" y'="-F(-t,y)).&lt;/p">

( 2017-10-01 12:06:10 +0200 )edit