Joe Riel

9048 Reputation

23 Badges

16 years, 338 days

MaplePrimes Activity


These are answers submitted by Joe Riel

I have written a package, Bark, available on the Maple Cloud, that partially addresses this issue.  I use it to convert Maple programs into command line tools. Because I work almost exclusively on Linux, it hasn't been tested much on Windows, though I did so originally.  However, on Windows it requires Cygwin (it creates a small bash file that calls maple).  It possibly could be extended to work from PowerShell, however, I didn't know enough about PowerShell to do so.

There are quite a few ways to do this in Maple.  Here's one. 

M := Matrix([[1,2,"A"],[2,3,"B"],[3,4,"A"]]):

# create list of indices of the desired rows
rows := [seq(ifelse(M[i,3]="A", i, NULL), i=1..upperbound(M,1))]:

# create submatrix that contains the desired rows
M[rows,..];

 

Function calls use parentheses, not square brackets.  Also, the exponent should be applied after the parentheses.  That is, change f^2[n-2] to f(n-2)^2 and f[n-1] to f(n-1).  To compute the derivative, do eval(diff(f(18),x), x=2*Pi).

Am not certain, but believe there is not a way to do this, at least if you want to refer to the object itself from a procedure in a submodule. You could, of course, do
 

A:=module()
    option object;
    local name::string:="";

    export ModuleCopy::static:= proc( self, proto, name::string, $)
         self:-name := name;
    end proc;

    export process_1::static:=proc(_self,$)
       B:-process_2(name);
    end proc;

    #method process_2 is now inside a module.
    local B :: static := module()
    export
        process_2::static:=proc(nm :: string)
            printf("in B:-process_2: %s\n",nm);
        end proc;
    end module;

end module:

o:=Object(A,"me"):
o:-process_1();

 

This looks like a bug.  I'll report it.  Note that the help page for copy does not state that it is intended for copying objects, however, it doesn't say what it does if the input is other than a table, rtable or record and the deep option is used.

What were you intending? 

The following extension may be helpful.  It adds a call to FixID in the ModuleConstructor for person.  The definition of FixID is reassigned in employee, the inheriting class.  If you want the FixID of the inheriting object to be used, then you'll need to use (as shown) either function or the parameter name, self, as the namespace (prepended with colon-dash) for FixID; omitting it will use FixID from the base class (person).  This is discussed in the help page object,function_mechanism.

person := module()
option object;
local idnumber :: integer := 0;
local name :: string := "";
export
    ModuleCopy :: static:= proc( self :: person
                               , proto :: person
                               , name :: string
                               , idnumber :: integer
                               , $)
        self:-idnumber := idnumber;
        self:-name := name;
        function:-FixID(self);
    end proc;
export
    FixID :: static := proc(_self)
        idnumber += 1;
    end proc;
export
    GetID :: static := proc(_self)
        idnumber;
    end proc;
end module;

employee := module()
option object(person);
local salary :: integer := 0;
    ModuleCopy :: static := proc( self :: employee
                                  , proto :: employee
                                  , name :: string
                                  , idnumber :: integer
                                  , salary :: integer
                                  , $)
        person:-ModuleCopy(self, proto, name, idnumber);
        self:-salary := salary;
    end proc;

    FixID := proc(_self)
        idnumber += 100;
    end proc;

end module:

bob   := Object(employee, "Bob", 1, 100):
GetID(bob);

There is another subtlety.  A procedure like FixID should probably be a local rather than an export.  However, if it is declared as a local, then the call function:-FixID(self) in ModuleConstructor will always call the version assigned in the person object.  To ensure that it calls the modified version, change the call to self:-FixID(self).

I just realized that what you are looking for can be readily accomplished by calling the ModuleConstructor of the base object from the ModuleConstructor of the inheriting object using the base classname to reference it. In your example,

person := module()
option object;

local idnumber::integer:=0;
local name::string:="";

export
    ModuleCopy::static:= proc( self :: person
                               , proto :: person
                               , name::string
                               , idnumber::integer
                               , $)
        self:-idnumber := idnumber;
        self:-name := name;
    end proc;

end module;

employee:=module()
option object(person);
local salary::integer:=0;

    ModuleCopy :: static := proc( self :: employee
                                  , proto :: employee
                                  , name::string
                                  , idnumber::integer
                                  , salary::integer
                                  , $)
        person:-ModuleCopy(self, proto, name, idnumber);
        self:-salary := salary;

    end proc;

end module:


bob   := Object(employee, "Bob", 1, 100):
alice := Object(employee, "Alice", 2, 80):

 

