ODE Times Matlab vs R

若如初见. 提交于 2019-12-12 14:24:26

问题


If using a variable time step solver such as ODE45 in matlab - I would define a time span for the outputs, i.e. times = [0 50], and matlab would return results at various time steps between 0 and 50.

However in R it appears I have to define the time points at which I want the ODE to return the results, i.e if I gave times = 0:50, it would return 51 results at 0,1,2, ... 50. Other wise I have to supply a sequence such as , times = seq(0,50,0.1).

I have a function which changes rapidly at the beginning and then much more gradually. In MATLAB the output results reflects this with 82 time steps returned in the results, of which 49 are between the time step 0 and 1.

I want to know if there is a way to get R to return the results in the same manner as MATLAB, so without me having the pre-specify the time points I wish the results returned at.


回答1:


The R-Package deSolve describes the used parameter times in this way:

time sequence for which output is wanted;

The document Dennis liked to has another important sentence:

We note that, for some implementations, the vector times at which the output is wanted defines the mesh at which the method performs its steps, so the accuracy of the solution strongly depends on the input vector times.

A simple example is the following one, the Lorenz equations, mentioned in the book about the package deSolve:

library(deSolve)

parameters <- c(
  a = -8/3,
  b = -10,
  c =  28)

state <- c(
  X = 1,
  Y = 1,
  Z = 1)

# ---- define function in R
Lorenz <- function(t, state, parameters) {
  with(as.list(c(state, parameters)),{
    # rate of change
    dX <- a*X + Y*Z
    dY <- b * (Y-Z)
    dZ <- -X*Y + c*Y - Z

    # return the rate of change
    list(c(dX, dY, dZ))
  })   # end with(as.list ...
}

times_1 <- seq(0, 100, by = 1)
out_1 <- lsoda(y = state, times = times_1, func = Lorenz, parms = parameters)

times_2 <- seq(0, 100, by = 0.01)
out_2 <- lsoda(y = state, times = times_2, func = Lorenz, parms = parameters)

tail(out_1)

       time        X          Y          Z
 [96,]   95 30.54833  11.802554  12.445819
 [97,]   96 21.26423   4.341405   4.785116
 [98,]   97 33.05220  13.021730  12.934761
 [99,]   98 21.06394   2.290509   1.717839
[100,]   99 10.34613   1.242556   2.238154
[101,]  100 32.87323 -13.054632 -13.194377

tail(out_2)

           time        X          Y         Z
 [9996,]  99.95 17.16735  -7.509679 -12.08159
 [9997,]  99.96 17.66567  -7.978368 -12.77713
 [9998,]  99.97 18.26620  -8.468668 -13.47134
 [9999,]  99.98 18.97496  -8.977816 -14.15177
[10000,]  99.99 19.79639  -9.501998 -14.80335
[10001,] 100.00 20.73260 -10.036203 -15.40840

You can see the differences in the results at t = 100. This comes from the different defined times.

Regards,
J_F




回答2:


Upon reading this document on deSolve it states:

We solve the IVP for 100 days, producing output every 0.01 days; this small output step is necessary to obtain smooth figures. In general this does not affect the time step of integration; this is usually determined by the solver

As such it would seem that you should indeed use times = seq(0,50,0.1) as input. If you only want to show 'interesting' points in a graph, I suppose you could write a small function to post-process the output of the actual solver output.



来源:https://stackoverflow.com/questions/37918300/ode-times-matlab-vs-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!