acer

32328 Reputation

29 Badges

19 years, 318 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

Sorry, I inadvertantly posted a reply to your message as a reply to the thread parent. Please see below. acer
R:=(n,x)->rem(simplify(HermiteH(n,x),'HermiteH'), x^2-1, x);

R(5,x);
acer
I can't foresee such a basic and longstanding aspect of Maple's evaluation behaviour changing. It doesn't seem like a bug to me, but then I'm used to it. I appreciate the fine level of control it gives. Note that a "full eval" like eval(x) is not always necessary. Eg,
> f:=proc()
> local x,y,z;
> x:=y^2; y:=z; z:=3;
> eval(x,1),eval(x,2),eval(x,3);
> end proc:
> f();

                                    2   2
                                   y , z , 9
A partial eval can allow you to return the value such as an unevaluated function call. If a full-eval were always done then we wouldn't be able to force less than full evaluation. The only locals that I can think of offhand, which get evaluated fully within a proc, are table members in the case that they have been passed (or supplied via lexical scoping) to another inner procedure. For example,
> f:=proc()
> local x,y,z;
> proc()
> x[1]:=y[1]^2; y[1]:=z[1]; z[1]:=3;
> x[1];
> end proc();
> end proc:
> f();

                                       9
Presumably that's because tables have last_name_eval and otherwise usual 1-level eval of locals used as parameters would only give the table name and not even the assigned value. It's as if this exception was coded precisely so that programmers wouldn't have to keep using eval(). (It's a bit weird though, because wouldn't an automatic 2-level eval have also solved the problem without having to wreck the fine control with a full-eval?) Note that globals declared in a procedure always get full evaluation.
> f:=proc()
> global x,y,z;
> x:=y^2; y:=z; z:=3;
> x;
> end proc:
> f();

                                       9
Using globals instead of locals can thus make a procedure less efficient. acer
The existing `convert/base` code in Maple 11, without edits, can also be used to do some conversions to binary significantly faster than is done using Maple 11's `convert/binary`.
Q := proc(n)
parse(cat("11.",
          StringTools:-Reverse(
             StringTools:-Select(
                StringTools:-IsBinaryDigit,
                convert(convert(trunc(evalf[trunc(n/log[2](10.0))+2](
                                         Pi*2^(n-2))),
                                base,2)[1..-3],
                        string))))):
end proc:
On my 64bit Linux machine, the performance crossover between Doug's modified `convert/binary` and `Q` above looks to be about N=25000. Repeat these examples below out of order, or separately. Use the `convert/binary/fraction` routine and its friends from the worksheet. As N gets to 400000 the routine Q gets about 10 times faster.
N := 25000:

gc():
st,ba,bu:=time(),kernelopts(bytesalloc),kernelopts(bytesused):
sol2:=convert(evalf[trunc(N/log[2](10.0))+2](Pi),binary,N):
time()-st,kernelopts(bytesalloc)-ba,kernelopts(bytesused)-bu;
                                                                                