The inheritance of Maple's objects is limited; I have yet to use it in an actual application.  I believe that you will have to effectively duplicate the code in the ModuleCopy of the original class.  However, if it were more complex than simple assignments, you could make that part an external method and call it from the ModuleCopy of the base class and the inherited class.  Here is a toy example (it's only simple assignments, but shows the idea).
 

person := module()
option object;

local masterid :: static := 0;
local idnumber;
export name :: string := "";

export
    ModuleCopy :: static:= proc( _self
                                 , proto
                                 , nm :: string
                                 , $
                               )
        SetName(_self, nm);
        SetID(_self);
    end proc;

export
    SetName :: static := proc(_self, nm)
        name := nm;
    end proc;

export
    SetID :: static := proc(_self)
        idnumber := ++masterid;
    end proc;

export
    GetID :: static := proc(_self)
        idnumber;
    end proc;

export
    GetName :: static := proc(_self)
        name;
    end proc;

end module;

#---- extend the above class

employee := module()
option object(person);
export salary::integer:=0;

    ModuleCopy :: static := proc( _self
                                  , proto
                                  , nm :: string
                                  , salary :: integer
                                  , $
                                )
        SetName(_self, nm);
        SetID(_self);
        SetSalary(_self, salary);

    end proc;

export
    SetSalary :: static := proc(_self, sal :: positive)
        salary := sal;
    end proc;

export
    GetSalary :: static := proc(_self);
        salary;
    end proc;
end module;

alice := Object(employee, "alice", 80);
bob   := Object(employee, "bob", 100);

GetID(bob);
GetSalary(alice);

 

I assume this occurs because the procedures in the list passed to overload are not exports of the module.  You could work-around this by assigning them as exports and then calling them from the overloaded procedure.  For example

export foo1 :: static := proc(_self, k :: integer) ... end proc:
export foo2 :: static := proc(_self, k :: rational) ... end proc:
export foo :: static := overload([
  proc(_self, k::integer) option overload; foo1(_passed); end proc,
  proc(_self, k::rational) foo2(_passed); end proc ]):
                                           

Not ideal but it should work. 

Later It makes more sense to declare foo1 and foo2 as locals, since presumably they wouldn't be directly accessed.  That also works.

I consider this a bug and have previously reported it as such.  The use of _self as a formal parameter in an object method allows object locals to be accessed without prepending the _self:-, however, this only works if the formal parameter _self is declared with no type.  If you remove the type declaration in ModuleCopy, then you can access the name local directly.

Rather than just give you the solution, here's the basic idea.

J := proc(n :: posint)
    if n = 1 then 1
    elif n :: 'even' then
         # some expression calling J
    else
         # some other expression calling J
   end if;
end proc:

# to check the result, do
[seq(J(n), n = 1..16)];

 

There is some weirdness with the 2D input for the plot command.  I exported the worksheet as Maple commands:
 

restart: i := I:
with(LinearAlgebra): 
E := 100;
Z(R) := (5+5*i)*(R-10*i)/`+`(5+5*i,R-10*i);
I__R(R) := E/Z(R);
F(R) := abs(I__R(R)); _maple_label_L51 := '%';
# "plot(F(R),R=0..100)->"
plot(_maple_label_L51);

Clearly there is a problem with the plot statement.  Reentering it manually fixes the issue.

As an aside, it's probably better not to assign functions using the syntax foo(x) := whatever; that only works in 2D mode. The "standard" way is to do foo := x -> whatever. 

By Geometric Algebra I assume (didn't open the link) you mean David Hestenes' take on Clifford Algebra.  There is a Maple package for Clifford Algebra, named Clifford I believe, by Rafal Ablamowicz.  I haven't looked at it in a long while.  At that time I wrote a package, named Glyph, for doing Clifford Algebra in Maple, but it is much out of date.  Ian McCreath revised it a few years ago, for his own purposes, mainly for study, I think.  I could ask him to contact you.  Writing a Maple package for this is a a great way to learn.

As tomleslie suggested, posting an example would be helpful.  Piecewise expressions that don't depend on solving variables (currents and voltages) should already be doable; if not, I'll extend Syrup. Piecewise expressions that depend on solving variables would be really useful, but its unlikely I'll implement them.

White-space is not needed after the closing parenthesis in the formal parameter sequence of a procedure statement.  For example

proc(x)x^2;end(z);
                                         z^2

There are places where white-space is required, say after a for.

Later Actually, you technically don't need white-space even after a for, and possibly not anywhere, though the alternative is rather ugly.  I'll leave that as a puzzle for now.

1 2 3 4 5 6 7 Last Page 1 of 110