Joe Riel

9660 Reputation

23 Badges

20 years, 3 days

MaplePrimes Activity


These are replies submitted by Joe Riel

@Carl Love There is nothing wrong with declaring ModuleApply as static, that is what is normally done when the ModuleApply is used an object factory, which so far is all I've ever used it for. By module factory I mean, for example,

export
     ModuleApply :: static := proc()
         Object(Incrementer, _rest);
     end proc;

That allows instantiating an object of type Incrementer by doing

      cnt := Incrementer();

I didn't bother assigning ModuleApply in my example to keep it short. What you want to do (myself as well) is to use ModuleApply as an object method, so that one can do

cnt := Object(Incrementer):
cnt(); # expecting to call the ModuleApply

That, alas, doesn't work because Maple object methods are supposed to pass the object as an argument. You can achieve that with

export
     ModuleApply :: static := proc(self :: Incrementer)
          self:-cnt := self:-cnt + 1;
     end proc:

However, the usage is then

     cnt(cnt);

which is not to my liking. Presumably you could also do

    ModuleApply(cnt);

But that is no better. Hence the hackish use of the exclamation function.

Addendum I suspect the syntax checker doesn't detect that (use of static modifier with direct reference to object local) because it isn't a syntax error, it's really a usage error. My commentary on the use of ModuleApply as an object method assumed that it was declared as static; I haven't experimented with using non static methods. 

I haven't looked closely at the solution, but am wondering why all solutions are shown as a 6x6 grid.  The problem doesn't specify the grid size of the room.  Was that omitted?

@Carl Love The module isn't necessary.

Incrementer2 := proc()
local i := 0;
    proc()
        i := i+1;
    end proc;
end proc:

cnt1 := Incrementer2():
cnt2 := Incrementer2():

cnt1(), cnt1(), cnt2(), cnt1();
                             1, 2, 1, 3

One of the reasons for introducing objects is that the static procedures are not reproduced with each instantiation; there is single common procedure that is used by the separate objects. Using Maple modules, which are more a packaging construct, as dynamic objects is not ideal, objects are better suited to that task, but they are a recent addition.

@vv Yes, of course.  Any linear improvements are ultimately futile, but still have the occasional benefit.

@vv In thinking about the brute-force algorithm, there is a theoretical improvement that could be made. The Permute constructor takes a 'plain' option, which then generates permutations using the plain ordering; sequential permutations differ by a transposition of an adjacent pair.  If the selected pair was available from the iterator, one could use it to compute the current sum from the previous value without having to sum over the entire path. If I can make it work effectively, I'll consider adding it to Permute.

@Carl Love Nice example. What happens when you omit ModuleType? It worked fine here.

See the Special Considerations section of the object,operators help page.  The `+` and `*` operators should allow n-ary arguments. Adding `*` is necessary to handle p1 + p1, where p1 is of type Point, because the Maple simplifier will first convert that to 2*p1. A reasonable implementation is

    `+`::static:= proc(pts :: seq(Point), $)
        Point(add(p:-x, p=pts), add(p:-y, p=pts));
        end proc,
    `*`::static := proc()
    local k,p;
        (p,k) := selectremove(type,[_passed],'Point');
        if numelems(p) <> 1 then
            "illegal product";
        end if;
        k := mul(k);
        Point(k*p[1]:-x, k*p[1]:-y);
    end proc,

Can you give a simple example of what you have in mind?

@Carl Love Hmm.  I had only partially tested ?[] and thought it worked here, as it should. Consider

A := [a,b,c]:
(indx -> `?[]`(A,indx))([2]);  # evaluates to b, as expected
(() -> `?[]`(A,args))([2]);    # this is what is produced by using curry
Error, (in unknown) invalid input: ?[] expects its 2nd argument, index, to be of type list, but received [2]

It appears that `?[]` is checking its argument type (a sequence, because of the use of args) before evaluating it, which leads to the error. The `?[]` function isn't really intended to be called directly, but rather is the means by which the index operation can be overloaded. I'll report this as a kernel bug.

@Carl Love That's some fine Maple esoterica.  I'm referring, of course, to the curry expression. That particular use of `?()` isn't, so far as I can tell, documented (it is mentioned in the help page for use and in object overloading of procedure).  Slightly less obscure, and safer, would be using  `?[]` in its place.  The `?()` here uses programmer's indexing, which also means that the list of indices can contain a single integer, but, more significantly will fail if A is an Array with indices that do not begin at 1. Clearer would be indx -> A[op(indx)] in place of the curry expression.

@AmusingYeti I'm not clear as to what you want.  The result currently being used is a Maple table, intended to be used to provide a reverse map from value to indices.   The format you are asking for is not valid Maple. As such do you want it to be generated as a string, so that it can be output to a file?

@Carl Love Yes, using ListTools:-Classify is a good way to make this efficient. For clarity and the ability to debug it, I'd probably start with 

InvertRtable := proc(R :: rtable)
local tmp;
    tmp := ListTools:-Classify(rhs, rtable_elems(R));
    map(proc(s) local eq; seq([lhs(eq)], eq = s) end proc, tmp);
end proc:

A downside of using rtable_elems is that it returns no equations for unassigned entries. One could do something like the following, which is intended to be easily debuggable.

InvertRtable := proc(R :: rtable)
local indx,tmp;
    tmp := [seq(indx=R[op(indx)], indx=[indices(R)])];
    tmp := ListTools:-Classify(rhs, tmp);
    map(proc(s) local eq; seq(lhs(eq), eq = s) end proc, tmp);
end proc:

@Carl Love (for Tom) as an example, consider the Matrix 

 [1    0    1]
 [           ]
 [1    1    0]
 [           ]
 [0    1    1]

in R, the reduced row echelon form is

 [1    0    0]
 [           ]
 [0    1    0]
 [           ]
 [0    0    1]

which has rank 3. In GF(2) the reduced form is

 [1    0    1]
 [           ]
 [0    1    1]
 [           ]
 [0    0    0]

which has rank 2.

@Carl Love Interesting.  I see what you mean.  Did not expect that, offhand.

@Carl Love Yes, it's a method in Iterator.  More exactly, a method of the BinaryGrayCode object, as it is for each object returned by the Iterator object constructors.  Probably I should write a separate post discussing the use of objects in Maple.  For those of us more familar with regular procedures, the manner in which object methods get dispatched seems strange at first.

@Carl Love I have not compared with yours, but here's an alternative.  

Cnt := proc(n :: posint)
local M, M2, P, cnt, found;
    P := Iterator:-BinaryGrayCode(n^2):
    M := ArrayTools:-Alias(output(P),[n,n]):
    M2 := Matrix(n,'datatype'=integer):
    cnt := 0:
    found := table():
    in P do
        M2(..) := M(..);
        if (LinearAlgebra:-Modular:-Rank)(2,M2,'inplaceREF') <= n-1 then
            cnt := cnt+1;
            found[cnt] := copy(M);
        end if;
    end do:
    cnt, found;
end proc:

Note that there is no explicit loop variable.

First 30 31 32 33 34 35 36 Last Page 32 of 195