I want to apply a function f to a list with fixed intervals, and then fill the gaps of the resulting list, as shown in the following picture. Since it will be run many times, it needs to be fast. The list has coordinates as its elements, which means for example a = {1.0, 2.0, 3.0}. enter image description here

The motivation for this question is this. Because applying the function f to many elements is time-consuming, so I apply f to a smaller subset of the list. The subset is considered to be an approximation of the full list. To achieve this, the elements can be thought of having an influence range. For this case, an element can influnce its left and right neighbors. If the resulting list does not have the same length with the original list, it should be filled to match with the original list.


closed as unclear what you're asking by Dr. belisarius, m_goldberg, Sjoerd C. de Vries, dr.blochwave, Bob Hanlon Jul 16 '15 at 17:51

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • $\begingroup$ how should it fill the gaps if the sequence is f /@ {1,3,5,7...}? $\endgroup$ – Dr. belisarius Jul 16 '15 at 4:50
  • $\begingroup$ And what if the length of the list in your example is 9 ... you should add f@10, but the 10 isn't there and also you haven't specified that the list elements are integers, so one could suspect that the problem is underspecified $\endgroup$ – Dr. belisarius Jul 16 '15 at 5:24
  • 1
    $\begingroup$ Underspecified, as noted, and what have you tried? In general, "I want this, do it for me...." questions are frowned upon. $\endgroup$ – ciao Jul 16 '15 at 5:38
  • $\begingroup$ In the edited example you're not using equal intervals. Voting to close as unclear. Please take your time to answer my questions above. $\endgroup$ – Dr. belisarius Jul 16 '15 at 15:08
  • $\begingroup$ @ belisarius, I present a short list for demonstration. The interval is 3, because each element has 2 neighbors. The interval seems unequal at first sight in this specific example, because the resulting list has to match with the original list in length. So I have to apply 'f' to the last element. I was thinking someone had encountered the same problem with me. I think it could be closed. $\endgroup$ – novice Jul 17 '15 at 2:59

Well, here's my guess at interpreting ambiguity:

func=With[{l = #, ll = #2, f = #3},
  Join[ConstantArray[f@#[[1]], Ceiling[ll/2]],
      Flatten[ConstantArray[f@#, ll] & /@ Rest@#, 1]][[;; 
       Length@l]] &@Append[l[[;; ;; ll]], l[[-1]]]] &;


(* {k[1], k[1], k[4], k[4], k[4], k[7], k[7], k[7], k[10], k[10]} *)

On your new example:

func[[{a, b, c, d, e, f, g, h, i}, 3, f]

(* {f[a], f[a], f[d], f[d], f[d], f[g], f[g], f[g], f[i]} *)

Or spitting some random 3-tuples into the list values:

Block[{a, b, c, d, e, f, g, h, i},
 {a, b, c, d, e, f, g, h, i} = RandomInteger[10, {9, 3}];
 Column[{{a, b, c, d, e, f, g, h, i}, 
   func[{a, b, c, d, e, f, g, h, i}, 3, k]}]]

enter image description here

  • $\begingroup$ `@ciao, it seems the question is not stated clearly. I added some explanation to my question. $\endgroup$ – novice Jul 16 '15 at 7:22
  • $\begingroup$ @novice: Well, output matches your new example (obviously, use some other name for the function than f if f is part of the target, or just apply the function directly), so give it a whirl and report back. $\endgroup$ – ciao Jul 16 '15 at 7:25
list = Range[8];
n = 3;

sel = Take[list, {1, -1, n}]
base = f /@ sel
filled = ConstantArray[base, n] ~Flatten~ {2, 1}
Take[filled, -Length@list]
{1, 4, 7}

{f[1], f[4], f[7]}

{f[1], f[1], f[1], f[4], f[4], f[4], f[7], f[7], f[7]}

{f[1], f[1], f[4], f[4], f[4], f[7], f[7], f[7]}
  • $\begingroup$ I don't understand the filling criteria.Take for example list = Range[9]; n = 7; Why did you decide to include only two ones in the result? $\endgroup$ – Dr. belisarius Jul 16 '15 at 6:21
  • $\begingroup$ @belisarius Without further specification this appeared as correct as any. Hopefully the OP can figure out what to replace the last line with if something else is needed. $\endgroup$ – Mr.Wizard Jul 16 '15 at 6:57
  • $\begingroup$ Not very important, but you may want to check the last part of my answer $\endgroup$ – Dr. belisarius Jul 16 '15 at 20:20

I believe the problem is underspecified. The following is a possible solution. I wanted to use Downsample, motivation is just mine.

meanField[list_List, downSample_Integer, fun_] :=
 Module[{ds, nst, r = Range@Length@list},
  ds = Downsample[r, downSample];
  nst = Nearest[Thread[ds -> fun /@ list[[ds]]]];
  Flatten[nst[#, 1] & /@ r, 1]

list = CharacterRange["a", "j"];
meanField[list, 2, r]
(* {r["a"], r["a"], r["c"], r["c"], r["e"], r["e"], r["g"], r["g"], r["i"], r["i"]}*)

meanField[list, 3, r]
(*{r["a"], r["a"], r["d"], r["d"], r["d"], r["g"], r["g"], r["g"],  r["j"], r["j"]}*)

MatrixPlot[Table[meanField[Range@9, i, Identity], {i, 9}], ColorFunction-> "CMYKColors",
 Epilog -> {Red, 
   MapThread[Downsample,{Table[Disk[{n,9 - m}, .1], {m,.5,9,1}, {n,.5,9,1}], Range@9}]}]

Mathematica graphics

Compare for example with Mr.Wizard's to understand why your problem is poorly defined:

mr[list_, n_, f_] := Module[{sel, base, filled},
  sel = Take[list, {1, -1, n}];
  base = f /@ sel;
  filled = ConstantArray[base, n]~Flatten~{2, 1};
  Take[filled, -Length@list]
MatrixPlot[mr[Range@9, #, Identity] & /@ Range@9, ColorFunction -> "CMYKColors"]

Mathematica graphics

  • $\begingroup$ On a second thought, I don't know if it really matters $\endgroup$ – Dr. belisarius Jul 16 '15 at 19:16
  • $\begingroup$ @ belisarius, In fact the function f does not matter, I only need to find a subset of a list to approximate the list uniformly(i.e. fixed interval), on the condition that the approximation list has the equal size. It is like using {{5, 5, 5}, {5, 5, 5}, {5, 5, 5}} to approximate {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}. In Chebyshev metric, the elements are 1 element neighbor of 5. $\endgroup$ – novice Jul 17 '15 at 3:17
  • $\begingroup$ @novice Sorry, I am not able to understand your comment. Of course f doesn't matter. Have I said on the contrary? $\endgroup$ – Dr. belisarius Jul 17 '15 at 3:27
  • $\begingroup$ @ belisarius, not a good example. It should like this: using {{5, 5, 5}, {5, 5, 5}, {5, 5, 5}} to approximate {{4.6, 4.7, 4.8}, {4.9, 5, 5.1}, {5.2, 5.3, 5.4}}. Something like using the average value to smooth the list, or the first pic shown here : philipbjorge.com/2011/12/02/… $\endgroup$ – novice Jul 17 '15 at 3:40

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