Joe Riel

9270 Reputation

23 Badges

17 years, 136 days

MaplePrimes Activity


These are replies submitted by Joe Riel

@acer The use of print came directly from the original:

(**) showstat(WARNING);

WARNING := proc(msg)
   1   if not _Env_hide_warnings = true then
   2       print(INTERFACE_WARN(1,msg,_passed[2 .. -1]))
       end if
end proc

The environment variable is relatively new (added a couple years ago); useful to know about.
Here's an updated version of the module that fixes a few bugs (thanks) and adds a clear option to Caught to clear a warning once it has been noted.
 

Warnings := module()
option package;

local catchall, formats, warnings;

export
    Catch := proc(fmts? :: seq(string), { all :: truefalse := false })
        if all then
            catchall := true;
        else
            formats := [fmts?];
        end if;
    end proc;

export
    ModuleLoad := proc()
    global WARNING;
        unprotect('WARNING'):
        WARNING := proc(fmt)
            if catchall or Match(fmt) then
                warnings[fmt] := StringTools:-FormatMessage(fmt, _rest);
            else
                streamcall('INTERFACE_WARN'(1,fmt,_rest));
            end if;
        end proc;
        protect('WARNING'):
        Clear();
    end proc;


export
    Display := proc()
    local msg;
        for msg in [entries(warnings,'nolist')] do
            printf("%s\n", msg);
        end do;
    end proc;

export
    Caught := proc(fmt :: string, { clear :: truefalse := false } )
        for f in [indices(warnings,'nolist')] do
            if SearchText(fmt,f)=1 then
                if clear then
                    warnings[f] := evaln(warnings[f]);
                end if;
                return true;
            end if;
        end do;
        return false;
    end proc;

local
    Match := proc(fmt)
        ormap(f -> SearchText(f, fmt)=1, formats);
    end proc;

export
    Clear := proc()
        catchall := false;
        warnings := table();
        formats := [];
        NULL;
    end proc:

export
    ModuleUnload := proc()
        kernelopts('unread' = ':-WARNING');
    end proc;

    ModuleLoad();

end module:

 

@PaulNewton A colon suppresses output only if it terminates a top-level statement; colons that terminate (technically separate) substatements of a structured statement have no effect on whether output is generated.

@PaulNewton For an Excel spreadsheet you should be able to use the ImportMatrix command to assign the data to a Maple matrix.  Here I'll manually assign the data to avoid creating a spreadsheet:

# M := ImportMatrix("acid-data.xls"); 
M := Matrix([["acetic acid", 1.75e-5], ["ammonia", 5.70e-10], ["benzoic acid", 6.28e-5]]):
# create list of strings
L := [seq(sprintf("%s (%g)", M[i,1], M[i,2]), i = 1 .. upperbound(M,1))]:
# insert list into combobox (previously inserted into worksheet)
DocumentTools:-SetProperty("ComboBox0", 'itemList', L);

To do something with a selection you can either parse the selected string, or probably simpler and better, use DocumentTools:-GetProperty("ComboBox0", 'selectedindex') to return a 0-based index that you can then increment by one and use as a row index into the Matrix.

Is there a space between the $ifdef and the __FILE__?  The following worked for me.
File named FILE.mpl:

file := __FILE__:
$ifdef __FILE__
print(file);
$endif

From O/S:

$ maple FILE.mpl
(**) file := "FILE.mpl":
(**) print(file);
                                                      "FILE.mpl"

Followup

I experimented with your example code and reproduced your results.  A little more experimentation suggests what is happening.  It seems as though __FILE__ is only defined when it is actually used in the file (other than in the condition of a preprocessor conditional).   So if you insert, say, # __FILE__ before the conditional that checks for it, then the observed output of a call to f is the desired
     "1", "2", "3", "4", "FILE.mpl"
 

@zenterix Here's what I do (I've written 100+ Maple packages, 75 of which are installed as personal toolboxes).  The source for each toolbox is kept in its own directory tree, under $HOME/maple; the actual location is not significant.  To create a new package, I do

$ cd ~/maple
$ cp -r clone Foo  # copy a custom source tree to Foo, the new package
$ tree Foo  # display the tree
Foo
├── bin
│   └── version
├── etc
│   └── MapleHelp_en.xml
├── Makefile
├── maple
│   ├── doc
│   │   └── Intro.md
│   ├── include
│   │   ├── About.mi
│   │   ├── mpldoc_macros.mpi
│   │   ├── standard.mi
│   │   └── test_macros.mi
│   ├── installer
│   │   └── CreateInstaller.mpl
│   └── src
│       └── _PKG_.mpl
├── README
├── README.setup
├── RELEASE-NOTES
└── sbin
    ├── release
    └── setup

8 directories, 15 files

$ cd Foo
$ sbin/setup 

The call to sbin/setup renames and edits some of the source files, expanding __PKG__ to Foo (based on the directory name).  It then creates a git repository.  At that point there is a file Foo/maple/src/Foo.mpl containing a skeleton of a Maple package assignment.   Executing make mla-install will build an mla from the source and install it to ~/maple/toolbox/Foo/lib/Foo.mla, from which Maple will automatically find it when it starts. The Makefile defines a number of useful targets:

$ make help
----------------------------------------------------------------
mla-version	Update maple/include/version.mi
mla		Create Maple archive: Foo.mla
mla-install	Install mla into /home/joe/maple/toolbox/Foo/lib
----------------------------------------------------------------
hlp-version	Update maple/include/version.mpi
hlp		Create Maple help database: Foo.help
hlp-clean	Delete extracted help sources
hlp-install	Install Foo.help in /home/joe/maple/toolbox/Foo/lib
----------------------------------------------------------------
book		Create Foo.maple
intro		Create Foo.intro
book-info-copy	Copy the saved cloud-info from book.info to Foo.maple
book-install	Install package from the book
book-uninstall	Uninstall the book
book-info-save	Save the cloud-info from updated Foo.maple to book.info
book-info-create	Create book.info
----------------------------------------------------------------
tags		Create TAGS file
mint		Check Maple syntax
----------------------------------------------------------------
test		Extract and run test suite
test-clean	Delete extracted tests
test-extract	Extract test suite
test-run	Run test suite
----------------------------------------------------------------
install		Install everything
uninstall	Remove directory /home/joe/maple/toolbox/Foo
----------------------------------------------------------------
installer	Create Maple installer: Foo-1.0.0.mla
installer-zip	Create Maple installer zip file: Foo-1-0-0.zip
----------------------------------------------------------------
sweep		Remove editor temp files
clean		Remove built files and sweep
cleanall	Remove intermediate files

The actual Makefile for each project is small; it assigns a few variables and then includes a common Makefile that is used by all the projects:

$ cat Makefile
# Makefile - for Foo
#
# Maintainer: Joe Riel <jriel@maplesoft.com>

PKG := Foo

VERSION := 1.0.0
CLOUD-VERSION := 1
CLOUD-ID := TBD
CLOUD-DESCRIPTION := TBD

# Assign executables
MAPLE  := $(MAPLE_ROOT)/bin/maple
MINT   := $(MAPLE_ROOT)/bin/smint
MPLDOC := $(MAPLE_ROOT)/bin/mpldoc

# Activate selected make sections
BOOK := true
TEST := true

include Maple.mk

 

For the second problem, there is a bug in the handling/conversion of the subcircuit definitions and nodes.  Should have a fix for it shortly. 

For the first am getting getting a different error, though am using an updated version of Syrup.  Will investigate.

@mmcdara I changed the repository to something suitable for my machine, then ran the script.  The result is what I warned about; the generated mla is not usable.  It does assign the package DesignOfExperiments, however, each of the exports is merely a stub.  To make this work you should add wrap each assignment in the module definition with an eval:

DesignOfExperiments := module()

 export  RunifFaure         := eval(:-RunifFaure)         ,
         FullFactDesign     := eval(:-FullFactDesign)     ,
         CenteredStarDesign := eval(:-CenteredStarDesign) ,
         UniformLHD         := eval(:-UniformLHD)         ,
         UniformLHS         := eval(:-UniformLHS)         ,
         UniformMC          := eval(:-UniformMC)          ,
         dmaxDesign         := eval(:-dmaxDesign)         ;

 option  package ; 

end module:

