Joe Riel

9660 Reputation

23 Badges

20 years, 3 days

MaplePrimes Activity


These are replies submitted by Joe Riel

Yes, seq is the proper approach. Your last comment, however, is incorrect. That is, hlist + flist does not "concatenate" the lists, rather, it adds their elements, term by term (it generates an error if the lists are not the same length). One way to catenate them is to do [op(hlist), op(flist)].
Yes, seq is the proper approach. Your last comment, however, is incorrect. That is, hlist + flist does not "concatenate" the lists, rather, it adds their elements, term by term (it generates an error if the lists are not the same length). One way to catenate them is to do [op(hlist), op(flist)].
I don't know what you are asking. However, the previous lines (before the if statement) should probably be handtotal := proc( hand :: list ) local card, total; global Cardvalues; total := add(Cardvalues[card], card = hand); ... end proc: Depending on what version of Maple you are using, you'll probably want to put make handtotal a member (local or export) of a module and make Cardvalues a local member of the module. That way it isn't a global variable.
That one is tricky. Here is a crude ad hoc approach (subsop is for convenience only), maybe someone can suggest something a bit more straightforward.
v := I*exp(I*theta):
subsop(1 = exp(j*Pi/2), v);
                           exp(1/2*j*Pi)*exp(I*theta)
combine(%, exp);
                           exp(1/2*j*Pi+I*theta)
subs(j = I, %);
                           exp((1/2)*I*Pi+I*theta)
op(%);
                           (1/2)*I*Pi+I*theta
That one is tricky. Here is a crude ad hoc approach (subsop is for convenience only), maybe someone can suggest something a bit more straightforward.
v := I*exp(I*theta):
subsop(1 = exp(j*Pi/2), v);
                           exp(1/2*j*Pi)*exp(I*theta)
combine(%, exp);
                           exp(1/2*j*Pi+I*theta)
subs(j = I, %);
                           exp((1/2)*I*Pi+I*theta)
op(%);
                           (1/2)*I*Pi+I*theta
Interesting comment, however, your suggestion has a few problems. First, it doesn't check that the number of elements in the two lists match. Second, there is a typo (missing terminator for the procedure, no biggie). Third, it is not, in fact, faster than Roman's suggestion, but slower---it's half the speed for lists with 10 elements. I suspect that the cause is the use of 'satisfies'. Using, as you suggest, a structured function to replace the "hideous" line reduces the time by about 20%. A more substantial savings can be made by replacing the checking of each index with calls to min and max. The following is about 3x faster than Roman's original:
 AddType('fst3'
         , proc(f)
              ( type(f, 'FST'(list(numeric),list))
                and nops(op(1,f)) = nops(op(2,f))
                and min(op(op(1,f))) >= 0
                and max(op(op(1,f))) <= 1
              )
           end proc);
Not knowing what the orignal poster intends, its hard to say whether speed in type checking this data-structure is an issue. If it were, I'd suggest using something simple and fast, say, specfunc(anything,'FST') and doing the validation as a separate step, only when needed. Using the modular approach I suggested, where a new structure is checked at creation, might eliminate the need for re-validation.
I have been informed that in Maple 10.04 you can use subscripted names as parameters in display mode. They aren't indexed, but created by clicking the "Aa" symbol in the third column of the first row of the Layout palette (adjacent to the "Ai" symbol, which inserts an indexed symbol).
I have been informed that in Maple 10.04 you can use subscripted names as parameters in display mode. They aren't indexed, but created by clicking the "Aa" symbol in the third column of the first row of the Layout palette (adjacent to the "Ai" symbol, which inserts an indexed symbol).
It's not necessary to use a separate table and define a function; you can instead just use the remember table of the function:
f(a) := 0.4:
f(b) := 0.2:
f(c) := 0.7:
You haven't specified how to form the union if the lists of names don't match. I'll mostly ignore that condition, then, and offer the following approach for union
# restart;