gc():
st,ba,bu:=time(),kernelopts(bytesalloc),kernelopts(bytesused):
sol1 := Q(N):
time()-st,kernelopts(bytesalloc)-ba,kernelopts(bytesused)-bu;
If my sums are right, then one doesn't need more than trunc(N/log[2](10.0))+2 decimal digits in order to be able to obtain N binary digits. The crossover point between Q and the regular system `convert/binary` routines in Maple 11 is about N=200. I didn't look at improving the routines in the worksheet. Perhaps if one could get the address of the DAG of the floating-point number in Maple, and offset it past the DAG header, and copy it byte for byte into a hardware datatype Array, then that could used with hard-coded lookup tables. The lookup tables might contain hardware datatype Arrays as well. acer
I couldn't get the Document that you referenced above (which does performance comparisons) to run as quickly as its printed timings suggest. I also saw what might be a mistake in that Document. You claim that it's OK to replace evalf[n](Pi) with evalf(Pi) in key spots. But there are no special evaluation rules in action here, and the `convert/binary` (and related) procedures would just see 10 digits of Pi in that case, since Digits was not set at the top-level. Are you sure that the methods you compare are really all doing the same thing? (DJ Keenan made some comments about his routines not needing Digits to be set at a higher level in order than a variant of his modifications to respect the optional precision parameter of `convert/binary. But it must surely still matter to what accuracy the inbound float approximation of Pi is made.) Perhaps as much accuracy as is provided by evalf[n](Pi) would not be required. In order to have `convert/binary` produce n binary digits then maybe something like evalf[trunc(n/log[2](10.0))+2](Pi) would suffice. Also, it's not reasonable to compare methods which might compute evalf of some same numbers (as they work internally, say) in the same session like that. More accurate would be to clear evalf's remember tables between tests. Better still is to also measure bytes alloc increases and to place each method in its own testing file. The following seems to be a big improvement on the first method that I suggested. And it doesn't require edits to any of the existing `convert` routines.
Q := proc(n)
op(ListTools:-Reverse(convert(trunc(evalf[trunc(n/log[2](10.0))+2](Pi*2^(n-2))),base,2))):
end proc:
If it really is a big improvement, then one might wonder why, exactly. One reason is that maple can scale a large floating point number up by a power of 2 pretty quickly, presumably helped by use of gmp. Another reason is that the irem techniques already used in `convert/base` aren't so bad. It seems to me that they act in the same general way as DJKeenan's code (but used above with the smallest possible base and hence no lookup table benefits). Consider the number
        trunc(evalf[trunc(n/log[2](10.0))+2](Pi*2^(n-2)))
Maybe one could get the address of its DAG, offset by enough to get the address of its data portion (the number itself), and copy it into a hardware datatype Vector. Entries of that Vector might then be taken and used in conjunction with a hard-coded lookup table. The copying might be done using an external call to a BLAS routine like scopy or dcopy. To compute comparison timings, I grabbed the modified `convert/binary` routines directly from the original worksheet. Those do indeed provide a big speedup over the regular Maple 11 `convert/binary` routines. But for your particular task, it looks to me as if simple routine Q above (which uses different, unchanged internal routines like `convert/base`) is still about 10 times faster and allocates about 10 time less memory when n=1000000. I'm just wondering whether I compared Q against the most efficient alternative provided by any incarnation of `convert/binary` and friends. acer
I couldn't get the Document that you referenced above (which does performance comparisons) to run as quickly as its printed timings suggest. I also saw what might be a mistake in that Document. You claim that it's OK to replace evalf[n](Pi) with evalf(Pi) in key spots. But there are no special evaluation rules in action here, and the `convert/binary` (and related) procedures would just see 10 digits of Pi in that case, since Digits was not set at the top-level. Are you sure that the methods you compare are really all doing the same thing? (DJ Keenan made some comments about his routines not needing Digits to be set at a higher level in order than a variant of his modifications to respect the optional precision parameter of `convert/binary. But it must surely still matter to what accuracy the inbound float approximation of Pi is made.) Perhaps as much accuracy as is provided by evalf[n](Pi) would not be required. In order to have `convert/binary` produce n binary digits then maybe something like evalf[trunc(n/log[2](10.0))+2](Pi) would suffice. Also, it's not reasonable to compare methods which might compute evalf of some same numbers (as they work internally, say) in the same session like that. More accurate would be to clear evalf's remember tables between tests. Better still is to also measure bytes alloc increases and to place each method in its own testing file. The following seems to be a big improvement on the first method that I suggested. And it doesn't require edits to any of the existing `convert` routines.
Q := proc(n)
op(ListTools:-Reverse(convert(trunc(evalf[trunc(n/log[2](10.0))+2](Pi*2^(n-2))),base,2))):
end proc:
If it really is a big improvement, then one might wonder why, exactly. One reason is that maple can scale a large floating point number up by a power of 2 pretty quickly, presumably helped by use of gmp. Another reason is that the irem techniques already used in `convert/base` aren't so bad. It seems to me that they act in the same general way as DJKeenan's code (but used above with the smallest possible base and hence no lookup table benefits). Consider the number
        trunc(evalf[trunc(n/log[2](10.0))+2](Pi*2^(n-2)))
Maybe one could get the address of its DAG, offset by enough to get the address of its data portion (the number itself), and copy it into a hardware datatype Vector. Entries of that Vector might then be taken and used in conjunction with a hard-coded lookup table. The copying might be done using an external call to a BLAS routine like scopy or dcopy. To compute comparison timings, I grabbed the modified `convert/binary` routines directly from the original worksheet. Those do indeed provide a big speedup over the regular Maple 11 `convert/binary` routines. But for your particular task, it looks to me as if simple routine Q above (which uses different, unchanged internal routines like `convert/base`) is still about 10 times faster and allocates about 10 time less memory when n=1000000. I'm just wondering whether I compared Q against the most efficient alternative provided by any incarnation of `convert/binary` and friends. acer
Ah, yes, sorry about that.
split := proc(z::polynom(anything,[x,y]))
  local C,t;
  C:=[coeffs(z,[x,y],'t')];
  add(C[i]*INT(degree(t[i],x),degree(t[i],y)),i=1..nops(C));
