CS101 Introduction to Computing

Summer 2015

Machine Problem 1

Posted: June 20th, 2015

Due Date:9:00 P.M., Friday July 10, 2015

Part 1: Building with Balloons (and Slinkys)

1. Introduction

You've been hired by the eccentric toymaker and party supplier Mr. Funnstuph of Kansas City to build a monument to his greatness. The monument will be built in Kansas City Missouri. Being the eccentric man that he is, and having not done particularly well in his Physics classes in college, Funnstuph has decided that the best testament to his glory would be a structure composed of his two best-selling items, Slinkys and Happy Helium Balloons. He wants you to build an arch composed of Happy Helium Balloons attached between equal-length Slinkys.

Knowing Slinkys to be way too floppy for your task, you make a desperate attempt at practicality:

"Mr. Funnstuph, I think your monument will be even more... glorious if we use specially made Slinkys."

"Oh? What kind of Slinkys should I use?"

"Well, the structure would look more imposing if you use especially thick Slinkys, and you vary the thickness."

"A brilliant idea! What do you call these modified Slinkys?"

"Springs, sir."

"Springs! What an intriguing label! Seems a little bland, though. Maybe we can market these as some Slinky variant. Springument? Splinky? No, no, how about Monusplink?"

"..."



The purpose of this machine problem is to find spring constants Ki for i = 1, 2, ..., N+1 springs that connect in series with N balloons (see figure below). Every spring should be stretched to an identical length. The computation proceeds by modifying the spring constants Ki so that all the spring lengths are length L/(N+1), L being the total length of all N+1 springs when the system of springs and balloons reach their equilibrium state. The two ends of the system are attached to left and right anchors with heights HL and HR, respectively. We will also find the x and y positions of the attach points of the balloons to the springs and plot the system using MATLAB. Figure 1 shows a system with five balloons. However, your program should handle any number of balloons, not just five, along with anchors of different heights.

Note that realistically (or as realistic as you can get with a monument made with Slinkys and Happy Helium Balloons), the balloons should be attached to the springs but float above the springs. We will be using the point of attachment of the balloons in the calculations, not the balloons themselves, to simplify the calculations. Also, the values Bi for the balloons reflect their lifting force after gravity is factored in, not their gaseous volume or anything complicated. For the purposes of the lab, consider the balloons to be a single point of upward force on the arch between springs, not the bags of gas that they actually are...

arch

Figure 1.

There are 6 tasks that you need to complete in this part:

  1. Write a main function. Note that main returns a value.

  2. Write a function find_d that computes a vector d of horizontal distances between successive balloons from a vector K of spring constants:

    d = [d1 d2 d3 ... dN+1] is of length N+1 (where N is the number of balloons in the system)

    and

    K = [K1 K2 K3 ... KN+1] is also of length N+1.

  3. Write a function build_Xvec that builds a row vector of length N+2, which starts with the x-position of the left anchor, followed by x-positions of the balloons, and ending with the x-position of the right anchor.

  4. Write a function find_h that builds a row vector of length N, of the y-coordinates of the balloons:

    y = [y1 y2 y3 ... yN] is of length N.

  5. Write a function build_Yvec that builds a row vector of length N+2, which starts with the y-position of the left anchor, followed by y-positions of the balloons, and ends with the y-position of the right anchor.

  6. Write a function spr_length that computes a vector of spring lengths from the vectors of x-positions and y-positions of balloons padded with the anchor points.

More detailed instructions and specifications will be given in later parts of this handout.

The data characterizing the system are provided in the file mp1_data.m.

The file contains the following variables:

Important Note: The names for all the functions and variables are case-sensitive, so make sure your functions and variables are named exactly what we specify here!

2. Preparation

  1. Before you start working on the project make sure you have a good understanding of materials covered in lectures 3-6, lab activities 3 and 4, and sections 3.1, 3.2, 4.1, 4.2, and 5.1 of Getting Started with MATLAB.

  2. In order to avoid unexpected errors due to incompatibilities between different versions of MATLAB, please use only MATLAB 7.0 or higher for editing, debugging and checking your programs with the checker.

  3. Copy mp1_data.m  and mp1demo.p  into your home directory. You can run the demo program by typing mp1demo at the MATLAB prompt. The demo program demonstrates how your program should run. It solves the system using mp1_data and makes a plot of the system. You can use the demo to compare your graphs for Parts 1 and 2 (but not Part 3). After you finish coding, you can run your own program by typing main at the MATLAB command prompt.

    After opening MATLAB, run the mp1_data script by typing mp1_data at the MATLAB prompt. After running the script, check to make sure that the variables N, L, K, B, HL, HR, and D have been defined for you to use in MATLAB. Feel free to modify the values in mp1_data to test if your program can handle varying values.

  4. We have provided a checker program for you. In order to run the checker, type mp1_check at the Matlab prompt. The checker has a menu where you can select which function to check (of course you must have completed the function first). Always check and verify each of your completed functions before moving on to the next.

3. Math

4. Implementation

Step 1

Step 2 (find_d.m)

Step 3 (build_Xvec.m)

Step 4 (find_h.m)

Step 5 (build_Yvec.m)

Step 6 (spr_length.m)

Step 7

Step 8

Troubleshooting

If your arch doesn't converge, what should you do?



Part 2: spdiags: It's All So Empty...

1. Introduction to spdiags and Sparse Matrices

Now we're going to perform a little optimization. Notice that the coefficient matrix we create to solve the system of equations in find_h can have a lot of zeroes if there is a large number of weights. This can bog down calculations, because MATLAB will spend the time to use each of those zeroes, even though they don't do anything, and they also take up space because MATLAB stores them as part of the matrix. The solution to this is to use something called a sparse matrix. Sparse matrices store only the non-zero elements; all other elements are assumed to be zero. This saves on storage space for matrices with lots of zeroes, and it also speeds up computation, since MATLAB will simply ignore the non-existent zeroes in the sparse matrix when doing matrix multiplication.

To create sparse matrices, we'll use the command "spdiags", which will replace diag. spdiags is a tad more complicated (but more powerful) than diag. The format for using spdiags is spdiags(D, c, m, n), where:

That is, spdiags will take each column of the D matrix and place it on the diagonal indicated by the control vector in an m x n sized matrix. Here's an example of how it works. First, we construct a matrix with the diagonal columns:

>> D = [1:5; 6:10; 11:15]'
D =
1 6 11
2 7 12
3 8 13
4 9 14
5 10 15

Note the three columns of D. We're going to use the columns as diagonals in a 5 x 5 matrix:

>> A1 = spdiags(D, [0 1 -2], 5, 5)
A1 =
(1,1) 1
(3,1) 11
(1,2) 7
(2,2) 2
(4,2) 12
(2,3) 8
(3,3) 3
(5,3) 13
(3,4) 9
(4,4) 4
(4,5) 10
(5,5) 5

Yes, A1 is actually a matrix. This is how MATLAB displays sparse matrices, as a list of indices with their values. Any index location in the matrix that isn't listed above, like A1(1,3), is implied to be a zero. However, this isn't a particularly good format for viewing the matrix, so let's multiply A1 with an non-sparse identity matrix to force it into the standard matrix format:

>> A2 = A1 * eye(5)
A2 =
1 7 0 0 0
0 2 8 0 0
11 0 3 9 0
0 12 0 4 10
0 0 13 0 5

A2 is the same matrix as A1, except in non-sparse form. How did the columns of D turn into the diagonals of A2? Let's break it down some more, using the same data as above:

spdiags

Figure 3.

Given D, c, m, and n, the resulting matrix A from spdiags is of m x n size. Each column of D is used to create a new diagonal. The first column is on the main diagonal of A, the second column is on the first upper diagonal, and the third column is on the second lower diagonal. How did they get there? Note the control vector c: 0 for the first value, corresponding to the main diagonal, 1 for the second value (first upper diagonal), and -2 for the last value (second lower diagonal). Thus, the c vector controls which diagonal the columns of D appear in A.

But wait, you may (should) be saying. How do the diagonals get created if the column of D isn't the same size as the diagonal it's being used for? How did the second column of D end up on the first upper diagonal of A if the column has five elements to the diagonal's four? The solution is that MATLAB will drop values from the D columns to make the diagonal fit. In the case of upper diagonals, the values are dropped starting from the top of the column matrix. Thus, the 6 from the second column of D was discarded, and 7 through 10 were used to make the diagonal. Similarly, in the case of lower diagonals, values are dropped starting from the bottom of the column matrix. For the second lower diagonal, 14 and 15 were dropped, while 11 through 13 were used.

2. Implementation

Now let's put all that newfound knowledge of spdiags to good use. Create a new function called "find_h2" and store it in a file called "find_h2.m". This function will take the same parameters as find_h, in the same order. You can copy most of the code over from find_h. The constants vector remains unchanged and the calculation to find the h values remains unchanged. However, instead of using multiple "diag" calls to create your coefficients matrix, now you will use a single call to "spdiags" to create a sparse version of your matrix. That is, make your own columns matrix and control vector, then feed them to spdiags along with the appropriate values for the matrix dimensions to get the same coefficients matrix as before, but in sparse form.

Now, change main.m to use find_h2. Comment out the line for find_h (put a "%" in front of it), and put a new line under it that calls find_h2 and assigns the result to h.

error = 1;
while error > 1.0e-5
% some function calls here
% h = commented-out call to find_h
h = % call to find_h2 here
% your call to spr_length here
% command to plot system with blue lines and points
axis equal
pause(0.1)
% modify K here
% calculate error here
end
% this is necessary to check the plots
handles(1) = h1;
% handles(2) is needed for the extra credit, so it is 0 for now
handles(2) = 0;

If you'd like to test how the sparse matrix affects calculation speed, modify your mp1_data file and set N to some high number (say, 1000). Try running main with both find_h and find_h2 (commenting out one or the other in main.m). You'll notice a significant slowdown with find_h compared to find_h2.

