acer

32353 Reputation

29 Badges

19 years, 331 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

@Carl Love For a starting value of 2 the other isolating formula seems needed with the PointFixe above. Ie, passing exp(x)-x-5 wouldn't suffice even the procedure were modified to "add x to g".

How about uploading a worksheet with the full details?  It sounds like your rotating object might be 3D, but it's not clear.

The Explore command can do that with an display of an Array of two plots. But depending on the details there may be nice alternatives. For example if the frames are individually slow to compute then pair of plots-animate style animations could still be advanced (essentially) in sync by advancing them together in two separate Plot Components.

If the rotating object is also 2D the even a dual-axis plot might suffice. If the rotating object is 3D and you don't need the see it rotate with respect to the axes, etc, the you may get better performance instead by changing the "point of view" (fly around it), which affect which method is easiest while also practical.

acer

@Preben Alsholm I don't know what causes this recurring and long-standing problem.

Ok, so the above is the 25 minute version, upon waking at 5:30am. (10 mins of that being mental design while the water boiled...)

My improvement wishlist grows: 1) passing the inbound color through ColorTools, to allow several more input formats, 2) careful handling of names which already have their own print-slash proc (saving it aside, forced clobber, proper reinstatement), 3) colouring braces, and 4) distinct colouring for function application of specific arguments (eg, F(x) versus F(t) ).

@John Fredsted Wouldn't you need the module to have 'option package' in order for it to work using 'with' ?

Perhaps the Programming Manual is a good place to start, as it contains an example of doing this.

The relative performance with increased problem "size" here can depend on on which gets larger: the number of items in the inner lists, or the number of inner lists, or both. I deliberately repeat one of the computations in each run below, to test whether the order of execution is affecting it's timing.

For example,

restart;
A := [seq([seq(i*j,j=1..1000000)],i=1..3)]:

ans1 := CodeTools:-Usage( op(map(op~,[1,2],A)) ):
memory used=1.70KiB, alloc change=0 bytes, cpu time=7.00ms, real time=7.00ms, gc time=0ns
ans2 := CodeTools:-Usage( op([1..2],ListTools:-Transpose(A)) ):
memory used=53.42MiB, alloc change=371.64MiB, cpu time=2.90s, real time=1.28s, gc time=2.48s
ans3 := CodeTools:-Usage( op(map(op~,[1,2],A)) ):
memory used=1.73KiB, alloc change=0 bytes, cpu time=8.00ms, real time=7.00ms, gc time=0ns

ans1-ans2, ans1-ans3;
                                    0, 0

restart;
A := [seq([seq(i*j,j=1..1700)],i=1..1700)]:

ans1 := CodeTools:-Usage( op(map(op~,[1,2],A)) ):
memory used=187.17KiB, alloc change=32.00KiB, cpu time=8.00ms, real time=8.00ms, gc time=0ns
ans2 := CodeTools:-Usage( op([1..2],ListTools:-Transpose(A)) ):
memory used=22.11MiB, alloc change=260.31MiB, cpu time=56.00ms, real time=56.00ms, gc time=20.00ms
ans3 := CodeTools:-Usage( op(map(op~,[1,2],A)) ):
memory used=187.34KiB, alloc change=0 bytes, cpu time=8.00ms, real time=7.00ms, gc time=0ns

ans1-ans2, ans1-ans3;
                                    0, 0

restart;
A := [seq([seq(i*j,j=1..3)],i=1..1000000)]:
ans1 := CodeTools:-Usage( op(map(op~,[1,2],A)) ):
memory used=106.82MiB, alloc change=47.27MiB, cpu time=2.08s, real time=919.00ms, gc time=1.58s
ans2 := CodeTools:-Usage( op([1..2],ListTools:-Transpose(A)) ):
memory used=22.89MiB, alloc change=22.90MiB, cpu time=40.00ms, real time=42.00ms, gc time=0ns
ans3 := CodeTools:-Usage( op(map(op~,[1,2],A)) ):
memory used=106.82MiB, alloc change=-7.63MiB, cpu time=1.72s, real time=815.00ms, gc time=1.23s

ans1-ans2, ans1-ans3;
                                    0, 0

@Annonymouse Thanks for that. Here is a worksheet in which your optimal target expression is named `OP`. It is better using several metrics, including `length`, `LeafCount`, codegen[cost], and the `simplify/size/size` internal procedure that the simplify(...,size) command uses.

simp4.mw

As I briefly mentioned above, the ability to temporarily add/subtract some either special terms (or some subset of the addends of a sum) can be a tricky topic, I suspect. The potential cost in the presence of a sum of many addends (in general, not here) looks like it might be daunting. As you say, there may be hints that can be leverage, including the presence of denominators common amongst some addends. Thanks for this example -- I'm going to consider all this in one partial approach of a compactifier I'm working on.

 @vv What I was trying to convey by showing that approach with `collect` was just that it produced a smaller result for the given example. I wasn't trying to imply that it would always do better, naturally. Indeed even for the given example it matters which name is collected. A similar question arises: should simplify(...,size) attempt collection wrt single names, all single names, combinations of all subsets on names present, etc, and if so how could that be effectively cut off for practicality?

