Group Abstract Group Abstract

Message Boards Message Boards

0
|
8.6K Views
|
7 Replies
|
0 Total Likes
View groups...
Share
Share this post:

A problem with using NDsolve, please help.

Posted 10 years ago

I am trying to solve numerically with NDsolve a pretty standard system of non-linear ODE's of the form y'=F(y), where y is a list of n points in the plane, and F is a certain function defined inside the program. All goes well, until I reach NDsolve. My guess is that I have an elementary syntax error in passing values of F to NDsolve, steming from my lack of experience with working with functions in Mathematica (my programming background is in C...). Thanks ahead for any suggestions. I paste the program below.

Polygon flow 

This is a numerical integration program that shows a "polygon flow" in the plane. That is, p={p[1],..., p[n]} is a list of n points, where each p[i] is in R^2, moving by a certain rule, given by the ODE p'=pflow[p]. The function pflow[p] requires a small program to evaluate it. After solving this ODE, with some initial condition p0,
the program shows how the n points move in the plane.

Preliminary definitions

In[1]:= Clear[n, canon, p0, long, e, pPlot, reflect, pPlot, pflow, A]

(* Define the number of vertices of the polygon; should be odd *)
n = 3; 

(* Define the cannonical basis of R^2  *)

canon = Table[IdentityMatrix[2][[i]], {i, 1, 2}];   

(* Define some initial polygon *)

