3

I've run into a problem where I have an ordered array of sets of coordinates, for example:

OrderedArray = {{{70.8938, 216.539},{70.89,216.54}}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {{71.0656,216.573}}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {{67.6546, 220.338}}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {{70.9211, 216.364}}, {{70.9184, 216.346}}, {{70.9079, 216.349}}, {{70.9046, 216.335}}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {{70.951, 216.705}}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {{70.9621,216.586}}, {{70.918, 216.576}}, {{70.9116, 216.559}}, {{70.9189,216.581}}, {{70.9115, 216.565}}, {{70.9294, 216.552}}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {{67.0276, 218.154}}};

Note that some elements (here the first) contain more than a single coordinate.

And I need to fill in the blanks, i.e. the {} positions, via some interpolation procedure. What would be the best way to do this? Reading through the instructions for InterpolatingPolynomial (for example), and playing around a bit, it isn't immediately clear how to do this. Ideally I'd like to be able to specify that the "gaps" should be filled in assuming a linear curve, or a polynomial of some order.

Sparse Pine
  • 1,133
  • 6
  • 13
  • 1
    "Note that some elements (here the first) contain more than a single coordinate." -- what do these represent? – Mr.Wizard Jul 27 '13 at 08:48
  • Possible duplicate: (20994) – Mr.Wizard Jul 27 '13 at 08:49
  • @Mr.Wizard These elements represents sets of coordinates for objects in particular frames of a movie. The blank {} spots represent the lack of an identified object in a frame. We're tracking the motion of an object from frame to frame with a sloppy identification technique that doesn't always work and sometimes falsely identifies multiple objects. – Sparse Pine Jul 27 '13 at 08:49
  • Okay, but how are multiple coordinates to be handled? – Mr.Wizard Jul 27 '13 at 08:52
  • @Mr.Wizard In the simplest case, the coordinates can be averaged, or a median can be calculated. However, I left this unspecified under the assumption that Mathematica' interpolation procedure could utilize the multiple data points for something like a least squares fit to the data. – Sparse Pine Jul 27 '13 at 08:55
  • Okay, I think I should let someone else answer this. If you don't have your algorithm nailed down perhaps you could ask on http://stats.stackexchange.com/ ? – Mr.Wizard Jul 27 '13 at 08:59
  • @Mr.Wizard I would be fine allowing for linear interpolation to fill in the gaps (i.e. the {} entries in the array) and simply calculating a median for the redundant data values as a preprocessing step. My goal here is to find a good Mathematica solution that's compact. – Sparse Pine Jul 27 '13 at 09:03
  • @Kuba Thanks - the difference here is that the sizes of the gaps are not predefined. – Sparse Pine Jul 27 '13 at 09:10
  • Did you have look at fitting a model to your data and using the function returned by the "BestFit" parameter to fill in the gaps? Maybe NonlinearModelFit is suitable for your case. – g3kk0 Jul 27 '13 at 09:20

2 Answers2

4

I believe this may do what you desire:

f[x : {{_, _} ..}, y_] := {y, Mean@x}
f[{}, _] := Sequence[]

if = Interpolation[MapIndexed[f, OrderedArray], InterpolationOrder -> 1];

Array[if, Length@OrderedArray] // ListLinePlot

enter image description here

The filled array is produced by Array[if, Length @ OrderedArray].

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • Is there a way in which to remove points / edges that are longer than a certain length? – Sparse Pine Jul 27 '13 at 09:28
  • I like the method a lot, but little bits of noise can really ruin the image. – Sparse Pine Jul 27 '13 at 09:30
  • @SparsePine Sure, but that's probably best as a separate question, if it's not already somewhere on this site. – Mr.Wizard Jul 27 '13 at 09:31
  • @SparsePine Thanks, don't be so quick to Accept an answer; it can discourage other, better, answers. I suggest all users wait 24 hours to let everyone have a chance to reply. – Mr.Wizard Jul 27 '13 at 09:36
1

This is my approach:

Edit Sequence added in order to avoid Flatten. Also it seems to work only for V9.

 seg = Split@OrderedArray /. x : {{} ..} :> Length@x (*counting gaps*)
 seg = seg  /. y : {{_, _} ..} :> Mean@y // Flatten[#, 1] & (*averaging multiple points*)

 f[x : {_, _}, _] := x (* ordinary coordinates with no affect*)
 f[x_, {y_}] := Sequence @@ Array[# &, x + 2, seg[[{y - 1, y + 1}]] ][[2 ;; -2]]
                (* "counts"-> interpolation via Array*)
 MapIndexed[f, seg, {1}]
Kuba
  • 136,707
  • 13
  • 279
  • 740