Lab 2: Matrix Manipulation and Fluid Diffusion

In class we talked about ways of organizing our approach to a problem, and also a collection of new matlab commands. Today we are going to start practicing with arrays.

    Problems
  1. Given nonzero integers n and k, build an array that looks like this:
    1 n+1 ...
    2 n+2 ...
    3 n+3 ...
    4 n+4 ...
    .  .  ...
    n 2n  ... nk
    
    For example, if n = 3 and k = 4, you'll get:
    1 4 7 10
    2 5 8 11
    3 6 9 12
    
    Hint: use 1:(n*k) and the "reshape" command.

  2. Now take that array and "pad" it with zeroes, i.e., make an (n+2) x (k+2) array whose central n x k block is the matrix above. Continuing our example above, the matrix would look like this:
    0 0 0 0 0  0
    0 1 4 7 10 0
    0 2 5 8 11 0
    0 3 6 9 12 0
    0 0 0 0 0  0
    
  3. Write a function res = pad(m) that does the following transformation in general: If m is the matrix
    1 3 5
    2 4 6
    then res is the matrix
    1 1 3 5 5
    1 1 3 5 5
    2 2 4 6 6
    2 2 4 6 6
    i.e., surrounds a matrix with a ring of numbers each of which is the same as the original array element that's closest to it. Hint: When you add the ring of numbers start by adding the new rows. Then add the new columns.
Check in with the TA and show that your "pad" function works.
Diffusion

Suppose we have a drop of ink in a dish of water. Over time, the ink diffuses into the water. We can model this in matlab by representing the dish of ink with an array of "little bits of water". Each one has a "concentration of ink" in it. For example, if the dish pure water, except for one spot of pure ink in the middle, the center element of the array has concentration 1, and all other elements have concentration zero. We want to simulate how the ink will diffuse, by updating the ink positions bit by bit. The way we update the picture is this.

We imagine that some particles in adjacent bits of fluid move into neighboring bits. So, particles from m(i,j) move to their 4 neighbors m(i+1,j), m(i-1,j), m(i,j+1), and m(i,j-1), Let's call each "bit of fluid" a "cell". Well, just as particles are moving from cell (i, j) to cell (i + 1, j), other particles are moving from cell (i + 1, j) to cell (i, j). The result of this is that after a short time, the concentration of ink in cell (i, j) changes with this rule:

cnew(i, j) = (1 - K) * cold(i, j) + K * average(neighbors)
where K is some constant depending on the fluid. (Things diffuse more slowly in honey than in in water, for instance). We'll use K = .5.

Task: Given a matrix m containing concentrations of ink, write a function res = diffusion(m) that contains the new concentrations, after one diffusion step.

Tricky issue: What will you do at the boundary of m? For example, how should you update m(1, 1)? It doesn#t have any neighbors to the left or above it! You should do the following: assume that the values in the neighbors to the left and above are the SAME as the current value of in m(1, 1), and similarly for other edge cells. (Hint: The last part of the previous problem might be helpful here!) (Optional) check in with the TA and show that your diffusion function works.

Task: Write a function diffusiondemo(n) that does the following:

  1. Makes an (2n + 1) x (2n + 1) array filled with zeros.
  2. Puts a "1" in the center element of the array. (Which element is that???)
  3. 100 times, does the following:
    1. Displays the array using imagesc or surf
    2. Pauses for .2 seconds (you may adjust this if you want it faster or slower) (hint: see the doc for pause)
    3. Updates the array using your diffusion funtion
Run your program with n = 10 and see what happens.

Task: Adjust your program to have various initial concentrations, and various different values of K ranging from 0 to 1. Again observe the behavior. Check in with the TA and show that your diffusiondemo function works.

Task: Suppose that after each diffusion step, you added more ink at the center so that the concentration again became 1.0 there. You'd get a very different result. Write a new version of your program, diffusiondemo2(initial) that takes an initial array whose non-zero elements are "concentration sources", i.e., they are points where after diffusion, the concentration is automatically readjusted to have the value it had in the initial array (perhaps ink is continuously being added to the fluid at this point). Observe the behavior and comment.

Hints:

  • Start by writing out a plan of attack. (either in comments or on some scratch paper). You may want to show these to a TA if you not confident that you have the right steps.
  • You'll need to keep a copy of the initial values so that you can reuse them to recopy the non-zero elements into the diffused array.
  • Think about how you can find the non-zero elements (of the initial array) in one line of code.