p0 = Table[{2 Cos[i 2 Pi/n], Sin[i 2 Pi/n]} // N, {i, 1, n}]; 

(* This function "lengthen " p, by adding the 1st vertex as the  nth+1 vertex \
*)
long[p_] := Join[p, {p[[1]]}];

(* Define the list of edges (unit vectors) of the poligon *)

e[p_] := Module[{edge, lp},
  lp = long[p];
  Table[
   edge = lp[[i + 1]] - lp[[i]];
   edge/Norm[edge], {i, 1, n}]
  ]

(* This generates a drawing of the polygon *)

pPlot[p_] := Graphics[Line[long[p]]]

(* This reflects a vector v about the edge e *)

reflect[v_, e_] := -v + 2 (v.e) e

(* This is the composition of reflections about the edges of the polygon *)

A[e_] := Module[{v},
  Table[
   For[
    j = 1; v = canon[[i]], 
    j < n + 1, j++,
    v = reflect[v, e[[j]]]
    ]; v,
   {i, 1, 2}
   ]
  ]

(* This defines a vector field on the space of polygons *)
pflow[p_] := Module[
  {edges, R, u},
  edges = e[p];
  R = A[edges];

  (* R is a composition of an odd number of reflections, so is a reflection, 
  hence has a unique fixed direction. 
  We pick a unit vector in this direction at the 1st vertex, 
  then spread it around the polygon by reflections wrt the edges *)

  u = First@NullSpace[R - IdentityMatrix[2]];
  Table[
   If[
    i == 1,
    u = u/Norm[u],
    u = reflect[u, edges[[i - 1]]]
    ],
   {i, 1, n}
   ] 
  ]

Integrating the ODE p'=pflow[p]

In[11]:= (* Integration time *)
T = 10;

(*Integrating the ODE*)

s = NDSolve[{y'[t] == pflow[y[t]], y[0] == p0}, y, {t, 0, T}];
yy := y /. s;

Animate[
 Graphics[
  Line[long[yy[t]]],
  PlotRange -> 3],
 {t, 0, T},
 AnimationRate -> .1
 ]
POSTED BY: Gil Bor
7 Replies
Posted 10 years ago

Would it be possible, perhaps just to make your problem simple enough for me to understand, for you to expand your y'[t]=pflow[y[t]] into a list of explicit differential equations in terms of your y1[t], y2[t],...y6[t] and the derivatives of those and the coefficient variables that you have constructed? If that could be done then it might be possible for someone to see how to then translate that into a notation that NDSolve would correctly accept.

POSTED BY: Bill Simpson
Posted 10 years ago

That's the whole issue, that NDSolve, just like you, wants to see an explicit form of the RHS of the DE p'[t]==pflow[p], but I dont have one, since the function pflow[p] is given by some complicated program, which cannot be summarized by a "formula" (probably it can, in my case, with some effort, but it's very unnatural, and one should not be obliged to do it, the program should serve me, not the other way around). In particular, pflow can only accept as input vectors p with numerical entries, not abstract symbols.

OK, so I can tell you that after searching around and asking some experts, I learnt that there is a very simple solution to this problem in Mathematica, but which is not obvious at all and is not mentioned in the documentation (at least I couldnt find it). You just add the single word "List" after the argument in the definition of pflow (the RHS of the DE)

pflow[p_List] := Module[{...}, etc

That's all. After this you can write

psol = NDSolveValue[{p'[t] == pflow[p[t]], p[0] == p0}, p, {t, 0, T}];

and all goes well. Maybe it's in the documentation somewhere, but I didnt find it. It somehow tells NDSolve, when trying to acces pflow before starting the integration process, not to use it prematurely, but wait patiently, start with the available initial conditions which turn p into a List of numbers (without them p is just a symbol without any meaning), which will be then accepted by pflow and produce, using the integrating scheme used by NDSolve, the next value of p, etc.

Thanks again for trying to help.

POSTED BY: Gil Bor
Posted 10 years ago
POSTED BY: Gil Bor
Posted 10 years ago

Dear Bill.

I am sorry that I was not clear. Let me try again.

This is the most standard system of 1st order (non-linear) ODEs, except, perhaps, for my notation. Let us take n=3 (as I do in the beginning of my program), and denote by V the usual 6-dimensional Euclidean vector space, the set of 6-tuples of real numbers x={x1,x2,x3,x4,x5,x6}. Now given some arbitrary function y=F[x] from V to V (this is basically my pflow), it defines a system of 6 ODEs y'[t]=F[y[t]], for the 6 components y1[t], ..., y6[t] of an unknown V-valued function y[t]={y1[t], ..., y6[t]}. The program is to solve this system with a given initial condition y[0] (an element of V).

The only twist, which is probably what confuses you, is that I want for some reason the 6 components of y[t] to be "repackaged" as a nested list y[t]={{y1[t],y2[t]}, {y3[t],y4[t]}, {y5[t],y6[t]}}, because I am thinking of y as a triple of points in the cartesian plane. But this is not important, and I am happy to "Flatten" my double-nested list into an ordinary list, if it helps (I tried, it did not work).

So this is exactly what NDsolve was made for, right? Perhaps what I need are some well explained standard advanced examples, where y=F[x] is a user defined function and y[t] is some list-valued, nested (a matrix), etc. The ones on the documentation are too simple. If you can point out to such examples it will be great and save a lot of explanations.

Thanks again for yr kind attention.

POSTED BY: Gil Bor
Posted 10 years ago
POSTED BY: Bill Simpson
Posted 10 years ago
POSTED BY: Gil Bor
Posted 10 years ago

If I remove the semicolon at the end of your NDSolve[...] and divide the input into a cell ending at that point and run your code then I get a stream of errors that all appear to be coming from pflow[] with your data structures not being compatible and with NDSolve not getting what it expects.

In[10]:=(*Integrating the ODE*)
s = NDSolve[{y'[t] == pflow[y[t]], y[0] == p0}, y, {t, 0, T}]

During evaluation of In[10]:= Join::heads: Heads y and List at positions 1 and 2 are expected to be the same. >>
During evaluation of In[10]:= Part::partw: Part 3 of Join[y[t],{t}] does not exist. >>
During evaluation of In[10]:= Part::partw: Part 4 of Join[y[t],{t}] does not exist. >>
During evaluation of In[10]:= Part::partw: Part 3 of Join[y[t],{t}] does not exist. >>
During evaluation of In[10]:= General::stop: Further output of Part::partw will be suppressed during this calculation. >>
During evaluation of In[10]:= Dot::dotsh: Tensors {1,0} and {(t-y[t])/Abs[t-y[t]]} have incompatible shapes. >>
During evaluation of In[10]:= Dot::dotsh: Tensors {1,0} and {(t-y[t])/Abs[t-y[t]]} have incompatible shapes. >>
During evaluation of In[10]:= Thread::tdlen: Objects of unequal length in {-1,0}+{(2 {1,0}.{(t+Times[<<2>>])/Abs[<<1>>]} (t-y[t]))/Abs[t-y[<<1>>]]} cannot be combined. >>
During evaluation of In[10]:= Thread::tdlen: Objects of unequal length in {(2 {1,0}.{(t+Times[<<2>>])/Abs[<<1>>]} (t-y[t]))/Abs[t-y[<<1>>]]}+{-1,0} cannot be combined. >>
During evaluation of In[10]:= Thread::tdlen: Objects of unequal length in {-((2 {1,0}.{(t+Times[<<2>>])/Abs[<<1>>]} (t-y[t]))/Abs[t-y[<<1>>]])}+{1,0} cannot be combined. >>
During evaluation of In[10]:= General::stop: Further output of Thread::tdlen will be suppressed during this calculation. >>
During evaluation of In[10]:= Dot::dotsh: Tensors {0,1} and {(t-y[t])/Abs[t-y[t]]} have incompatible shapes. >>
During evaluation of In[10]:= General::stop: Further output of Dot::dotsh will be suppressed during this calculation. >>
During evaluation of In[10]:= NullSpace::matrix: Argument {{-((2 ({Times[<<4>>]}+{-1,0}).{Power[<<2>>] Plus[<<2>>]} (-t+Join[y[<<1>>],{<<1>>}][[3]]))/Abs[Times[<<2>>]+Part[<<2>>]])}+{(2 {1,0}.{<<1>> <<1>>} (t-y[t]))/Abs[t+Times[<<2>>]]}+{-2,0}+(2 ({2 Power[<<2>>] Dot[<<2>>] Plus[<<2>>]}+{<<1>>}+{1,0}).<<1>> (-Join[y[<<1>>],{<<1>>}][[3]]+Join[y[t],{t}][[4]]))/Norm[-Part[<<2>>]+Join[<<2>>][[4]]],{-(<<1>>/<<1>>)}+<<2>>+<<1>>/<<1>>} at position 1 is not a non-empty rectangular matrix. >>
During evaluation of In[10]:= Power::infy: Infinite expression 1/0. encountered. >>
During evaluation of In[10]:= Power::infy: Infinite expression 1/0. encountered. >>
During evaluation of In[10]:= Infinity::indet: Indeterminate expression 0. ComplexInfinity encountered. >>
During evaluation of In[10]:= Infinity::indet: Indeterminate expression 0. ComplexInfinity {0,1}.{{{1.,-1.},{1.,1.},{-1.,Indeterminate}}} encountered. >>
During evaluation of In[10]:= Power::infy: Infinite expression 1/0. encountered. >>
During evaluation of In[10]:= General::stop: Further output of Power::infy will be suppressed during this calculation. >>
During evaluation of In[10]:= Infinity::indet: Indeterminate expression 0. ComplexInfinity encountered. >>
During evaluation of In[10]:= General::stop: Further output of Infinity::indet will be suppressed during this calculation. >>
During evaluation of In[10]:= NDSolve::ndnum: Encountered non-numerical value for a derivative at t == 0.`. >>
During evaluation of In[10]:= NDSolve::ndnum: Encountered non-numerical value for a derivative at t == 0.`. >>

Can you determine exactly what your pflow function should return?

Most of those error messages appear to be fairly clearly related to things not having the expected dimensions inside pflow. Can you make sense of some of those error messages and resolve the first layer of incompatibilities?

POSTED BY: Bill Simpson
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard