Joe Riel

9250 Reputation

23 Badges

17 years, 125 days

MaplePrimes Activity


These are replies submitted by Joe Riel

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.

With Emacs, I search for the regular expresssion \<i\>.  An alternative is to use the debugger.  Consider
 

foo := proc()
    for cnt to 20 do
        "whatever";
       i := cnt;
    end do;
end proc:

stopwhen([foo,i]):
foo();

That will cause the debugger to stop at the statement which assigns the i.

The solution includes the equations {Vx[XQ601A] = v[D], v[D] = v[D]}.  Syrup interprets the presence of Vx[XQ601A] and v[D] to mean there are an unsolved variables (they are solving variables).

@mehdibgh I assume that in the real problem you are using Matrices or Arrays, which are mutable Maple structures (in this context, mutable means they can be changed without reallocating memory). If possible, the best approach would be to continually reuse an assigned Matrix, or small number of Matrices. In the toy problem you gave, my suggestion computes a Matrix with symbolic values one time, however, the following loop then generates a separate Matrix with each increment.  If you don't need to save all the resulting matrices, you could do something like the following
 

U := simplify((A+1/A).B);
V := copy(U); # one time allocation of V
for s to n do
    subs['inplace'](t=s, V); # modify V 
    # do something with V     
    V[] := U[];              # transfer content of U to V, but don't allocate more memory
end do:

 

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