fst := module()
export New,`union`;
local ModuleLoad, printfst;
option package;

    printfst := proc(indx, vals)
    local i;
        [seq](convert(vals[i],'`local`')[indx[i]], i=1..nops(indx));
    end proc;

    ModuleLoad := proc()
        TypeTools['AddType'](':-FST'
                             , m -> type(m,'`module`'('index', 'names')));

        `union` := proc( a :: FST, b :: FST )
        option overload;
            if a:-names = b:-names then
                New( zip(max, a:-index,b:-index), a:-names);
            else
                'a union b';
            end if;
        end proc;

    end proc;

    New := proc(indx :: list(numeric), nmes :: list(name))

        if nops(indx) <> nops(nmes) then
            error "number of indices (%1) does not match number of values (%s)";
        elif not andmap( proc(ix) evalb(0 <= ix and ix <= 1) end proc
                         , indx ) then
            error "indices must be between 0 and 1, inclusive";
        end if;

        module()
        export index, names;
        local ModulePrint;

            ModulePrint := () -> printfst(index,names);
            index := indx;
            names := nmes;

        end module;

    end proc;

    ModuleLoad();

end module:
Here's what it does:
with(fst):
f1 := New([0.2, 0.3], [x,y]):
f2 := New([0,1], [x,y]):
f3 := f1 union f2;
            f3 := [x[0.2], y[1]]
Here's a rather simplistic approach. It works over the global name space, but not for local variables.
A := {a,b,c}:
B := {b,c}:
f := proc(s) anames(identical(s)) end proc:
f(A union B);
                 {A}
f(A intersect B);
                 {B}
Another way to handle this is to use a module as the data structure. One advantage to using a module is that a ModulePrint member can be assigned; it is used whenever the module is displayed. Type checking can be simplified because modules are created with a constructor that validates the fields. Here is one approach. I chose the names `index' and `value' for the two lists in the old FST data-structure, the names probably are not appropriate.
fst := module()
export New;
local ModuleLoad, printfst;
option package;

    printfst := proc(indx, vals)
    local i;
        [seq](convert(vals[i],'`local`')[indx[i]], i=1..nops(indx));
    end proc;

    ModuleLoad := proc()
        TypeTools['AddType'](':-FST'
                             , m ->  type(m,'`module`'('index', 'value')));                                      
    end proc;

    New := proc(indx :: list(numeric), vals :: list(name))

        if nops(indx) <> nops(vals) then
            error "number of indices does not match number of values";
        elif not andmap( proc(ix) evalb(0 <= ix and ix <= 1) end proc
                         , indx ) then
            error "indices must be between 0 and 1, inclusive"
        end if;

        module()
        export index, value;
        local ModulePrint;

            ModulePrint := () -> printfst(index,value);
            index := indx;
            value := vals;

        end module;

    end proc;

    ModuleLoad();

end module:
To use this you could do
with(fst):
f := New([0.2, 0.3], [x,y]);
type(f,FST);
The above implementation is simplistic. You might not want to export index and value, that allows a user to directly modify them and hence possibly generate an illegal structure. Safer would be to export methods (procedures) that access (and modify) local fields.
Roman's suggestion should get you started, but here are a few finer points to consider. Rather than using `type/FST` to create the type, you might consider using TypeTools[AddType]. Thus
TypeTools[AddType]('FST'
                   , proc(f)
                      ( type(f, specfunc(list,'FST'))
                        and nops(f)=2
                        and type([op(f)], 'listlist')
                        and andmap(proc(a) 
                                     evalb(a >= 0 and a <= 1) 
                                   end proc, op(1,f)));
                     end proc);
An advantage to using TypeTools is that the global name space isn't polluted. Alas, there is currently no equivalent PrintTools package, so to handle the printing you need to assign the global procedure `print/FST`. You specified that anything could be allowed in the second list. If that is indeed the case (though I suspect names might be more likely) you may need to modify Roman's suggested `print/FST` procedure. Consider what would happen if an element of the list were actually a list, say [a]. Then the if the corresponding 'index' is 0.5 the expression [a][0.5] is created by the print procedure, which generates an error. Another possibility is that the index is 1, which creates [a][1] and so prints `a', not what you wanted. If that is a concern, one possiblity is to do something like
`print/FST` := proc(a, b) local i;
     if type('FST'(args),'FST') then
         [seq](convert(b[i],'`local`')[a[i]], i=1..nops(a));
      else
         'FST'(args)
      end if;
end proc:
This converts the elements of the second list to local names and then appends an index to them. The reason for adding the conditional was to handle the case of an improperly formed FST element, say FST(1,2,3).
Maple 10 works fine on my Debian system (Sarge, unstable).
No, it took about 3 seconds. I multiplied the time from 1 to 10^7 by 90 to compute the time it should take (assuming linearity) to go from 10^8 to 10^9.
First 181 182 183 184 185 186 187 Last Page 183 of 195