7
$\begingroup$

Suppose I have the variable expr1 = a[n] + b[n], and the list stencil={-1,0,1}. I want to make a function f[expr_, stencil_]:= ... that can give:

a[n-1] + b[n-1] + a[n] + b[n] + a[n+1] + b[n+1].

Basically I want to 'map' the values inside stencil to n of expr. Any help would be appreciated.

$\endgroup$
2
  • 1
    $\begingroup$ Use the ideas by@Ben lzd Replace[expr1, $_ -> $ + #, {-1}] & /@stencil // Total $\endgroup$
    – cvgmt
    May 22 at 22:58
  • 3
    $\begingroup$ It would have been much better if you had defined your expression as a function instead: Total[Function[n, a[n] + b[n]] /@ (n + {-1, 0, 1})]. $\endgroup$ May 23 at 14:14

7 Answers 7

10
$\begingroup$

Another approach could be:

Total[Thread /@ Map[# + stencil &, expr1, {-1}]]

Note that it's slightly faster than the @Syed answer but uses more memory.

$\endgroup$
7
$\begingroup$

Does this work correctly apart from your example?

f = Join @@ (# /. Table[sym -> Head[#][sym, i], {i, #2}, {sym, Variables[Level[#, {-1}]]}]) &;

f[expr1, stencil]
(* a[-1 + n] + a[n] + a[1 + n] + b[-1 + n] + b[n] + b[1 + n] *)
$\endgroup$
5
$\begingroup$
Total@(expr1 /. n -> n + # & /@ stencil)

a[-1 + n] + a[n] + a[1 + n] + b[-1 + n] + b[n] + b[1 + n]

$\endgroup$
4
$\begingroup$
Distribute[{expr1, stencil},List,List,Plus,Replace[#1,n:>n+#2,2]&]

(* a[-1 + n] + a[n] + a[1 + n] + b[-1 + n] + b[n] + b[1 + n] *)
$\endgroup$
3
$\begingroup$

Another way:

Total@Flatten[Map[Composition[Through, Map[Head, Variables[expr1]]], 
Mean[Level[expr1, {-1}]] + stencil]] // AbsoluteTiming
(*{0.000063, a[-1 + n] + a[n] + a[1 + n] + b[-1 + n] + b[n] + b[1 + n]}*)
$\endgroup$
2
  • 2
    $\begingroup$ I think you want Total instead of Sort. $\endgroup$
    – bbgodfrey
    May 22 at 21:02
  • $\begingroup$ Thanks, bbgodfrey! :) $\endgroup$ May 22 at 21:21
3
$\begingroup$

Outer also works.

Outer[#1/.n->n+#2&, List@@(a[n] + b[n]),{-1,0,1}]//
Total//
Total

a[-1 + n] + a[n] + a[1 + n] + b[-1 + n] + b[n] + b[1 + n]

Here is the trick.

a[n]-b[n] // FullForm

Plus[a[n], Times[-1, b[n]]]

So the + or - will not affect the result.

$\endgroup$
2
$\begingroup$

Different way:

expr1 = a[n] + b[n]
stencil = {-1, 0, 1}
f[ex_, sten_] := Sum[Map[# + tp &, ex, {2}] /. tp -> sten[[i]], {i, 1, Length[sten]}]

Then, f[expr1, stencil] gives

a[-1 + n] + a[n] + a[1 + n] + b[-1 + n] + b[n] + b[1 + n]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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