While that seems to work, I have doubts as to the viability of this method for a hierarchically designed package (i.e. one with submodules).  The robust way to do this is to use external source files, with include statements so that there is one top-level file that defines the module; it has include statements to pull in the procedure and submodule assignments (they can have includes to pull in subprocedures).  In your example, the top level file would look like
 

DesignOfExperiments := module()

option  package;
    
 export  RunifFaure,
         FullFactDesign,
         CenteredStarDesign,
         UniformLHD,
         UniformLHS,
         UniformMC,
         dmaxDesign
    ;

$include <RunifFaure.mpl>
$include <FullFactDesign.mpl>
$include <CenteredStarDesign.mpl>
$include <UniformLHD.mpl>
$include <UniformLHS.mpl>
$include <UniformMC.mpl>
$include <dmaxDesig.mpl>

end module:

Each procedure would be assigned in its own file (FullFactDesign.mpl).  To build the mla you would use a shell command. To get this to work well, you need to build up a little infrastructure (I use a makefile, but a simple shell script will suffice).

There are several advantages to this approach:

  • Source code is isolated from changes to the Maple worksheet format
  • Source can be put under version control
  • Allows using programming editor of choice
  • Allows use of Maple's mint facility to check the syntax 

@mmcdara Do you create mlas from your source code?  A downside of your approach (using globally assigned procedures as the exports of a module) is that the global variables would have to be explicitly saved to the mla.  You could get around that by doing, say

P := proc(x) x^2; end proc:
M := module()
export P := eval(':-P');
end module:

That (using the eval) almost seems mandatory, otherwise name-collision is going to be an issue.
I don't recommend this style.

@acer The OP will have to clarify, but my guess is that he is writing the code in a worksheet and used that method to break the code into chunks instead of one giant input region.  I would not recommend that style.  In external files, use preprocessor $include statements.

@nm My mistake.  I had forgotten about the use of A in foo and was testing the use of _self:-A and A in ModuleCopy. On reflection that made no sense in that there the A appears on the lhs, so wouldn't affect the "otherwise unused" nag.

As before, you can eliminate this nag by adding, somewhere in the assignment to A_class,

$ifdef MINTONLY
      A;
$endif

The preprocessor conditional isn't necessary, the naked A will do, but it's generally better to be clear.

@nm Note that the workaround (using a preprocessor conditional to fake usage) to selectively suppress the mint warning is independent of whether you use _self:-A or A in the code.  

@nm Here's a workaround, again using preprocessor macros.  Not ideal, but it avoids the mint nags and allows using the object local variables without the object name prepended (A vs _self:-A).
 

kernelopts('assertlevel'=2):

$ifdef MINTONLY
$define USE_SELF _self;
$define USE_PROTO proto;
$else
$define USE_SELF
$define USE_PROTO
$endif


A_class:=module()
option object;
local A :: integer :=0;
export
    ModuleCopy :: static := proc( _self, proto :: A_class,m::integer)
        USE_SELF; USE_PROTO;
        A := m; #initialize object private variable
end proc;

export foo :: static := proc(_self,$)
local eq;
    USE_SELF;
    eq := A^2;
    return eq;
end proc;

end module:


a := Object(A_class, 23):
foo(a);

Just a note; I frequently find it useful to make parameters to ModuleCopy optional by giving them defaults based on the proto parameter; if that was done here you wouldn't need USE_PROTO.  For example
 

export
    ModuleCopy :: static := proc( _self, proto :: A_class, m :: integer := proto:-A)
        USE_SELF;
        A := m; #initialize object private variable
end proc;

 

@nm Try the following.  It runs with assertlevel=2 and is mint clean (I never use maplemint):

kernelopts('assertlevel'=2):

A := module()

local
    B := module()
    option object;
    export n::integer := 1;
    local m := 23;
    export
        foo :: static := proc(_self, x)
$ifdef MINTONLY
            _self;
$endif
            m + x;
        end proc;
    end module;

export
    foo := proc()
    local a :: A:-B;
        a := Object(B);
        a:-n := 2;
        a:-foo(23);
    end proc;
end module:


A:-foo();

 

Please upload a worksheet with the equations.  Use the green up-arrow on the toolbar of this site when replying.

I hadn't considered using codegen[optimize] directly in the Custom Component template.  Will create a request for enhancement.

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