Why these definitions are so slow

Mathematica

    Next

  • 1. calculate de Jong function
    Hello, I don't know how I should implement the first de jong function: f(x)=Sum((x_i)^2) where x is a Vector with n dimensions and x_i is the value of the i-th Dimension. i.e. all Values of the Vector are squared and added. My problem is that I don't know how many Dimensions there are, so I can't define the borders of the SUM function. thanks in advance for help Stefan
  • 2. named pattern variable scoped as global, should be local
    When using a named pattern variable within a module, it should be scoped locally within the pattern. However, this does not seem to work as advertised. For example, shouldn't the pattern variable x in the statements below be local to the pattern? Does anyone know whether this is a bug, or whether I am just missing something about the usage of variables in patterns/condition constructs? (* this returns 14! *) x = 7; Module[{x},{1, 2, 3} /. x_ -> 2x]; (* this returns {2,4,6}, assuming q is not globally defined. *) Remove[q]; Module[{q},{1, 2, 3} /. q_ -> 2q]; Lee
  • 3. ArcTan[1/0] no result, but ArcTan[Infinity] ok. How to resolve?
    hi; Mathematica 5.1, on windows. ArcTan[1/0] gives an error but ArcTan[Infinity] gives the correct answer. One way to make ArcTan[1/0] give Pi/2 is to write it as ArcTan[0,1]. I do know that 1/0 is DirectedInfinity[] with unknown direction while Infinity is DirectedInfinity[1], and that is probably the reason that ArcTan[1/0] gives an error but ArcTan[Infinity] does not. I am asking is how to make 1/0 result in DirectedInfinity[1] to avoid the error? is this possible? What function do I need to wrap 1/0 with to cause it to become Infinity[1] instead of Infinity[] ? or may be I need to figure how to detect if a division results in Infinity[] and convert that to Infinity[1]? do I need to redfine 1/0 somehow? may be make a new rule to say if Mathematica see 1/0 expression then make it Infinity[1]? but may be this will screw other things? Or may I should not mess with this stuff and just change the code to ArcTan[x,y] instead of ArcTan[y/x] and be happy? thanks, Steve

Why these definitions are so slow

Postby Arturas Acus » Sat, 13 Nov 2004 16:20:36 GMT

Dear Group,

Could somebody explain why these simple definitions takes so long time
to run?
I also tried to wrap them with HoldPattern[] in various ways, change
blanks, etc., all in vain. 

In[1]=

