summations and combinations

Please support our C++ advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: Jul 2004
Posts: 6
Reputation: ellisrn is an unknown quantity at this point 
Solved Threads: 0
ellisrn ellisrn is offline Offline
Newbie Poster

summations and combinations

 
0
  #1
Jul 14th, 2004
I'm trying to write a program to do a Runge-Kutta algorithm for a complicated Norberg ODE, but two of my equations involve summations over small intervals (0 to 3) and summations of combinations.

Does anyone know how to program these type of math equations?

Thanks!
Reply With Quote Quick reply to this message  
Join Date: May 2004
Posts: 141
Reputation: meabed is on a distinguished road 
Solved Threads: 3
Team Colleague
meabed's Avatar
meabed meabed is offline Offline
Junior Poster

Re: summations and combinations

 
0
  #2
Jul 17th, 2004
this is my assignment in the past ..
  1. #include <stdio.h>
  2. #include <iostream.h>
  3. #include <math.h>
  4. #include <fstream.h>
  5.  
  6. /*
  7.  
  8. Different methods for solving ODEs are presented
  9. We are solving the following eqation:
  10.  
  11. m*l*(phi)'' + reib*(phi)' + m*g*sin(phi) = A*cos(omega*t)
  12.  
  13. If you want to solve similar equations with other values you have to
  14. rewrite the methods 'derivatives' and 'initialise' and change the variables in the private
  15. part of the class Pendel
  16.  
  17. At first we rewrite the equation using the following definitions:
  18.  
  19. omega_0 = sqrt(g*l)
  20. t_roof = omega_0*t
  21. omega_roof = omega/omega_0
  22. Q = (m*g)/(omega_0*reib)
  23. A_roof = A/(m*g)
  24.  
  25. and we get a dimensionless equation
  26.  
  27. (phi)'' + 1/Q*(phi)' + sin(phi) = A_roof*cos(omega_roof*t_roof)
  28.  
  29. This equation can be written as two equations of first order:
  30.  
  31. (phi)' = v
  32. (v)' = -v/Q - sin(phi) +A_roof*cos(omega_roof*t_roof)
  33.  
  34. All numerical methods are applied to the last two equations.
  35. The algorithms are taken from the book "An introduction to computer simulation methods"
  36. */
  37.  
  38. class pendelum
  39. {
  40. private:
  41. double Q, A_roof, omega_0, omega_roof,g; //
  42. double y[2]; //for the initial-values of phi and v
  43. int n; // how many steps
  44. double delta_t,delta_t_roof;
  45.  
  46. public:
  47. void derivatives(double,double*,double*);
  48. void initialise();
  49. void euler();
  50. void euler_cromer();
  51. void midpoint();
  52. void euler_richardson();
  53. void half_step();
  54. void rk2(); //runge-kutta-second-order
  55. void rk4_step(double,double*,double*,double); // we need it in function rk4() and asc()
  56. void rk4(); //runge-kutta-fourth-order
  57. void asc(); //runge-kutta-fourth-order with adaptive stepsize control
  58. };
  59.  
  60. void pendelum::derivatives(double t, double* in, double* out)
  61. { /* Here we are calculating the derivatives at (dimensionless) time t
  62.   'in' are the values of phi and v, which are used for the calculation
  63.   The results are given to 'out' */
  64.  
  65. out[0]=in[1]; //out[0] = (phi)' = v
  66. if(Q)
  67. out[1]=-in[1]/((double)Q)-sin(in[0])+A_roof*cos(omega_roof*t); //out[1] = (phi)''
  68. else
  69. out[1]=-sin(in[0])+A_roof*cos(omega_roof*t); //out[1] = (phi)''
  70. }
  71.  
  72.  
  73. void pendelum::initialise()
  74. {
  75. double m,l,omega,A,viscosity,phi_0,v_0,t_end;
  76. cout<<"Solving the differential eqation of the pendulum!\n";
  77. cout<<"We have a pendulum with mass m, length l. Then we have a periodic force with amplitude A and omega\n";
  78. cout<<"Furthermore there is a viscous drag coefficient.\n";
  79. cout<<"The initial conditions at t=0 are phi_0 and v_0\n";
  80. cout<<"Mass m: ";
  81. cin>>m;
  82. cout<<"length l: ";
  83. cin>>l;
  84. cout<<"omega of the force: ";
  85. cin>>omega;
  86. cout<<"amplitude of the force: ";
  87. cin>>A;
  88. cout<<"The value of the viscous drag constant (viscosity): ";
  89. cin>>viscosity;
  90. cout<<"phi_0: ";
  91. cin>>y[0];
  92. cout<<"v_0: ";
  93. cin>>y[1];
  94. cout<<"Number of time steps or integration steps:";
  95. cin>>n;
  96. cout<<"Final time steps as multiplum of pi:";
  97. cin>>t_end;
  98. t_end *= acos(-1.);
  99. g=9.81;
  100. // We need the following values:
  101. omega_0=sqrt(g/((double)l)); // omega of the pendulum
  102. if (viscosity) Q= m*g/((double)omega_0*viscosity);
  103. else Q=0; //calculating Q
  104. A_roof=A/((double)m*g);
  105. omega_roof=omega/((double)omega_0);
  106. delta_t_roof=omega_0*t_end/((double)n); //delta_t without dimension
  107. delta_t=t_end/((double)n);
  108. }
  109.  
  110. void pendelum::euler()
  111. { //using simple euler-method
  112. int i;
  113. double yout[2],y_h[2];
  114. double t_h;
  115.  
  116. y_h[0]=y[0];
  117. y_h[1]=y[1];
  118. t_h=0;
  119. ofstream fout("euler.out");
  120. fout.setf(ios::scientific);
  121. fout.precision(20);
  122. for(i=1;i<=n;i++){
  123. derivatives(t_h,y_h,yout);
  124. yout[1]=y_h[1]+yout[1]*delta_t_roof;
  125. yout[0]=y_h[0]+yout[0]*delta_t_roof;
  126. // Calculation with dimensionless values
  127. fout<<i*delta_t<<"\t\t"<<yout[0]<<"\t\t"<<yout[1]<<"\n";
  128. t_h+=delta_t_roof;
  129. y_h[1]=yout[1];
  130. y_h[0]=yout[0];
  131. }
  132. fout.close;
  133. }
  134.  
  135. void pendelum::euler_cromer()
  136. {
  137. int i;
  138. double t_h;
  139. double yout[2],y_h[2];
  140.  
  141. t_h=0;
  142. y_h[0]=y[0]; //phi
  143. y_h[1]=y[1]; //v
  144. ofstream fout("ec.out");
  145. fout.setf(ios::scientific);
  146. fout.precision(20);
  147. for(i=1; i<=n; i++){
  148. derivatives(t_h,y_h,yout);
  149. yout[1]=y_h[1]+yout[1]*delta_t_roof;
  150. yout[0]=y_h[0]+yout[1]*delta_t_roof;
  151. // The new calculated value of v is used for calculating phi
  152. fout<<i*delta_t<<"\t\t"<<yout[0]<<"\t\t"<<yout[1]<<"\n";
  153. t_h+=delta_t_roof;
  154. y_h[0]=yout[0];
  155. y_h[1]=yout[1];
  156. }
  157. fout.close;
  158. }
  159.  
  160. void pendelum::midpoint()
  161. {
  162. int i;
  163. double t_h;
  164. double yout[2],y_h[2];
  165.  
  166. t_h=0;
  167. y_h[0]=y[0]; //phi
  168. y_h[1]=y[1]; //v
  169. ofstream fout("midpoint.out");
  170. fout.setf(ios::scientific);
  171. fout.precision(20);
  172. for(i=1; i<=n; i++){
  173. derivatives(t_h,y_h,yout);
  174. yout[1]=y_h[1]+yout[1]*delta_t_roof;
  175. yout[0]=y_h[0]+0.5*(yout[1]+y_h[1])*delta_t_roof;
  176. fout<<i*delta_t<<"\t\t"<<yout[0]<<"\t\t"<<yout[1]<<"\n";
  177. t_h+=delta_t_roof;
  178. y_h[0]=yout[0];
  179. y_h[1]=yout[1];
  180. }
  181. fout.close;
  182. }
  183.  
  184.  
  185. void pendelum::euler_richardson()
  186. {
  187. int i;
  188. double t_h,t_m;
  189. double yout[2],y_h[2],y_m[2];
  190.  
  191. t_h=0;
  192. y_h[0]=y[0]; //phi
  193. y_h[1]=y[1]; //v
  194. ofstream fout("er.out");
  195. fout.setf(ios::scientific);
  196. fout.precision(20);
  197. for(i=1; i<=n; i++){
  198. derivatives(t_h,y_h,yout);
  199. y_m[1]=y_h[1]+0.5*yout[1]*delta_t_roof;
  200. y_m[0]=y_h[0]+0.5*y_h[1]*delta_t_roof;
  201. t_m=t_h+0.5*delta_t_roof;
  202. derivatives(t_m,y_m,yout);
  203. yout[1]=y_h[1]+yout[1]*delta_t_roof;
  204. yout[0]=y_h[0]+y_m[1]*delta_t_roof;
  205. fout<<i*delta_t<<"\t\t"<<yout[0]<<"\t\t"<<yout[1]<<"\n";
  206. t_h+=delta_t_roof;
  207. y_h[0]=yout[0];
  208. y_h[1]=yout[1];
  209. }
  210. fout.close;
  211. }
  212.  
  213. void pendelum::half_step()
  214. {
  215. /*We are using the half_step_algorith.
  216.   The algorithm is not self-starting, so we calculate
  217.   v_1/2 by using the Euler algorithm. */
  218.  
  219. int i;
  220. double t_h;
  221. double yout[2],y_h[2];
  222.  
  223. t_h=0;
  224. y_h[0]=y[0]; //phi
  225. y_h[1]=y[1]; //v
  226. ofstream fout("half_step.out");
  227. fout.setf(ios::scientific);
  228. fout.precision(20);
  229. /*At first we have to calculate v_1/2
  230.   For this we use Euler's method:
  231.   v_`1/2 = v_0 + 1/2*a_0*delta_t_roof
  232.   For calculating a_0 we have to start derivatives
  233.   */
  234. derivatives(t_h,y_h,yout);
  235. yout[1]=y_h[1]+0.5*yout[1]*delta_t_roof;
  236. yout[0]=y_h[0]+yout[1]*delta_t_roof;
  237. fout<<delta_t<<"\t\t"<<yout[0]<<"\t\t"<<yout[1]<<"\n";
  238. y_h[0]=yout[0];
  239. y_h[1]=yout[1];
  240. for(i=2; i<=n; i++){
  241. derivatives(t_h,y_h,yout);
  242. yout[1]=y_h[1]+yout[1]*delta_t_roof;
  243. yout[0]=y_h[0]+yout[1]*delta_t_roof;
  244. fout<<i*delta_t<<"\t\t"<<yout[0]<<"\t\t"<<yout[1]<<"\n";
  245. t_h+=delta_t_roof;
  246. y_h[0]=yout[0];
  247. y_h[1]=yout[1];
  248. }
  249. fout.close;
  250. }
  251.  
  252. void pendelum::rk2()
  253. {
  254. /*We are using the second-order-Runge-Kutta-algorithm
  255.   We have to calculate the parameters k1 and k2 for v and phi,
  256.   so we use to arrays k1[2] and k2[2] for this
  257.   k1[0], k2[0] are the parameters for phi,
  258.   k1[1], k2[1] are the parameters for v
  259.   */
  260.  
  261. int i;
  262. double t_h;
  263. double yout[2],y_h[2],k1[2],k2[2],y_k[2];
  264.  
  265. t_h=0;
  266. y_h[0]=y[0]; //phi
  267. y_h[1]=y[1]; //v
  268. ofstream fout("rk2.out");
  269. fout.setf(ios::scientific);
  270. fout.precision(20);
  271. for(i=1; i<=n; i++){
  272. /*Calculation of k1 */
  273. derivatives(t_h,y_h,yout);
  274. k1[1]=yout[1]*delta_t_roof;
  275. k1[0]=yout[0]*delta_t_roof;
  276. y_k[0]=y_h[0]+k1[0]*0.5;
  277. y_k[1]=y_h[1]+k2[1]*0.5;
  278. /*Calculation of k2 */
  279. derivatives(t_h+delta_t_roof*0.5,y_k,yout);
  280. k2[1]=yout[1]*delta_t_roof;
  281. k2[0]=yout[0]*delta_t_roof;
  282. yout[1]=y_h[1]+k2[1];
  283. yout[0]=y_h[0]+k2[0];
  284. fout<<i*delta_t<<"\t\t"<<yout[0]<<"\t\t"<<yout[1]<<"\n";
  285. t_h+=delta_t_roof;
  286. y_h[0]=yout[0];
  287. y_h[1]=yout[1];
  288. }
  289. fout.close;
  290. }
  291.  
  292. void pendelum::rk4_step(double t,double *yin,double *yout,double delta_t)
  293. {
  294. /*
  295.   The function calculates one step of fourth-order-runge-kutta-method
  296.   We will need it for the normal fourth-order-Runge-Kutta-method and
  297.   for RK-method with adaptive stepsize control
  298.  
  299.   The function calculates the value of y(t + delta_t) using fourth-order-RK-method
  300.   Input: time t and the stepsize delta_t, yin (values of phi and v at time t)
  301.   Output: yout (values of phi and v at time t+delta_t)
  302.  
  303.   */
  304. double k1[2],k2[2],k3[2],k4[2],y_k[2];
  305. // Calculation of k1
  306. derivatives(t,yin,yout);
  307. k1[1]=yout[1]*delta_t;
  308. k1[0]=yout[0]*delta_t;
  309. y_k[0]=yin[0]+k1[0]*0.5;
  310. y_k[1]=yin[1]+k1[1]*0.5;
  311. /*Calculation of k2 */
  312. derivatives(t+delta_t*0.5,y_k,yout);
  313. k2[1]=yout[1]*delta_t;
  314. k2[0]=yout[0]*delta_t;
  315. y_k[0]=yin[0]+k2[0]*0.5;
  316. y_k[1]=yin[1]+k2[1]*0.5;
  317. /* Calculation of k3 */
  318. derivatives(t+delta_t*0.5,y_k,yout);
  319. k3[1]=yout[1]*delta_t;
  320. k3[0]=yout[0]*delta_t;
  321. y_k[0]=yin[0]+k3[0];
  322. y_k[1]=yin[1]+k3[1];
  323. /*Calculation of k4 */
  324. derivatives(t+delta_t,y_k,yout);
  325. k4[1]=yout[1]*delta_t;
  326. k4[0]=yout[0]*delta_t;
  327. /*Calculation of new values of phi and v */
  328. yout[0]=yin[0]+1.0/6.0*(k1[0]+2*k2[0]+2*k3[0]+k4[0]);
  329. yout[1]=yin[1]+1.0/6.0*(k1[1]+2*k2[1]+2*k3[1]+k4[1]);
  330. }
  331.  
  332. void pendelum::rk4()
  333. {
  334. /*We are using the fourth-order-Runge-Kutta-algorithm
  335.   We have to calculate the parameters k1, k2, k3, k4 for v and phi,
  336.   so we use to arrays k1[2] and k2[2] for this
  337.   k1[0], k2[0] are the parameters for phi,
  338.   k1[1], k2[1] are the parameters for v
  339.   */
  340.  
  341. int i;
  342. double t_h;
  343. double yout[2],y_h[2]; //k1[2],k2[2],k3[2],k4[2],y_k[2];
  344.  
  345. t_h=0;
  346. y_h[0]=y[0]; //phi
  347. y_h[1]=y[1]; //v
  348. ofstream fout("rk4.out");
  349. fout.setf(ios::scientific);
  350. fout.precision(20);
  351. for(i=1; i<=n; i++){
  352. rk4_step(t_h,y_h,yout,delta_t_roof);
  353. fout<<i*delta_t<<"\t\t"<<yout[0]<<"\t\t"<<yout[1]<<"\n";
  354. t_h+=delta_t_roof;
  355. y_h[0]=yout[0];
  356. y_h[1]=yout[1];
  357. }
  358. fout.close;
  359. }
  360.  
  361.  
  362.  
  363. void pendelum::asc()
  364. {
  365. /*
  366.   We are using the Runge-Kutta-algorithm with adaptive stepsize control
  367.   according to "Numerical Recipes in C", S. 574 ff.
  368.  
  369.   At first we calculate y(x+h) using rk4-method => y1
  370.   Then we calculate y(x+h) using two times rk4-method at x+h/2 and x+h => y2
  371.  
  372.   The difference between these values is called "delta" If it is smaller than a given value,
  373.   we calculate y(x+h) by y2 + (delta)/15 (page 575, Numerical R.)
  374.  
  375.   If delta is not smaller than ... we calculate a new stepsize using
  376.   h_new=(Safety)*h_old*(.../delta)^(0.25) where "Safety" is constant (page 577 N.R.)
  377.   and start again with calculating y(x+h)...
  378.   */
  379. int i;
  380. double t_h,h_alt,h_neu,hh,errmax;
  381. double yout[2],y_h[2],y_m[2],y1[2],y2[2], delta[2], yscal[2];
  382.  
  383. const double eps=1.0e-6;
  384. const double safety=0.9;
  385. const double errcon=6.0e-4;
  386. const double tiny=1.0e-30;
  387.  
  388. t_h=0;
  389. y_h[0]=y[0]; //phi
  390. y_h[1]=y[1]; //v
  391. h_neu=delta_t_roof;
  392. ofstream fout("asc.out");
  393. fout.setf(ios::scientific);
  394. fout.precision(20);
  395. for(i=0;i<=n;i++){
  396. /* The error is scaled against yscal
  397.   We use a yscal of the form yscal = fabs(y[i]) + fabs(h*derivatives[i])
  398.   (N.R. page 567)
  399.   */
  400. derivatives(t_h,y_h,yout);
  401. yscal[0]=fabs(y[0])+fabs(h_neu*yout[0])+tiny;
  402. yscal[1]=fabs(y[1])+fabs(h_neu*yout[1])+tiny;
  403. /* the do-while-loop is used until the */
  404. do{
  405. /* Calculating y2 by two half steps */
  406. h_alt=h_neu;
  407. hh=h_alt*0.5;
  408. rk4_step(t_h, y_h, y_m, hh);
  409. rk4_step(t_h+hh,y_m,y2,hh);
  410. /* Calculating y1 by one normal step */
  411. rk4_step(t_h,y_h,y1,h_alt);
  412. /* Now we have two values for phi and v at the time t_h + h in y2 and y1
  413. We can now calculate the delta for phi and v
  414.   */
  415. delta[0]=fabs(y1[0]-y2[0]);
  416. delta[1]=fabs(y1[1]-y2[1]);
  417. errmax=(delta[0]/yscal[0] > delta[1]/yscal[1] ? delta[0]/yscal[0] : delta[1]/yscal[1]);
  418.  
  419. /*We scale delta against the constant yscal
  420. Then we take the biggest one and call it errmax */
  421. errmax=(double)errmax/eps;
  422. /*We divide errmax by eps and have only */
  423. h_neu=safety*h_alt*exp(-0.25*log(errmax));
  424. }while(errmax>1.0);
  425. /*Now we are outside the do-while-loop and have a delta which is small enough
  426.   So we can calculate the new values of phi and v
  427.   */
  428. yout[0]=y_h[0]+delta[0]/15.0;
  429. yout[1]=y_h[1]+delta[1]/15.0;
  430. fout<<(double)(t_h+h_alt)/omega_0<<"\t\t"<<yout[0]<<"\t\t"<<yout[1]<<"\n";
  431. // Calculating of the new stepsize
  432. h_neu=(errmax > errcon ? safety*h_alt*exp(-0.20*log(errmax)) : 4.0*h_alt);
  433. y_h[0]=yout[0];
  434. y_h[1]=yout[1];
  435. t_h+=h_neu;
  436. }
  437. }
  438.  
  439.  
  440. int main()
  441. {
  442. pendelum testcase;
  443. testcase.initialise();
  444. testcase.euler();
  445. testcase.euler_cromer();
  446. testcase.midpoint();
  447. testcase.euler_richardson();
  448. testcase.half_step();
  449. testcase.rk2();
  450. testcase.rk4();
  451. return 0;
  452. } // end of main function
feel free to PM me
Real Eyes Realize Real Lies
My Resume
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:




Views: 3681 | Replies: 1
Thread Tools Search this Thread



Tag cloud for C++
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC