MIT OpenCourseWare http://ocw.mit.edu 12.010 Computational Methods of Scientific Programming Fall 2007 For information about citing these materials or our Terms of Use, visit: http://ocw.mit.edu/terms.
12.010 Homework #3 Due Tuesday, October 30, 2007 Question (1) (25-points) (a) Write, compile and run a C/C++ program which generates a table of Bessel functions of the first kind for integer orders between 0 and 5, and argument between 0 and 10 in steps of 1.0. Bessel functions of the first kind satisfy the following differential equation: 2 2 d y dy 2 2 x + x + (x " n )y = 0 dx 2 dx where the function y is the Bessel function of order n. (see http://mathworld.wolfram.com/besselfunctionofthefirstkind.html for information on Bessel function ). Bessel functions are rarely computed by directly the solving the differential equation. The values in the table should be given with 5 decimal places. The table should have headers explaining what the columns are. Explain how you designed the program and give an example of the output. (b) How would you change this program if 10 significant digits were required? C/C++ source code and example output should also be supplied The main decision to be made here is how to implement the evaluation of the Bessel function. Additional considerations are the formatting of the table but this is relatively easy in C/C++. The solution to this problem follows the same method as used in the fortran solution. In this case, we added passing the number of orders to compute and the number of significant digits to the runstring i.e., these values can be passed to the program at run time. A similar procedure could have been in the fortran program as well although there can be some system dependence on the methods used to read the runstring. The http://mathworld.wolfram.com/besselfunctionofthefirstkind.html gives the series expansion of the Bessel Function of the first kind. From equation 46 we have # l ("1) 2l+ m J m (x) = $ x m integer 2l + m l=0 2 l!( m + l)! This formula will work for all values of the argument x. To implement this equation we note the sum is to infinity, which will take a long time to compute. So we need to decide on the number of terms to include. As we look at the expression, for x <1 the series is well behaved in that as l goes to infinity, x 2l+m will go to zero (i.e., the terms get smaller and smaller). However for x >1, x 2l+m will go to infinity as l goes to infinity. These ever increasing values are reduced in size by the l! and (m+l)! in the denominator. The magnitudes of l! and (m+l)! could cause problems. (m+l)! grows rapidly and will lead to overflow of integer*4 when there are enough terms in the series. Sample calculations of the series suggest at for x=10.0, l+m should be 32 to obtain 10-6 accuracy in the calculation. Factorial(32) is 2.6x10 35 which 25-orders of magnitude larger than the
maximum value possible with long. Therefore although factorial in an integer, it will need to be computed as a double in this calculation. Another aspect of this series is the alternating sign (-1) l. For arguments greater than 1, the series will be summing and subtracting numbers that are large and this can introduce rounding errors. Code design: The major issue with accuracy of the series calculations and factorial magnitude were discussed above. The major components of the code are to (1) Output table headers so that the user knows what is being tabulated. In this code, the number of orders and number of significant digits can specified and so the formats for output are generated as strings and used to write out the results and header. (2) Functions to evaluate the Bessel function. In my implementation, the besselfunction functions evaluates how many terms are needed to obtain the accuracy set by the number of significant digits in the output (eps). The number of terms for each argument varies because of this. (3) Function needed to evaluate factorial. As noted above this is a real*8 function to ensure that the result does not overflow. Solution: The C code I used is linked to hw2_1_07.c. The output of my program is given below. G4-Computer[453] cc hw3_1_07.c -o hw3_1_07c G4-Computer[455] hw3_1_07c TABLE OF BESSELL FUNCTION FROM ORDER 0 to 5 Arg J00 J01 J02 J03 J04 J05 0.00 1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 1.00 0.76520 0.44005 0.11490 0.01956 0.00248 0.00025 2.00 0.22389 0.57672 0.35283 0.12894 0.03400 0.00704 3.00-0.26005 0.33906 0.48609 0.30906 0.13203 0.04303 4.00-0.39715-0.06604 0.36413 0.43017 0.28113 0.13209 5.00-0.17760-0.32758 0.04657 0.36483 0.39123 0.26114 6.00 0.15065-0.27668-0.24287 0.11477 0.35764 0.36209 7.00 0.30008-0.00468-0.30142-0.16756 0.15780 0.34790 8.00 0.17165 0.23464-0.11299-0.29113-0.10536 0.18577 9.00-0.09033 0.24531 0.14485-0.18094-0.26547-0.05504 10.00-0.24594 0.04347 0.25463 0.05838-0.21960-0.23406 How would you change this program if 10 significant digits were required? Several changes would be needed to output to 10-signifciant digits. (1) The double arguments would needed (already coded that way) (2) The formats would need to change for the extra digits. Code currently does that through generating its own formats. (3) The headings format would need to be changed to re-align the columns. Again done in code.
Example below is for 10-significant digits. (Only 0-3 orders are output so that table would fit. G4-Computer[456] hw3_1_07c 3 10 TABLE OF BESSELL FUNCTION FROM ORDER 0 to 3 Arg J00 J01 J02 J03 0.00 1.0000000000 0.0000000000 0.0000000000 0.0000000000 1.00 0.7651976866 0.4400505857 0.1149034849 0.0195633540 2.00 0.2238907791 0.5767248078 0.3528340286 0.1289432495 3.00-0.2600519549 0.3390589585 0.4860912606 0.3090627223 4.00-0.3971498099-0.0660433280 0.3641281459 0.4301714739 5.00-0.1775967713-0.3275791376 0.0465651163 0.3648312306 6.00 0.1506452573-0.2766838581-0.2428732100 0.1147683848 7.00 0.3000792705-0.0046828235-0.3014172201-0.1675555880 8.00 0.1716508071 0.2346363469-0.1129917204-0.2911322071 9.00-0.0903336112 0.2453117866 0.1448473415-0.1809351903 10.00-0.2459357645 0.0434727462 0.2546303137 0.0583793793 Question (2): (25-points). Write a C/C++ program that reads a file containing text, counts the number of characters (letters a-z) and words in the text, and output the text with capital letters at the beginning of each sentence. The text below is contained in the file Q2_text.txt. we take as a self evident foundational principle that the set of effects to be considered as contributing to local station displacements and the conventional models to be applied for their compensation should be guided by rational and well considered bases, and should not be developed haphazardly or randomly. for historical reasons and general consistency, it might be prudent to retain some past practices even if they are not fully consistent with the adopted principles; but future expansions should be determined by specified rules. this position paper proposes such a set of guidelines and rationales for iers Conventions updates. Hints: You might look for toupper and tolower as part of the ctype.h header file Remember if reads are coded as scanf or fscanf using sidin then the file Q2_text.txt can be re-directed into the program using: Q2C < Q2text.txt where Q2C is the name of the program (you can call the program any name you like). Again a nominally easy program but we will clearly need a few utility subroutines to perform various tasks. There are several approaches that could be used. The file could be read line by line using fscanf as in the fortran solution. The solution adopted reads the file character by character and manipulates and counts characters as they are read. In the way C character reads work, the newline character is read (\n) and when output causes a new line to start. In the program, the name of the file to be processed is passed in the runstring with a default name of Q2_text.txt. Code design Get the name of the file from the runstring or use the default name. Use fopen to get a file pointer to the file. Report an error if the file pointer returns NULL
Loop over reading characters from file until an EOF is returned. Count characters and words Capitalize as needed in output updated line At end of program output final counts. hw2_2_07.c G4-Computer[452] cc hw3_2_07.c -o hw3_2_07c G4-Computer[457] hw3_2_07c 12.010 HW 3 Q2: Reading file Q2_text.txt Text capitalized We take as a self evident foundational principle that the set of effects to be considered as contributing to local station displacements and the conventional models to be applied for their compensation should be guided by rational and well considered bases, and should not be developed. Haphazardly or randomly. For historical reasons and general consistency, it might be prudent to retain some past practices even if they are not fully consistent with the adopted principles; but future expansions should be determined by specified rules. This position paper proposes such a set of guidelines and rationales for iers conventions updates. Letter count 533 Word count 99 Total file 642 Question (3): (50-points) Write a C/C++ program that will compute the motion of a baseball in 2-dimensions. The program should generate the trajectory of the ball and compute the change in height of the ball from where it is initially released and home plate 18.44 m away and the velocity at home plate. The dynamical forces acting on the baseball are: Wind Drag r F d = "1/2A r C d (v)#vv (v"vd)/ $ C d (v) = 0.2 +0.4 /(1+ e ) r r Magnus force F m = S(v)% & v S(v) = 4.1&10 "4 m Question (3): (50-points) Write a C/C++ program that will compute the motion of a baseball in 2-dimensions. The program should generate the trajectory of the ball and compute the change in height of the ball from where it is initially released and home plate 18.44 m away and the velocity at home plate. The dynamical forces acting on the baseball are:
Wind Drag r F d = "1/2A r C d (v)#vv (v"vd)/ $ C d (v) = 0.2 +0.4 /(1+ e ) r r Magnus force F = S(v)% & v m S(v) = 4.1&10 "4 m where A r is the cross-sectional area of the ball, C d is the drag coefficient which depends on the velocity, v, of the ball, ρ is the density of air. The drag coefficient depends on velocity with vd =35 m/s and Δ=5m/s. The Magnus force, F m is the lift force due to the rotation of the ball ω. S is a scaling coefficient for the Magnus force with m being the mass of the baseball. Although S probably depends on velocity, in this problem we will assume that it is constant. (see discussion in: http://farside.ph.utexas.edu/teaching/329/lectures/node43.html ) In your problem, the rotation vector will be perpendicular to the velocity vector (i.e., horizontal) and hence the Magnus force will only lift or depress the ball and not move it out of its plane of motion. As a test of your program use the following constants to compute the trajectory of the ball: Assume the following values Baseball circumference 23 cm Baseball mass (m) 150g ρ = 1.226 kg/m 3 g = 9.8 m/s 2 Initial release angle +1 deg Initial velocity 85 mph Spin rate 1800 rpm (counter clockwise so ball will lift). The height at home plate should be calculated to an accuracy of 1mm. Hint: Be very careful with units (there are all mixed above). Your answer to this question should include: (a) The algorithms used and the design of your program (b) The C/C++ program source code (I will compile and run your programs). (c) The results from the test case above that will include the change in height from release to home plate (18.44 m) and the velocity at home plate. With these equations, we can compute the forces acting on the plane (gravity, Magnus force and drag) and using the mass of the ball, compute accelerations. By integrating the accelerations we generate velocity changes and by integrating the velocity changes we get position changes. Since the forces depend on velocity, we need to integrate in small steps. Precisely how small we discuss below. This problem is basically an integration
problem. It can also be posed as the solution to a second-order differential equation and in later homework (and languages) we will how to solve it this way. This solution follows the method in the Fortran program. There is an include file that has global constants in that can be used by all functions (cbaseball.h). In the fortran program we used complex variables to hold 2-D data such as positions, velocities and accelerations. We could have introduced structures into C, which would allow the same approach but decided to use 2-element arrays for these quantities. With this method, we can not return values directly from functions (unless separate calls were made for each component) so instead we return results through the call arguments. Arrays are pointers so this works easily. The basic flow of the program is to: -Read the inputs fro the user. These reads are ordered such that those quantities most likely to be changed by the user. These values have defaults and so the user only needs to use /<cr> to adopt the defaults. The routine GetIn is coded to work like the fortran reads. - Trial integrations with decreasing step sizes to determine the step size needed to hit the ground within a specific accuracy. - Note the code that tests for the ball arriving at home plate. The integration step size is reduced so that we converge onto home plate - Once the step size is set, run with the final step size and output results. (This later step is a little inefficient since it repeats an earlier calculation but with output generated this time. Output the final height change to home plate and the velocity at home plate. The program in implemented is given in hw2_3_07.c. It also uses an include file cbaseball.h that contains parameters for gravity values, air density etc and a common block that contains the fixed: variables in the program (object mass, etc.) Example output for test case:
G4-Computer[451] cc hw3_3_07.c -o hw3_3_07c G4-Computer[460] hw3_3_07c 12.010 Program to solve baseball trajectory problem Given initial velocity, release angle and spin rate the time to homeplate and speed at homeplate are computed. Do you want to change defaults (y/n) n PROGRAM PARAMETERS ++++++++++++++++++ Pitch velocity: 38.00 m/s, Angle 1.0 deg, Spin Rate 188.50 rads/s MASS 0.1500 kg, Area 0.004 m^2 GRAVITY 9.80000 m/s**2 RHO AIR 1.22500 kg/m**3] Step Heights -0.566197-0.566197 Delta (mm) 0.000017 T* Time X_pos Z_pos X_vel Z_vel T* (sec) (m) (m) (m/s) (m/s) T 0.000 0.0000 0.0000 37.9926 0.6632 T 0.050 1.8890 0.0244 37.5666 0.3137 T 0.100 3.7567 0.0314 37.1418-0.0336 T 0.150 5.6032 0.0211 36.7184-0.3785 T 0.200 7.4285-0.0064 36.2967-0.7210 T 0.250 9.2329-0.0510 35.8768-1.0611 T 0.300 11.0163-0.1125 35.4590-1.3987 T 0.350 12.7788-0.1908 35.0435-1.7338 T 0.400 14.5207-0.2858 34.6307-2.0662 T 0.450 16.2419-0.3974 34.2208-2.3961 T 0.500 17.9428-0.5254 33.8141-2.7233 T 0.510 18.2711-0.5522 33.7355-2.7866 T 0.513 18.3837-0.5615 33.7085-2.8083 T 0.514 18.4212-0.5646 33.6995-2.8156 T 0.515 18.4337-0.5657 33.6965-2.8180 T 0.515 18.4379-0.5660 33.6955-2.8188 T 0.515 18.4393-0.5661 33.6952-2.8190 T 0.515 18.4398-0.5662 33.6950-2.8191 T 0.515 18.4399-0.5662 33.6950-2.8192 C 0.515 18.4401-0.5662 33.6950-2.8192 Step (s) 0.009720 0.003338 0.001114 0.000372 0.000124 0.000041 0.000014 0.000005 0.000002 Final Height change -0.5662 m; Velocity 75.6 mph Angle -4.78 deg