2

I want to write an (somehow) enhanced sum function which takes a number of indices at once, but I cannot understand how to get it work. Here is what I currently have:

(%i1) nsum(indexes, expr) :=
          if indexes = []
          then expr
          else nsum(rest(indexes), sum(expr, first(indexes),1, N)) $

(%i2) nsum([i,j], i+j), nouns;
      sum: index must be a symbol; found intosym(first(indexes))
      #0: nsum(indexes=[k,j],expr=k+j)

I think this could be fixed by forcing Maxima expand first(indexes) into a symbol before passing to sum function. I tried ''(...) and ev(..., nouns), but without any success.

firegurafiku
  • 3,017
  • 1
  • 28
  • 37

1 Answers1

1

After some reading and trying I came to the following solution which uses apply function to pre-evaluate arguments for sum:

nsum(indexes, expr) :=
    if indexes = []
    then expr
    else nsum(rest(indexes), apply(sum, ['expr, indexes[1], 1, N])) $

UPD1:
Unfortunately, there is something wrong with the above code, as it works well only for relatively simple expressions. In my case the straightforward approach works fine where nsum fails:

(%i1) rot[i](f) := sum(sum(sum(sum(
      G[r,i]*G[q,j]*w[i,j,k]*('diff(f[k], y[q]) + sum(K[k,q,m]*f[m], m, 1, N)),
        r, 1, N),
        j, 1, N),
        k, 1, N),
        q, 1, N) $

(%i2) rot2[i](f) := nsum( [r,j,k,q],
        G[r,i]*G[q,j]*w[i,j,k]*('diff(f['k], y[q]) + sum(K[k,q,m]*f[m], m, 1, N))) $

(%i3) rot[1](f);
(%o3) ... Yelds the result.

(%i4) rot2[1](f);
apply: subscript must be an integer; found: k
lambda([i,j],diff(ys[i],x[j]))(i=k,j=1)

UPD2:

The code works indeed. It was 'k accidentally left in rot2 definition instead of just k.

firegurafiku
  • 3,017
  • 1
  • 28
  • 37
  • 2
    I think the `apply` technique is working as expected. I find that if I change `'k` to `k` in the definition of `rot2` (i.e. remove the quote) then `rot2` yields the same result as `rot` in this case. – Robert Dodier Jul 24 '15 at 15:50
  • 1
    @RobertDodier: Ah, seems like I just mistyped that quote. Thank you for spotting that! – firegurafiku Jul 24 '15 at 17:18
  • @RobertDodier Is it possible to get rid of extra evaluation? Consider, `(%i1) display2d: false $ (%i2) kill(l1, l2, l0) $ (%i3) l2: l1 $ (%i4) l1: l0 $ (%i5) expr: expr0 $ (%i6) apply('sum, [expr , i, 0, l2]); (%o6) expr0*(l0+1) (%i7) sum (expr0, i, 0, l2 ); (%o7) expr0*(l1+1)` – slitvinov Jul 27 '15 at 12:26
  • @RobertDodier Here is link to the proper formatted example https://gist.github.com/anonymous/7cb52b1bb9768a9718df – slitvinov Jul 27 '15 at 12:28
  • 1
    @slitvinov I'm not sure I understand what you mean. Are you saying that it's possible to write this example without `apply`? I believe so, but one still has to use a substitution or evaluation mechanism to make it work. If you have another idea, I'd be interested to hear about it. – Robert Dodier Jul 27 '15 at 19:16
  • @RobertDodier Sorry for not being clear. In my example there is a difference between `(%o6) expr0*(l0+1)` and `(%o7) expr0*(l1+1)`. I think it is becouse the last agrument was evaluted two times in case of `apply`. How can I write a following function `(%i6) sum2(expr , i, 0, l2); (%o6) expr0*(l1+1)` ? – slitvinov Jul 28 '15 at 00:13