For compilers which allow dynamic linking, it is possible to use external C programs to speed up the right-hand sides etc. This also lets you create complicated right-hand sides that would be difficult to do with the XPP parser. Here are the steps you need to do this.
#include
You can define as many of these functions as you want within one file. The parameters in are passed by XPP to the function. The parameters out are what the function computes and passes back to XPP. The integers nin,nout are junt the number of such passed parameters. I never use them. The array con contains all your parameters in the order you defined them in the ODE file starting with con[2] and the array var contains the time variable, followed by the state variables, and then the fixed variables. Thus, you could directly communicate with all the variables or parameters.
gcc -shared -fpic -o pp.so pp.cwhere pp.c is what I called the C file.
export {} {}
statement to send out and read in what
is needed.
y' = y(x-a)
Here is the ODE file:
# pp.ode with dlls
#
# xp,yp are the right-hand sides
x'=xp
y'=yp
# a,b are parameters
par a=.4,c=0
init x=.1,y=.2
# dummies to allocate storage
xp=0
yp=0
# here is the main communication
export {a,c,x,y} {xp,yp}
@ total=50
done
The parameters and current values of the variables are passed in via
the first {} in the export statement. The second {}
passes back values for the fixed variables, xp,yp which are
the right-hand sides. You have to define these in XPP so I usually set
them to zero.
Next I write the C code for the right-hand sides:
/* pp.c for DLL
*/
#include
I have added a few defines to make it easier to read and write.
I compile this as
gcc -shared -fpic -o pp.so pp.c
This should give me a file called pp.so which is a shared
labrary.
I run the ODE file with XPP. I click on File Edit Load-DLL and choose the file pp.so and pp for the function name (since that is what I called it in the C file).
Then let it rip to see the solution.
u0' = f(u0)+d(u1 - u0)
u80' = f(u80)+d(u79 - u80)
uj' = f(uj)+d(uj-1 - 2uj +uj+1 ) for j=1,...,79
Here is the ODE file
# wave front in bistable RD model
u[0..80]'=up[j]
up[0..80]=0
par a=.1,d=.25,n=80
init u[0..4]=1
export {a,d}
@ total=400,nout=2
done
Note that only the parameters are exported and nothing is sent back throught the export statement. I have set the total to 400 and plot every other point.
Next, I write the C code:
#include
Note how I pass the inputs to the pointer x and the outputs to the pointer xp which respectively point to the elements var[1] and var[82]
Compile this
gcc -shared -fpic -o front.so front.c
Now run front.ode, click on File Edit Load DLL and load front.so choosing the function front. Let it rip.
I compared this to a normal ODE file
# wave front in bistable RD model
f(u)=u*(1-u)*(u-a)
u[0..80]'=up[j]
up0=f(u0)+d*(u1-u0)
up[1..79]=f(u[j])+d*(u[j-1]+u[j+1]-2*u[j])
up80=f(u80)+d*(u79-u80)
par a=.1,d=.25,n=81
init u[0..4]=1
@ total=400,nout=2
done
and get about a two-fold increase in speed.