@Carl Love I'm not sure whether Carl has overlooked one aspect of this task, or has left it as part of the homework exercise...

In order to utilize the procedure that Carl has written the first argument must be equal to the remaining expression when one instance of x in the original expression is isolated. First, let's do it by isolating for the two individual instances of x in exp(x)-x-5 .

For example,

evalf( [solve( exp(x)-x-5, x )] );
                  [-4.993216189, 1.936847407]

PointFixe(exp(x)-5, -2, 1e-8, 100);
                          -4.993216188

PointFixe(ln(x+5), 2, 1e-8, 100);
                          1.936847409

I have changed Carl's routine a little, to return FAIL rather than raise an error. In the attached sheet I show a crude way to generate the various "isolations" for separate occurences of `x` (in this case, two of them).

Download pointfixe.mw

@Thomas Richard 

restart:

A := [[1,2],[3,4],[5,6]]: 

op([1..2],ListTools:-Transpose(A));
                                         [1, 3, 5], [2, 4, 6]

seq(map(`?[]`,A,[i]),i=1..2);
                                         [1, 3, 5], [2, 4, 6]

B := [[1,2,3,4],[5,6,7,8],[9,10,11,12]]:

op([1..2],ListTools:-Transpose(B));
                                         [1, 5, 9], [2, 6, 10]

seq(map(`?[]`,B,[i]),i=1..2);
                                         [1, 5, 9], [2, 6, 10]

When the length of the inner lists gets large the mapped `?[]` approach becomes relatively faster, and the additional memory allocation becomes relatively smaller (because the transposition creates something effectively as large as the original).

[edited] Oh, it seems like the performance of the following is quite a bit better, for large inner lists. Thanks, Kitonum!

op(map(op~,[1,2],A));
                                          [1, 3, 5], [2, 4, 6]

op(map(op~,[1,2],B));
                                          [1, 5, 9], [2, 6, 10]

@vv Yes, it's an interesting topic. Leaving aside the complications of trying to introduce terms so as to get fortuitous factorization (which seems like it may be a deep rabbit hole), it can be an involved subject using just the tools available.

F3 := expand(E3):

length( simplify(F3,size) );
                                                  6938

CG:=u->codegen[optimize](subs(__dum=u,proc() __dum; end proc),tryhard)():

length( CG( collect( F3, y, u->simplify(u,size) ) ) );
                                                  2580

length( simplify( (CG@@2)( collect( simplify(F3,size), y, u->simplify(u,size) ) ),size ) );
                                                  2441

This page indicates that OSX versions 10.12 is not an officially supported platform for Maple 2016.

It would be useful if this roadmap page could be updated with the intended support for Maple 2017.

acer

@AmusingYeti I do not recall seeing full details from you as to how your lengthy expressions come about. Please keep in mind that a common mistake is to use floating-point vallues too early. Sight unseen, there is a chance that some earlier aspect of your computations which produced these lengthy integrands might be better handled with exact (or possibly even symbolic) values.

Since the integrand is somewhat expensive to compute, and since the numeric triple-integration does many functional evaluations of the integrand, it is beneficial here to compile the integrand (after making a procedure from it).

There is a little extra overhead due to the external cuhre function having to call back to Maple to access the compiled integrand procedure. But for this example the speed advantage of the compiled version over the (otherwise, here) evalhf evaluations of the integrand wins out.

This compiled version takes 2.25 sec on my 64bit Linux Maple 2016.1 using the well-optimized expr1, while the previous well-optimized version takes 8.6 sec. The first method in my original Answer above takes 21.1 sec.

Maple_numeric_speed_compiled.mw

Of course this approach requires that the Compiler:-Compile command is functioning.

Even when using Maple 2016.1 the speed will depend on your machine and the OS. I tried this on a moderately quick Windows 7 machine using 64bit Maple 2016.1 and the well-optimized version shown previously took about 22 sec while the compiled version tool about 6.3 sec and the first I posted took about 55 sec.

The upshot is that the speed of the individual evaluations of the integral is key here. Compactification of the integrand helps, and so to may compilation (if possible, like here).

@vv 

The manually written procedure you gave has the virtue that it declares y as a local. With the unapply method I gave there would be a problem if global y were assigned, say, a numeric value. So I think that it's good that you showed it, and wrote the useful explanation.

As a side note, perhaps it would be convenient if parameter-processing were to offer a terse syntax for handling required arguments in such a way.

Eg (making this up, this is not valid syntax ladies and gentlemen),

g := (a::query(numeric)) -> a^3;

or 

g := proc(a::query(numeric))
       a^3;
     end proc:

where such a procedure would return unevaluated if the required argument did not satisfy its queried type.

@Markiyan Hirnyk The final number you show is negative, but you said you wanted the solution in RealRange(Open(0),4).

solve( {n>1, n<=4, (1/n-1)*ln(t)+(n-1/n-1)*ln(1-t)=ln(t)/n-ln(t)}, n); 

                                                            1/2
                                                           5
                                                      {n = ---- + 1/2}
                                                            2
First 292 293 294 295 296 297 298 Last Page 294 of 592