Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have the particle movement data in the following format:

{
 {1., 1., 0., 0.},
 {1., 2., 0.240727, 0.974106},
 {1., 3., 0.0215366, 0.703085},
 {1., 4., 0.437541, 1.19085},
 {2., 1., 0., 0.},
 {2., 2., -2.17808, 0.455328},
 {2., 3., -2.97556, -0.668351},
 {2., 4., -3.91848, -1.25396},
 {3., 1., 0., 0.},
 {3., 2., -0.523589, 0.136621},
 {3., 3., -1.87956, 0.679403},
 {3., 4., -2.36116, 0.749859}
}

The first number is the particle number, second is the frame number in the movie, third is the $x$ position, and the fourth is the $y$-position. So in the above data, the first 4 lists belong to particle 1, the next 4 to particle 2 and the last 4 to particle 3.

I need to calculate the mean square displacement (MSD) $(x_2-x_1)^2 + (y_2-y_1)^2$ for each of the particles separately. I can calculate MSD if I don't have to care about the above data having 3 particles, treat all as the same (but that's not what I want). I need to calculate MSD for each of these particles separately. Basically, somehow I have to tell the program where the the data for particle 1 end and where data for particle 2 starts.

In MATLAB, I have used the find function to return the location index of the number "1" in the second column of the data and run the loop till that index to calculate MSD for each particle.

I am new to Mathematica and trying to learn it. It's taking me a while to find a answer to this problem. Can anyone help?

share|improve this question

1 Answer 1

Let's break down the task step by step.

  1. Separate the data for the different particles: GatherBy
  2. Sort data by frame number (not really necessary as it's sorted, but let's do it anyway): SortBy
  3. Extract the positions and calculate the MSD.

I have your data stored in the variable data.

GatherBy[data, First] separates into sublists having the same first element (same particle). Let's take the first sublist, sublist = First@GatherBy[data, First].

sublist = SortBy[sublist, #[[2]]&] sorts the sublist by the second element (frame number).

Now take the difference of sequential coordinates, take the squared norm of that difference, and calculate the mean: Mean[#.#& /@ sublist[[All, {3,4}]] ].

Putting it all together:

gatheredData = GatherBy[data, First];

msd = Function[sublist, 
  Mean[#.# & /@ 
    Differences@SortBy[sublist, #[[2]] &][[All, {3, 4}]]
  ]
] /@ gatheredData

You may wish to pair up this list of results with the particle indices:

Transpose[{gatheredData[[All, 1, 1]], msd}]

(* ==> {{1., 0.513101}, {2., 2.69401}, {3., 0.887661}} *)

Again, this is not necessary if your list was originally sorted by particle index, but it's important if it wasn't.


Recommended reading to understand this code:

share|improve this answer
    
Thank you for your answer. I do get most of it. I still get confused by the syntaxes in mathematica, but I will read the documentation and try to make complete sense of this. –  Anjil Dec 19 '13 at 19:55
    
@Anjil It's helpful to read code from "outside to inside". First just look at Function[...] /@ gatheredData. Now try t understand what that function does by using it on a single element of gatheredData. You'll see that that's just what I wrote in the first part of the answer. Keep moving inward in the expression to understand what's going on. –  Szabolcs Dec 19 '13 at 19:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.