Integralas[Times[a__, b_?(FreeQ[#, rTilde] &), c___]] :=
b*Integralas[Times[a, c]]

Integralas[Plus[a__, b_?(FreeQ[#, rTilde] &), c___]] := 
  b + Integralas[Plus[a, c]]

Integralas[n_?NumberQ] := n



In[2]=

Integralas[(3*aTilde)/(4*Pi) + (3*aTilde*j)/(2*Pi) +
(3*aTilde*j^2)/(2*Pi) - (9*aTilde*Cos[2*F[rTilde]])/(8*Pi) + 
 (3*aTilde*j*Cos[2*F[rTilde]])/(2*Pi) +
(3*aTilde*j^2*Cos[2*F[rTilde]])/(2*Pi) + 3*rTilde^2*Sin[F[rTilde]]^2 - 
 4*j*rTilde^2*Sin[F[rTilde]]^2 - 4*j^2*rTilde^2*Sin[F[rTilde]]^2 +
3*rTilde^2*Cos[2*F[rTilde]]*Sin[F[rTilde]]^2 - 
 4*j*rTilde^2*Cos[2*F[rTilde]]*Sin[F[rTilde]]^2 -
4*j^2*rTilde^2*Cos[2*F[rTilde]]*Sin[F[rTilde]]^2 - Sin[F[rTilde]]^4 - 
 2*j*Sin[F[rTilde]]^4 - 2*j^2*Sin[F[rTilde]]^4 -
6*rTilde^2*Sin[F[rTilde]]^4 + 8*j*rTilde^2*Sin[F[rTilde]]^4 + 
 8*j^2*rTilde^2*Sin[F[rTilde]]^4 + 3*Cos[2*F[rTilde]]*Sin[F[rTilde]]^4 -
4*j*Cos[2*F[rTilde]]*Sin[F[rTilde]]^4 - 
 4*j^2*Cos[2*F[rTilde]]*Sin[F[rTilde]]^4]

In[4]:=
$Version

Out[4]=
5.0 for Linux (November 18, 2003)


Sincerely, Arturas Acus



Re: Why these definitions are so slow

Postby David Bailey » Sun, 14 Nov 2004 18:50:42 GMT

rturas Acus wrote:
Hi,

That definition is spectacularly slow, and it was quite interesting to
figure out why!

The first thing to realise is that the Mathematica pattern matcher
already takes into account the fact that Plus and Times commute, so you
can improve the efficiency quite a bit thus:

Integralas[ b_?(FreeQ[#1, rTilde] &) c_] := b Integralas[c];
Integralas[b_?(FreeQ[#1, rTilde] &) + c_] := b + Integralas[c];
Integralas[n_?NumberQ] := n;

However, even this version runs pretty slow, so I changed the definition
to this:

freer[x_] := (Print[freer[x] // HoldForm]; FreeQ[x, rTilde]);
Integralas[ b_?freer c_] := b Integralas[c];
Integralas[b_?freer + c_] := b + Integralas[c];
Integralas[n_?NumberQ] := n;

I also used a variant where I counted the calls to freer, rather than
printing them out.

This shows that freer (i.e. FreeQ) is called 2.3 x 10^6 times. It was
probably called many more times in your original version.

The problem is that a pattern like Plus[a_,b_] can match a sum of 20 odd
terms in an enormous number (2^20-2) of ways. This is compounded by the
fact that Mathematica rearranges the pattern

b_?freer + c_

into

c_ +b_?freer

(because they commute and happen to sort that way!)

This means that if you give it a complicated sum at the start c gets set
to each term in turn and b gets set to the rest - there is a fair
combinatorial explosion here and the case of interest is near the end.

You can avoid the rearrangement using HoldPattern, but perhaps it is
easier to rearrange your definition thus:

Integralas[ b_ c_] := b Integralas[c] /; FreeQ[b, rTilde];
Integralas[b_ + c_] := b + Integralas[c] /; FreeQ[b, rTilde];
Integralas[n_?NumberQ] := n;

Tests are generally more efficient within patterns than placed at the
end, but b_ c_ does not get sorted into c_ b_, so the search finds a
match much sooner. Of course, when Integrelas gets an expression that it
can't simplify you still have to go through all possibilities - so it is
still not super efficient - but this version only takes 4.6 secs on my
2GHz machine.

You could improve the efficiency more, but I suspect this is a cut-down
of your real problem, so I don't want to complicate the code.

The following illustrates the combinatorial explosion of matching:

Foo[a_ + b_] := 0 /; (Print[a]; False);

Foo[a+b+c+d]

Regards,

David Bailey


Re: Re: Why these definitions are so slow

Postby DrBob » Mon, 15 Nov 2004 19:01:14 GMT

ould it be the OP intended Integralas to be additive? If so, this works:

ClearAll@Integralas
Integralas[b_ c_] := b Integralas@c /; FreeQ[b, rTilde];
Integralas[b_] := b /; FreeQ[b, rTilde];
Integralas[b_ + c_] := Integralas@b + Integralas@c;

Bobby

On Sat, 13 Nov 2004 04:40:08 -0500 (EST), David Bailey < XXXX@XXXXX.COM > wrote:




--
XXXX@XXXXX.COM
www.eclecticdreams.net



Return to Mathematica

 

Who is online

Users browsing this forum: No registered users and 22 guest