When handing in your solution, make sure that find_h is commented out (not deleted, since we want to see that you called it in part 1) and that find_h2 is the function that your main.m is calling.



Part 3: Extra Credit: Extra credit is an optional part of MP1. It is worth 5 points.

Trouble brewing in Saint Louis


After doing endless tinkering with the springs and balloons, you've finally found a configuration of the arch in Kansas City that Mr. Funnstuph thinks is pleasant. But wait! Could the well-known arch of St. Louis Missouri be exactly the same shape as Mr. Funnstuph's arch?

The mayor of St. Louis has sent you a copy of their top-secret formula to create their arch, so you can compare to your arch and see if they're the same. Modify mp1_data to use Mr. Funnstuph's preferred numbers:

1. Math


The shape of the arch in St. Louis is defined by the equation of a reversed catenary curve:

curve (equation_6)

where Tis a horizontal tension, and Wis a weight of one foot of the curve, depending on the material from what the arch is made.

For the right and left anchors of Kansas City arch this equation looks like:

equation

W

where XLand XRare horizontal coordinates of the left and right anchors relative to the midpoint of the arch, XC. Subtracting HRfrom HLand dividing both parts of the equation by T/Wwe get:

equation

since equation, the right-hand side can be rewritten as:

equation_7 (equation_7)

The length of the curve can be determined by the following expression:

L

where:

equation

Therefore

equation,

Dividing both sides of the above equation by T/W, we get:

equation_8. (equation_8)

Since equation_9, equation 7 can be rewritten:

equation_9 (equation_9)

Dividing both sides of equation 7 by equation 9:

equation

Since equation_10, the second term of the right-hand side of equation 7 can be rewritten as:

equation, so the whole equation 7 looks like:

equation 10 (equation_10)

Replacing W/Twith t , we define the function f(t) as follows:

equation_11 (equation_11)

2. Implementation


Step 1

Write a function called stlouis_aux that takes an input parameter t and computes the value f(t) from equation 11 above, where XR = D, and XL = 0. Note, that you should call mp1_data script in the first line of the function stlouis_aux in order to obtain values for HR, HL and L.





Step 2

Next write the function called stlouis, which plots the catenary curve defined by



equation

where in equation 11 we defined t = W/T. The first twos lines of this function is,

function h2 = stlouis()
mp1_data;
hold on


We will have to first compute values t =W/T , XC and A. As in parts 1 and 2, function stlouis should return the result of calling the plot function to plot the catenary curve. In order to plot the graph, you need to compute the following values:


1. In equation 11 we defined t = W/T. We can find t by solving the equation f(t) = 0 for t ( f(t) is defined above; use fzero with an initial guess of .1). Note that we named the function f , stlouis_aux in our code in step 1.




2. Once we know t we can then solve for XC by using the formula,
XC




3. Knowing both t and XC we can now solve for A,
A

4. Plot the catenary in red using the equationy where x is a vector of 100 evenly spaced values between 0 and D and assign the result of calling the plot function to the output parameter of stlouis.

h2 = plot(....);

Step 3

Change the last line of the main function from:

   handles(2) = 0;

to

   handles(2) = stlouis;

to see if the arches match. Run your program by typing

>> main


at the Matlab prompt. Chances are they are not quite the same...

Mr. Funnstuph: "Ha! It's not the same at all!"

You: "But sir, we're only using this number of balloons as a test. The real arch uses many more balloons. We're just not using enough data points..."

Mr. Funnstuph: "Shh! Be quiet!"



Step 4


Now modify your mp1_data and set the number of balloons to 100 (N = 100). Run main and stlouis again and see how close the arches are.

Mr. Funnstuph: "Oh, shoot."



Part 4: No More Balloons...

Looks like Mr. Funnstuph can't make his monument of toys after all. We're going to have to confiscate all the materials...

Before you hand over your programs, though, make sure that each file has your name and section as a comment at the top of the file. Also, provide enough comments to make the program understandable. This means comments on the purpose of each function or script, including what they take as input and what they return as output. This should be done for functions as helpful information directly below the function definition line (see Lab 3, Section C for more details). Scripts can just have comments for major sections. Note that the comments should be an overview and explanation, not a line-by-line recap of the program (so comments that are twice as long as the function are bad). Please don't try to comment every line of code.

Part 5: Grading Scheme

Everything working perfectly (correct answers and graph plotted right) = 50 points. The grading is based on a per function basis. Each function is graded on an all or nothing basis. The table below lists points per function.

Function

Points

find_d

5

build_Xvec

6

find_h2

7

build_Yvec

5

spr_length

5

main

15

comments

7

Total (w/o Extra Credit)

50

stlouis, stlouis_aux

9

comments

1

Total (Extra Credit)

10



Hand in Procedure

Click here for handin instructions.
That's it! You're done!

sad (Aww, you don't want to play with the balloons anymore?)