Joe Riel

9660 Reputation

23 Badges

20 years, 3 days

MaplePrimes Activity


These are replies submitted by Joe Riel

First, a correction or two. The procedures I gave have two flaws. First, the counter in the (empty) do loop should start at one rather than zero. Second, they should return 32 for inputs greater than 16 (I extended the algorithm). Here is the correction:
d4 := proc(n)
local i, m;
    if n::posint then
        if n > 16 then 32;
        else
            m := n;
            for i from 1 while irem(m,2,'m') = 0 do od;
            procname(n) := 2^i;
        end if;
    elif n=0 then
        procname(n) := 1;
    else
        'procname(n)';
    end if;
end proc:
Here is code for your Q procedure:
Q1 := proc(m)
local i;
    mul(1/2*(2*i-1)*d4(i)/i, i = 1..m)/mul(d4(i),i=1..m);
end proc:
Note that we can combine the two products, in which case the d4's cancel. We can then express that as a symbolic product:
Qm := simplify(product(1/2*(2*i-1)/i, i = 1..m));
                   Qm := GAMMA(m+1/2)/GAMMA(m+1)/Pi^(1/2)
To test this we can do
simplify(Q1(1000) - eval(Qm,m=1000));
                        0
Maple doesn't provide any routines for directly working on binary. You could use convert/base to convert the number to a list of 1's and 0's, however, you'll find that using the irem method I gave is faster.
Do you mean the .dvi file generated by tex/latex? On *nix systems there are a few dvi readers: xdvi and yap are two. I'm not sure about Windows, but if you have a TeX distribution one will be included. You can also use dvips to convert the dvi to postscript.
If you only need to evaluate it on 16 integer inputs, then you can save the computed values so you don't have to recompute them (though speed of evaluation doesn't appear to be a concern).
d4 := proc(n)
local i, m;
    if n::posint then
        m := n;
        for i from 0 while irem(m,2,'m') = 0 do od;
        procname(n) := 2^i;
    elif n=0 then 
        procname(n) := 1;
    else
        'procname(n)';
    end if;
end proc:
What do you mean by "shed some light"? I assume you understand what the function does. That is, if you consider the binary representation of the input, it returns the value of the right most 1 followed by the trailing zeros. For example, d(12) = d(11002]) = 1002 = 4.
There are several issues here. First, the mul procedure, like add and seq, only works with integer values in the range parameter. You cannot do, for example, mul(x, i = 1..y), where y is not an integer. The product procedure, which is used to compute symbolic products (analagous to sum), does allow symbolic values in the range parameter. However, to get this to work, your procedure must be able to deal with a nonintegral input. I'll get back to that point in a moment. You are using the mod function. Note that mod is actually a Maple environmental variable that may be assigned either modp or mods (see the ?mod help page). The default is modp, however, if it were assigned mods then you could get an unexpected result. Actually, that won't happen with the procedure you wrote, but it is something to consider. Unless there is a reason to use mod, you should probably use modp. As Jacques stated, to enable your procedure to handle nonintegral values, you need to return what is called an unevaluated function call that, when evaluated, returns the proper result. That is done by using forward quotes around the function name (or the special name, procname). Rather than doubling the modulus each time, it is usually faster to half the value. Here is a version of your function that works with any positive integer:
d2 := proc(n)
local i, m;
    if n::posint then
        m := n;
        for i from 0 while irem(m,2,'m') = 0 do od;
        2^i;
    elif n=0 then 1;
    else
        'procname(n)';
    end if;
end proc:
You can also add some 'smarts' to the procedure to enable it to handle negative integers, fractions, and symbolic products:
d3 := proc(n)
local i, m;
    if n::posint then
        m := n;
        for i from 0 while irem(m,2,'m') = 0 do od;
        2^i;
    elif n::negint then -procname(-n);
    elif n=0 then 1;
    elif n::fraction then procname(numer(n))/procname(denom(n));
    elif n::`*` then map(procname, n);
    elif n::`^` and op(2,n)::integer then applyop(procname,1,n);
    elif n::typefunc(anything,identical(Product,product)) then
        applyop(procname,1,n);
    else
        'procname(n)';
    end if;
end proc:
You'll want to check that for correctness. Some of my extensions may be questionable.
Your "few more years of concentrated effort" is probably also an under-estimation 8-). While the notion of creating a literate programming tool with a Maple worksheet as a typeset output is appealing, I doubt whether it would be useful (not to mention possible). One would really want the created worksheet to be executable, but there is currently no way to split the source for a procedure (in a worksheet) into sections with interspersed typeset comments (let alone reshuffling chunks as is done in Knuth's literate programs). It is, though, an interesting idea.
I've done a fair amount of literate programming using noweb with Maple. I've written noweb filters for indexing Maple noweb files. These were available on my home page, alas, it no longer exists. I'll try to post them on blog here.
Another method is to use sscanf.
sscanf("2","%d")[];
                    2
Here's a simple example:
restart;
with(Maplets[Elements]):
maplet := Maplet([BoxCell(ListBox([seq(StringTools:-Random(15,'alpha'),i=1..20)]),'vscroll=always')]):
Maplets[Display](maplet);
The problem is the minus signs. They are some other symbol than the usual.
The problem is the minus signs. They are some other symbol than the usual.
While it isn't a book, and won't help you there, you might check out my Syrup package for analyzing electric circuits. It is available at the Maple website in the Applications section. It can read spice decks and symbolically solve them. For example,
with(Syrup):
ckt := "
V1 1 0
R1 1 2
C1 2 0
.end":
syrup(ckt, ac);

                       /                      V1     \ 
                      { v[1] = V1, v[2] = ----------- }
                       \                  1 + s C1 R1/ 
dsolve(syrup(ckt,tran));
                                          /    t  \   
                       v[C1](t) = V1 - exp|- -----| V1
                                          \  C1 R1/   
Alas, it doesn't have a transmission line element, but you might find it useful, regardless.
There currently, alas, is no way to program a procedure (say JordanForm) so that one of its keyword parameters, such as 'output=Q', works regardless whether Q has a local binding. Note that this isn't necessarily the case for the keyword ('output'). The keyword parameters introduced in Maple10 work regardless whether the keyword itself is local. However, that doesn't apply to JordanForm, which was written before Maple 10 and uses an older mechanism for handling keyword parameters. So, if you declared 'output' local, then you'd have to do ':-output = :-Q'.
Yes and no. The Q in question is a predefined value of the output option. Acceptable values are the global names J and Q, or a list of those names. Similary, the left side of the output option is also a global name, the name output. Changing the names J and Q to JordForm and TransMatrix, as you suggest, would have lessened the likelihood of a conflict with a local name. Making them strings, say, "J" and "Q", as Tobey suggests, would eliminate the possibility of a conflict. As it is, the safe method is to use ':-Q' and ':-J'. The colondash operator refers to the global name, regardless a local binding, the forward quotes prevent the name from being replaced with a (global) assigned value.
Yes, I had missed your concluding paragraph. Possibly my reiteration will inform others. The reason, I believe, for names rather than strings is chiefly historical. Strings weren't available before Maple V R5, so names were once the only way to go. While newer procedures (the entire LinearAlgebra package, for instance) could have used strings, I assume that that wasn't done because of the inconsistency in usage, that is, with some procedures one would use strings as keywords, while with others one would use names. Note that the DifferentialGeometry package, which is new with Maple11, uses strings as keywords for many of its procedures.
First 178 179 180 181 182 183 184 Last Page 180 of 195