Repeatedly applying trigsimp, ratsimp etc.



>From code I see on this list, it seems that xxx[iii] is a super popular way to extract a list member. So I think it would be great if
somebody proposed and tested code that makes local values trump global arrays.

The slowness of "for i thru length(l) do... l[i]" compared to  "for i in l do...i " can be  dramatic:

(%i1) f(l) := block([x : 0], for lx in l do x : x + lx,x)$

(%i2) g(l) := block([x : 0, n : length(l)], for i : 1 thru n do x : x + l[i],x)$

(%i3) h(l) := block([x : 0, n : length(l)], for i : 1 thru n do x : x + inpart(l,i),x)$

(%i4) l : makelist(i,i,1,10^4)$

(%i5) showtime : all$
Evaluation took 0.0000 seconds (0.0000 elapsed)

(%i6) f(l);
Evaluation took 0.0500 seconds (0.0500 elapsed)
(%o6) 50005000

(%i7) g(l);
Evaluation took 7.1600 seconds (7.1600 elapsed)
(%o7) 50005000

(%i8) h(l);
Evaluation took 8.0400 seconds (8.0400 elapsed)
(%o8) 50005000

--Barton
________________________________
From: macrakis at gmail.com [macrakis at gmail.com] on behalf of Stavros Macrakis [macrakis at alum.mit.edu]
Sent: Sunday, November 04, 2012 16:30
To: Barton Willis
Cc: David Scherfgen; maxima at math.utexas.edu
Subject: Re: [Maxima] Repeatedly applying trigsimp, ratsimp etc.

Barton,

I agree that

            for i in l do...i

is far better than

            for i thru length(l) do... l[i]

After all, the latter takes quadratic time for lists (as opposed to arrays)!

As for the global 'r' problem, I agree that inpart is a reasonable workaround for the current semantics.  But this seems like a good argument for getting rid of the current semantics, where a global array 'r' trumps a local value 'r'.

                       -s

On Sun, Nov 4, 2012 at 9:27 AM, Barton Willis <willisb at unk.edu<mailto:willisb at unk.edu>> wrote:
(1) To access a member of a list, I suggest using inpart, not [k].  Consider:

   (%i1) larry(k) := block([r : [1,2,3]], r[k])$
  (%i2) george(k) :=  block([r : [1,2,3]], inpart(r,k))$

  (%i5) r[x] : 42$

Unintended:

  (%i6) larry(1);
  (%o6) r[1]

OK:

  (%i7) george(1);
  (%o7) 1

Alternatively,

   larry(k) := block([r : [1,2,3]], local(r), r[k])$

is OK too.

(2) To loop over the members of a list r, consider using

  for rk in r do (  ...

instead of

  for k : 1 thru length(r) do ( ...

The function length gets called each time at the top of the loop--also you will also not need to do r[k] any more :)

(3)  Consider giving the last argument of dssimp a goofy name such as %_r_%. This isn't foolproof, but it does give some protection against
      problems such as

   (%i5) dssimp(1,[fff]);
   (%o5) 1

  (%i6) dssimp(1,[r]);
  apply: found r evaluates to [r] where a function was expected.

(4)  To form a compound statement without local variables, an explicit 'block' isn't needed--just (XXX, YYY, ZZZ),  not block(XXX, YYY, ZZZ).


--Barton

________________________________________


----------------------
(defmfun $conssize (x) (if (atom x) 0 (do ((x (cdr x) (cdr x)) (sz 1))
((null x) sz) (incf sz (1+ (conssize (car x)))))))

File dssimp.mac:
-----------------------
dssimp(expr, r) :=
     block([exprSize, smallestExpr, smallestExprSize, simpdExpr,
simpdExprSize],
         exprSize : conssize(expr),
         smallestExpr : expr,
         smallestExprSize : exprSize,
         loop,
         for i : 1 thru length(r) do
         block(
             simpdExpr : r[i](expr),
             simpdExprSize : conssize(simpdExpr),
             if simpdExprSize < smallestExprSize then
             block(
                 smallestExpr : simpdExpr,
                 smallestExprSize : simpdExprSize
             )
         ),
         if smallestExprSize >= exprSize then
             return(expr),
         expr : smallestExpr,
         exprSize : smallestExprSize,
         go(loop)
     );

dssimpall(expr) := dssimp(expr, [combine, logcontract, radcan, ratsimp,
rootscontract, trigrat, trigreduce, trigsimp, xthru]);