Note: the tips and tricks are being moved from the end of the README file to here.
How to define the field of expressions in factored form?
K := Dom::ExpressionField(expr@factor); K(x^2-1);
Note that it is safer to use expr@factor as normalizing function. Indeed, for efficiency reason, polynomials over fields of expressions use syntactical equality to decide for equality to zero; in some cases, the kernel may not detect, and delete, zero terms.
See http://www.mupad.de/BUGS/?bug=1402 for details
Adding a new domain / category to MuPAD-Combinat
You may want to use the script createDomain at the top level of the MuPAD-Combinat distribution. See the documentation inside the script for details. Basic usage:
createDomain combinat::myCombinatorialClass "the combinatorial class of ..."
Writing tests
A very practical way to create new tests is to use prog::makeTest interactively, and to copy paste the result (after double checking it!) into the test file (say lib/COMBINAT/DOC/words.tst). Example:
>> prog::makeTest(combinat::partitions::count(4), combinat::partitions::list(3)): prog::test(combinat::partitions::count(4), 5): prog::test(combinat::partitions::list(3), [[3], [2, 1], [1, 1, 1]]):
Running the test suite of a particular package (say combinat::words)
cd test make COMBINAT/words.res
Running the test suite under a temporary different version of MuPAD
cd test make check MUPAD=mupad252 MUPAD_VERSION=2.5.2
Learn to use the MuPAD debugger. It is very powerful, quite easy to
debug(theFunctionToDebug(bla, bli))
And then you can go through the function step by step, continue until the next error, check and set variables, etc ... (like in any standard source code debugger like gdb). See ?debug for details.
For a nice graphical interface which shows you the source code while you run through it, I recommend using the debugger inside emacs (see http://mupacs.sf.net), or inside xmupad.
Breakpoints are not very practical to use with the MuPAD command line debugger. However, they can be conveniently emulated with the
f:=proc() begin bla:=1; ble:=2; warning("STOP HERE"); bli:=3; end: debug(f())
Now, just press c, and the execution will continue until the line with the warning is reached.
Learn option hold
twolists := proc(l1, l2) option hold; begin [[context(l1)], [context(l2)]]; end: twolists((1,2,3), 4); // returns [[1,2,3], 4]
Note that almost any access to the parameters in such a procedure requires a call to the function context.
Passing options when using option hold
context(hold(f)(x)) context(hold(a::b)(x))
If the function is not visible, or you need to use dom to name it, better use
context(subsop(hold(f)(x), 0 = dom::something))with any f -- it's just a placeholder anyway.
Where to find documentation on how to write documentation for MuPAD-Combinat
Badly enough, there is no up-to-date documentation on the LaTeX style files for MuPAD documentation. However, our documentation files have a fairly systematic layout and chances are that you can learn everything you need just by browsing through the source of the existing ones. The documentation of combinat::partitions is one of the
You may also browse through the documentation of combinat::permutations which
See also DocumentationTipsAndTricks
Updating the documentation
cd doc make
hash_extra.context = 40000 hash_extra = 300000 pool_size.context = 750000 pool_size = 300000
Compiling just one of the documentation files with just one latex run
cd doc/dvi (or doc/dvia4!) make combinat.mdvi LATEXRUNS=1
Testing the examples in the documentation
cd doc/dvi make check
Testing the examples of a particular documentation file
cd doc/dvi make combinat.res
prog::getOptions
We strongly support the use of prog::getOptions for parsing procedure options. However, this function only appeared (undocumented) in MuPAD 2.5.0, and was changed incompatibly in MuPAD 3.0.0. To ensure compatibility with all versions of MuPAD, it should be called as combinat::getOptions, which is a patched backport of the prog::getOptions of MuPAD 3.0.0.
MuPAD 2.0.0's option remember bug for methods
Try this code with MuPAD 2.0.0:
domain bla x:= proc() option remember; begin print(coucou); end_proc; end_proc: bla::x(); bla::x(); bla::x();
The first time bla::x is called, the result is not inserted in the remember table. This is fixed in MuPAD >= 2.5.0. Standard workaround: force the evaluation of bla::x before calling it:
domain bla x:= proc() option remember; begin print(coucou); end_proc; end_proc: bla::x; bla::x(); bla::x();
MuPAD 2.0.0's prog::check bug
prog::check(proc(typeOfObjects) local rank; begin proc() : typeOfObjects begin end_proc; end_proc, 3)
Type::Boolean:
Beware that Type::Boolean is not defined in MuPAD < 2.5.0. Furthermore, if you just want to test for TRUE/FALSE/UNKNOWN, it's preferable to use DOM_BOOL (Type::Boolean is for boolean expressions in general).
Deleting list entries
Better use delete(l[3]) than l[3]:=null() to delete an element of a list (with MuPAD 2.0.0, the list needs to be evaluated for the element to be actually deleted).
min/max
Beware that min([1,2,3]) returns [1,2,3] with MuPAD <= 2.5 and 1 with MuPAD 3.0.0. So, always use the form min(op([1,2,3])) to get the minimal element of a list.
Since MuPAD 3.0.0 strings are indexed by 1..length(s) to be more coherent with other MuPAD objects (lists, ...); beforehand, they were indexed by 0..length(s)-1. This is a good thing in se, but this means that we need to be careful when writing code for all versions of MuPAD. We already encoutered this problem in several of the MuPAD-Combinat libraries (see e.g. combinat::dyckWords). The standard
%if "12"?1="1" then // work around a change in strings indexed
// access from MuPAD 3.0.0 on
// Code when strings are indexed by 1..length(s)
else
// Code when strings are indexed by 0..length(s)-1
end_if;
Mind the %if: it means that the test is resolved at parse-time. So there is no overhead during execution. Note also that the test does not rely on the MuPAD version, but on the feature itself. This makes it more robust (some old mupad devel versions before the string already had version number 3.0.0, ...).
Compiling dynamic modules on MacOS 9
Note from Christopher: Compiling modules for this MuPAD version requires ?MetroWerks ?CodeWarrior, if I remember correctly. The "Modules" directory of the installation contains a directory "Dynamic Module SDK" in which you should find all that is needed.
Recompiling the dynamic modules for another MuPAD version
rm config.cache rm `\ls src/*/*.mcc | sed 's/\.mcc$/.cc/'` ./configure MUPAD=mupad2.5.1 make
Compiling programs/dynamic modules with another compiler
rm config.cache cd src; make clean ./configure CXX=g++3 make
Using dynamic module functions when time is critical
(Christopher) Using:
f := external("module", "function") f(a, b)
may be faster than
module::function(a, b)
There is still a non-negligible overhead compared to standard function calls in C.