end proc:
acer
Just replace the seq() with add(). acer
In your second try, when you call dzurflu(720), you're forgetting that the new unapplied function is actually named dzurflu14. Calling dzurflu14(...) repeatedly should work fine. I still think that using D for this is more straightforward. See the above reply, or the ?D help-page. acer
In your second try, when you call dzurflu(720), you're forgetting that the new unapplied function is actually named dzurflu14. Calling dzurflu14(...) repeatedly should work fine. I still think that using D for this is more straightforward. See the above reply, or the ?D help-page. acer
I wasn't completely sure what you were after. It doesn't seem to have anything especially to do with integrals. It looks more like a task of getting coefficients and replacing terms by some function call.
split := proc(z::polynom(anything,[x,y]))
  local C,t;
  C:=coeffs(z,[x,y],'t');
  seq(C[i]*INT(degree(t[i],x),degree(t[i],y)),i=1..nops([C]));
end proc:

z := a + b/c*x + d/e*x*y^3 + f*y^5:
split(z);

z := c1 + c2*x + c3*y + c4*x*y:
split(z);
acer
I think that there's probably more that can be done. The ArrayTools:-Copy calls might all be replaced by the lowest level external calls to BLAS (just like those others that appear within matexp). There is a bit of non-external work done in matexp, most of it to do with size n, Digits, and routine selection according to UseHardwareFloats. It could be set up that a new routine, matexp_generator(), emits a version of matexp in which most all that work is hard-coded. (LinearAlgebra could do this, if someone went to the trouble.) This new routine could use a remember table so that it only had to generate one matexp() version per combination of n/Digits. The hardware external functions could be left in, and the software external functions removed, for your example. The matexp() version could be emitted by doing a subs on a template procedure -- a minor variant of the existing matexp() procedure. It'd make a decent blog post, if it worked well. There may be savings in the other parts of Parametrize_SU_Euler(), but if I need more underlying code I'll send a private message with my email address and you could decide on whether that'd be OK. At some point, when size n gets large, the cost of the external hardward computations involved with the exponential will dominate. Comparison with Matlab or pure C would, at that point, depend on the algorithm used. There are several poor ways to compute it. It'd take a little research to figure out the state-of-art for it. There are a few obvious places to start, such as this paper co-authored by Cleve Moler. acer
I think that there's probably more that can be done. The ArrayTools:-Copy calls might all be replaced by the lowest level external calls to BLAS (just like those others that appear within matexp). There is a bit of non-external work done in matexp, most of it to do with size n, Digits, and routine selection according to UseHardwareFloats. It could be set up that a new routine, matexp_generator(), emits a version of matexp in which most all that work is hard-coded. (LinearAlgebra could do this, if someone went to the trouble.) This new routine could use a remember table so that it only had to generate one matexp() version per combination of n/Digits. The hardware external functions could be left in, and the software external functions removed, for your example. The matexp() version could be emitted by doing a subs on a template procedure -- a minor variant of the existing matexp() procedure. It'd make a decent blog post, if it worked well. There may be savings in the other parts of Parametrize_SU_Euler(), but if I need more underlying code I'll send a private message with my email address and you could decide on whether that'd be OK. At some point, when size n gets large, the cost of the external hardward computations involved with the exponential will dominate. Comparison with Matlab or pure C would, at that point, depend on the algorithm used. There are several poor ways to compute it. It'd take a little research to figure out the state-of-art for it. There are a few obvious places to start, such as this paper co-authored by Cleve Moler. acer
Yes, I'm sure that one of the Maple plot devices is cps (not eps). The c in cps stands for color. But in Linux I get color encapsulated Postscript (.eps) when using the right-click Context Menu on a plot in Maple 11. So maybe that works for you too, in Windows or what have you. In that case, you probably don't need to set the plot device to cps, as Export might work fine to produce color .eps. If you look at the .eps file with Ghostview or GSview or similar, does it show as color? If so, then maybe you are OK. Aren't most dvi viewers only capable of displaying in greyscale, even if they contain color embedded .eps? If you run the .dvi through dvips (or whatever MikTeX has for that) then does the resulting final .ps display or print it in color? What if you produce pdf from it, does that show the color? acer
Yes, I'm sure that one of the Maple plot devices is cps (not eps). The c in cps stands for color. But in Linux I get color encapsulated Postscript (.eps) when using the right-click Context Menu on a plot in Maple 11. So maybe that works for you too, in Windows or what have you. In that case, you probably don't need to set the plot device to cps, as Export might work fine to produce color .eps. If you look at the .eps file with Ghostview or GSview or similar, does it show as color? If so, then maybe you are OK. Aren't most dvi viewers only capable of displaying in greyscale, even if they contain color embedded .eps? If you run the .dvi through dvips (or whatever MikTeX has for that) then does the resulting final .ps display or print it in color? What if you produce pdf from it, does that show the color? acer
First 557 558 559 560 561 562 563 Last Page 559 of 591