943,949 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 4068
  • C++ RSS
Jul 14th, 2004
0

summations and combinations

Expand Post »
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!
Similar Threads
Reputation Points: 11
Solved Threads: 0
Newbie Poster
ellisrn is offline Offline
6 posts
since Jul 2004
Jul 17th, 2004
0

Re: summations and combinations

this is my assignment in the past ..
C++ Syntax (Toggle Plain Text)
  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
Team Colleague
Reputation Points: 55
Solved Threads: 3
Junior Poster
meabed is offline Offline
139 posts
since May 2004

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: How to use combobox function
Next Thread in C++ Forum Timeline: Double Linked Lists and Functions required





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC