1 (load("symplectic_ode"),ty : elapsed_real_time(), 0);
4 (reset(), display2d : false, 0);
7 ([pp, qq] : symplectic_ode (p^2/2 + 42*q^4/4,[p], [q], [po],[qo], dt, 2, 'symplectic_euler, 'any),0);
10 expand( poisson_bracket(first(last(pp)), first(last(qq)),[po],[qo]));
13 ([pp, qq] : symplectic_ode (p^2/2 + 42*q^4/4,p,q,po,qo, dt, 2, 'symplectic_euler, 'any),0);
16 expand( poisson_bracket(last(pp), last(qq),po,qo));
19 ([pp, qq] : symplectic_ode(p1^2/2 + p2^2/2 + 42*q1^2 - q1*q2 + q2^4,[p1,p2],
20 [q1,q2], [p10, p20],[q10, q20], dt, 2, 'symplectic_euler, 'any),0);
23 (pp : last(pp), qq : last(qq),0);
26 expand(outermap(lambda([f,g], poisson_bracket(f,g, [p10,p20],[q10,q20])), pp,qq));
29 ratsimp(expand(outermap(lambda([f,g], poisson_bracket(f,g, [p10,p20],[q10,q20])), pp,pp)));
32 ratsimp(expand(outermap(lambda([f,g], poisson_bracket(f,g, [p10,p20],[q10,q20])), qq,qq)));
35 /* check for correct order */
37 ([pp,qq] : symplectic_ode (p^2/2 + q^2/2,[p], [q], [po],[qo], dt, 4, 'symplectic_euler, 'any),0);
40 taylor(first(last(pp)) - (po * cos(4 *dt) - qo * sin(4 *dt)),dt,0,2);
43 taylor(first(last(qq)) - (qo * cos(4 *dt) + po * sin(4 *dt)),dt,0,2);
46 /* Test verlet method */
48 ([pp, qq] : symplectic_ode(p^2/2 + q^4/4,[p],[q],[po],[qo],dt,1, 'verlet, 'any),0);
51 expand( poisson_bracket(first(last(pp)), first(last(qq)),[po],[qo]));
54 ([pp, qq] : symplectic_ode(p1^2/2 + p2^2/2 + 42*q1^2 - q1*q2 + q2^4,[p1,p2],
55 [q1,q2], [p10, p20],[q10, q20], dt, 2, 'verlet, 'any),0);
58 (pp : last(pp), qq : last(qq),0);
61 expand(outermap(lambda([f,g], poisson_bracket(f,g, [p10,p20],[q10,q20])), pp,qq));
64 expand(outermap(lambda([f,g], poisson_bracket(f,g, [p10,p20],[q10,q20])), pp,pp));
67 expand(outermap(lambda([f,g], poisson_bracket(f,g, [p10,p20],[q10,q20])), qq,qq));
70 ([pp,qq] : symplectic_ode (p^2/2 + q^2/2,[p], [q], [po],[qo], dt, 4, 'verlet, 'any),0);
73 taylor(first(last(pp)) - (po * cos(4 *dt) - qo * sin(4 *dt)),dt,0,4);
74 -(2*qo*dt^3)/3-(2*po*dt^4)/3$
76 taylor(first(last(qq)) - (qo * cos(4 *dt) + po * sin(4 *dt)),dt,0,4);
77 -(po*dt^3)/3-(2*qo*dt^4)/3$
79 /* Test a third order method */
81 ([pp, qq] : symplectic_ode (p^2/2 + q^4/4,[p],[q],[po],[qo],dt,1, 'symplectic_third_order, 'any),0);
84 expand( poisson_bracket(first(last(pp)), first(last(qq)),[po],[qo]));
87 ([pp, qq] : symplectic_ode (p1^2/2 + p2^2/2 + 42*q1^2 - q1*q2 + q2^4,[p1,p2],
88 [q1,q2], [p10, p20],[q10, q20], dt, 2, 'verlet, 'any),0);
91 (pp : last(pp), qq : last(qq),0);
94 expand(outermap(lambda([f,g], poisson_bracket(f,g,[p10,p20],[q10,q20])), pp,qq));
97 expand(outermap(lambda([f,g], poisson_bracket(f,g,[p10,p20],[q10,q20])), pp,pp));
100 expand(outermap(lambda([f,g], poisson_bracket(f,g,[p10,p20],[q10,q20])), qq,qq));
103 ([pp,qq] : symplectic_ode (p^2/2 + q^2/2,[p], [q],[po],[qo], dt, 4, 'symplectic_third_order, 'any),0);
106 taylor(first(last(pp)) - (po * cos(4 *dt) - qo * sin(4 *dt)),dt,0,5);
107 -(po*dt^4)/9-(qo*dt^5)/45$
109 taylor(first(last(qq)) - (qo * cos(4 *dt) + po * sin(4 *dt)),dt,0,5);
110 (qo*dt^4)/9-(37*po*dt^5)/2160$
112 /* Test a fourth order method */
114 (algebraic : true,0);
117 ([pp, qq] : symplectic_ode (p^2/2,[p],[q],[po],[qo],dt,1, 'symplectic_fourth_order, 'any),0);
120 expand( poisson_bracket(first(last(pp)), first(last(qq)),[po],[qo]));
123 ([pp, qq] : symplectic_ode (p1^2/2 + p2^2/2 + q1*q2,[p1,p2],
124 [q1,q2], [p10, p20],[q10, q20], dt, 2, 'symplectic_fourth_order, 'any),0);
127 (pp : last(pp), qq : last(qq),0);
130 ratsimp(expand(outermap(lambda([f,g], poisson_bracket(f,g,[p10,p20],[q10,q20])), pp,qq)));
133 ratsimp(expand(outermap(lambda([f,g], poisson_bracket(f,g,[p10,p20],[q10,q20])), pp,pp)));
136 ratsimp(expand(outermap(lambda([f,g], poisson_bracket(f,g,[p10,p20],[q10,q20])), qq,qq)));
139 ([pp,qq] : symplectic_ode(p^2/2 + q^2/2,[p], [q],[po],[qo], dt, 4, 'symplectic_fourth_order, 'any),0);
142 taylor(first(last(pp)) - (po * cos(4 *dt) - qo * sin(4 *dt)),dt,0,5);
143 ((3*(2^(1/3))^8-5*(2^(1/3))^7-5*(2^(1/3))^4+18)*qo*dt^5)/(225*(2^(1/3))^10-585*(2^(1/3))^8+1440)$
145 taylor(first(last(qq)) - (qo * cos(4 *dt) + po * sin(4 *dt)),dt,0,5);
146 -((19*(2^(1/3))^8-155*(2^(1/3))^4-85*(2^(1/3))^2+325*2^(1/3)-6)*po*dt^5)/(225*(2^(1/3))^7-585*(2^(1/3))^5+720)$
150 ([pp, qq] : symplectic_ode (p^2/2 + 42*q^4/4,[p], [q], [1],[0], 1/10, 57, 'symplectic_euler, 'float),0);
153 every('floatnump, xreduce('append, pp)) and every('floatnump, xreduce('append, qq));
156 ([pp, qq] : symplectic_ode (p^2/2 + 42*q^4/4, p, q, 1, 0, 1/10, 5, 'symplectic_euler, 'rational),0)$
159 every('ratnump, pp) and every('ratnump, qq);
162 ([pp, qq] : symplectic_ode (p^2/2 + 42*q^4/4, p, q, 1, 0, 1/10, 5, 'symplectic_euler, 'bfloat),0);
165 every('bfloatp, pp) and every('bfloatp, qq);
168 /* poisson Brackets */
170 poisson_bracket(p,p,[p],[q]);
173 poisson_bracket(p,q,[p],[q]);
176 poisson_bracket(p^2,q^2,[p],[q]);
179 poisson_bracket(p^2,q^2,p,q);
182 (ham : lambda([p,q], p^2/2 + q^4-q^2),dt : 1/10^4, N : 10^4, 0);
185 (x : symplectic_ode(ham(p,q), p,q,1,0,dt,N,'symplectic_euler, 'float),
186 z : symplectic_ode(ham(p,q), p,q,1,0,dt, N, 'verlet, 'float),
187 block([listarith : true], is(lmax(map('abs, xreduce('append,x-z))) < 2.0e-4)));
190 (z : symplectic_ode(ham(p,q),p,q,1,0,dt,N, 'symplectic_third_order, 'float),
191 block([listarith : true], is(lmax(map('abs, xreduce('append,x-z))) < 2.0e-4)));
194 (z : symplectic_ode(ham(p,q), p,q,1,0,dt,N, 'symplectic_fourth_order, 'float),
195 block([listarith : true], is(lmax(map('abs, xreduce('append,x-z))) < 2.0e-4)));
198 (z : symplectic_ode(ham(p,q), p,q,1,0,dt,N,'symplectic_fifth_order, 'float),
199 block([listarith : true], is(lmax(map('abs, xreduce('append,x-z))) < 2.0e-4)));
202 /* How well does each method conserve energy? */
203 (ham : lambda([p,q], p^2/2 + q^4-q^2),dt : 1/10, N : 10^4, 0);
206 (x : symplectic_ode(ham(p,q),p,q,1,0,dt,N,'symplectic_euler, 'float),
207 x : map(ham,first(x),second(x)),
208 is(lmax(x)-lmin(x) < 3.0e-1));
211 (x : symplectic_ode(ham(p,q), p,q,1,0,dt,N,'verlet, 'float),
212 x : map(ham,first(x),second(x)),
213 is(lmax(x)-lmin(x) < 2.0e-2));
216 (x : symplectic_ode(ham(p,q), p,q,1,0,dt,N,'symplectic_third_order, 'float),
217 x : map(ham,first(x),second(x)),
218 is(lmax(x)-lmin(x) < 2.0e-3));
221 (x : symplectic_ode(ham(p,q), p,q,1,0,dt,N,'symplectic_fourth_order, 'float),
222 x : map(ham,first(x),second(x)),
223 is(lmax(x)-lmin(x) < 5.0e-4));
226 (x : symplectic_ode(ham(p,q), p,q,1,0,dt,N,'symplectic_fifth_order, 'float),
227 x : map(ham,first(x),second(x)),
228 is(lmax(x)-lmin(x) < 2.0e-6));
231 /* bogus argument errors */
233 errcatch(symplectic_ode(p^2/2+(42*q^4)/4,[p],q,1,0, 1/10,2));
236 errcatch(symplectic_ode(p^2/2+(42*q^4)/4,p,[q],1,0, 1/10,2));
239 errcatch(symplectic_ode(p^2/2+(42*q^4)/4,p,q,[1],0, 1/10,2));
242 errcatch(symplectic_ode(p^2/2+(42*q^4)/4,p,q,1,[0], 1/10,2));
245 errcatch(symplectic_ode(p^2/2+(42*q^4)/4,p,q,1,0, [1/10],2));
248 errcatch(symplectic_ode(p^2/2+(42*q^4)/4,p,q,1,0,1/10,8.8));
251 errcatch( poisson_bracket(p^2,q^2,p,[q]));
254 errcatch( poisson_bracket(p^2,q^2,[p],q));
257 /* see mailing list "symplectic_ode and mapatom" 30 Nov 2020 */
258 symplectic_ode (p^2/2 + q^2/2,p,q, %pi/7,%pi, 1/10, 2, 'symplectic_euler, 'any);
259 [[%pi/7,(3*%pi)/70,-(403*%pi)/7000],[%pi,(703*%pi)/700,(69897*%pi)/70000]]$
261 errcatch(symplectic_ode (p^2/2 + q^2/2,[p],q, %pi/7,%pi, 1/10, 2, 'symplectic_euler, 'any));
265 symplectic_ode (p^2/2 + q^2/2,[p],[q], [1],[1], 1/10, 2, 'symplectic_euler, 'any);
266 [[[1],[9/10],[791/1000]],[[1],[109/100],[11691/10000]]]$
268 (print("Runtime was ", elapsed_real_time()-ty," seconds."),0);
271 /* make a mess? Clean it up.*/
272 (remvalue(pp,qq,ty,ham,dt,N,x,z), reset(algebraic, display2d),0);