Calmat
a Fortran Equation Parser Involving Matrix Operations
Install / Use
/learn @hassaniriad/CalmatREADME
Calmat: a Fortran Equation Parser Involving Matrix Operations
-
Installation / Compilation
2.1. Compiling the pk2 library and calmat library and executable
2.2. Compiling your program that uses calmat -
Calmat as a stand-alone program
3.1. Interactive mode
3.2. Batch mode
3.3. How to add user functions? -
Calling calmat from a user code
4.1.exprInandfileInarguments
4.2 Thestatargument (error handling)
4.3warning,dispResandwelcomearguments
4.4parseOnlyandevaluatearguments
4.5 Accessing the values of a calmat variable (copy, move allocation and pointer association) -
Examples
7.1. Example of script
7.2. Example of user program
1. What is calmat? <a name="whatis"></a>
Calmat can evaluate an expression or a set of expressions involving operations between matrices, vectors or scalars of any type (integer, real, complex, logical or character string), using a language borrowed from Matlab/Scilab (including two control structures: for loop and if-then-elseif constructs).
Calmat is an application of the pk2 library (polymorphic rank-2 arrays, see here) that lets you define a variable that can represent a matrix of any type and perform almost any kind of operation.
Calmat is a stand-alone program (see §3) as well as a subroutine that can be called from a user program (see §4), for example:
call calmat ( exprIn = "x = sqrt(5)-1 ; y = exp(-x^2)/x" )
call calmat ( exprIn = "inv([1,2,3; 0,5,6; 7,8,9])" )
2. Installation / Compilation <a name="comp"></a>
Clone the calmat project:
git clone https://github.com/hassaniriad/calmat.git
It contains a copy of the pk2 project.
2.1. Compiling the pk2 library and calmat library and executable <a name="complib"></a>
-
Prerequisites: You will need a recent fortran compiler. At present, the compilers I have tested are:
- on macos: gfortran (>= 14), nagfor (>= Build 7213), ifort 2021.7.0
- on linux: gfortran (>= 11.2.1), ifx (>= 2024.1.2)
(please note that several compiler bugs have been corrected, be sure you have the last release).
I haven't tried compiling it on Windows and on macOS ARM, but if you do, I'd be very interested to know.
The makefile in the main calmat directory first runs the makefile of the pk2 library (located in calmat/pk2/src directory) and then the makefile of calmat (located in calmat/src directory). These makefiles are ready to use for ifort, ifx, gfortran and nagfor (you can easily adapt them to another compiler).
To get help just type: make
- Setting the compiler name: For compiling with ifort, gfortran or nagfor use the keyword
comp, e.g.
make comp=gfortran
- Setting options: By default the flag
-O3is used. You can use your own options by using the keywordoptwhose value is a string. For example:
make comp=ifort opt="-fast"
- Setting the kind parameters: By default the kind parameters for integer (
Ikind) and for real/complex (Rkind) are set, respectively, toint32and toreal64(two parameters of theiso_fortran_envmodule).
If you wish to change them use the keywordkindwhich can take the flags:-DI32,-DI64,-DSPor-DDP(forint32,int64,real32,real64, respectively). For example:
make comp=gfortran kind="-DSP -DI32"
If the compilation is successful
- the
pk2library (libpk2.aandlibpk2_d.so) and the module files are located incalmat/pk2/lib/$compandcalmat/pk2/mod/$comp, respectively, where$compis the name of the compiler used. - the
calmatlibrary (libcalmat.aandlibcalmat_d.so) and the module files are located incalmat/lib/$compandcalmat/mod/$comp, respectively. - the
calmatexecutable (calmat.exeandcalmat_d.exe) is located incalmat/bin/$comp
You can move them to a more appropriate directory if you wish or add their paths to your LIBRARY_PATH/DYLD_LIBRARY_PATH environment variable.
2.2. Compiling your program that uses calmat <a name="compprog"></a>
You need to link your program against calmat, pk2, lapackand blas libraries and to add the path name of the module files of calmat and pk2 (-I flag).
- If the static libraries are used, the compilation takes the form:
ifort -L$libcal -lcalmat -L$libpk2 -lpk2 -llapack -lblas -I $modcal -I $modpk2 -o foo foo.f90
where$libcal, $libpk2, $modcal and $modpk2 are the paths of the calmat and pk2 libraries and module files.
It may be shortened to:
ifort -lcalmat -lpk2 -llapack -lblas -o foo foo.f90
by setting the environment variable LIBRARY_PATH:
export LIBRARY_PATH=/Users/me/calmat/pk2/lib/ifort:/Users/me/calmat/lib/ifort:$LIBRARY_PATH
and CPATH for module files (unfortunately, only ifort supports this):
export CPATH=/Users/me/calmat/pk2/mod/ifort:/Users/me/calmat/mod/ifort
- If the shared libraries are used, the compilation takes the form:
gfortran -lcalmat_d -lpk2_d -llapack -lblas -I $modcal -I $modpk2 -o foo foo.f90
provided that the environment variable DYLD_LIBRARY_PATH has also been set to:
export DYLD_LIBRARY_PATH =/Users/me/calmat/pk2/lib/gfortran:/Users/me/calmat/lib/gfortran:$DYLD_LIBRARY_PATH
3. Calmat as a stand-alone program <a name="calmat1"></a>
Calmat can be executed in a window command, in interactive mode or in batch mode. To see the command line options type
$ calmat -h
3.1. Interactive mode <a name="calmat1a"></a>
Note: If you have rlwrap installed (https://github.com/hanslub42/rlwrap), you can use it to benefit from the left/right/up/down keys to recall a command (history) or to modify one, by launching:
$ rlwrap calmat
or better (use an alias for convenience):
$ rlwrap -c -w 0 calmat
(-c allows file name completion).
Once calmat is running a prompt is displayed and it waits for an input. Enter your statements as in Matlab:
<p align="left"> <img src="./media/demo0.png" width="550"> </p> <p align="left"> <img src="./media/demo1.png" width="550"> </p> <p align="left"> <img src="./media/demo3.png" width="550"> </p> <p align="left"> <img src="./media/demo4.png" width="550"> </p> <p align="left"> <img src="./media/inv1.png" width="550"> </p>-
Available functions, operators and commands: to list them type, respectively,
<p align="left"> <img src="./media/list_of_builtin_func1.png" width="550"> <img src="./media/list_of_builtin_func2.png" width="550"> <img src="./media/list_of_builtin_func3.png" width="550"> </p> <p align="left"> <img src="./media/list_of_operators.png" width="550"> </p> <p align="left"> <img src="./media/list_of_commands.png" width="550"> </p>list fun,list opandlist cmd:(see also the help of
list) -
Help: to get the help of a given command, a given function or a given operator use the command
<p align="left"> <img src="./media/help.png" width="550"> </p>help, for example: -
Comments: as in scilab, the symbol
//is used for comment. -
Strings: simple quotes or double quotes can be used for character strings.
-
List of variables (workspace): to list all your variables just type
<p align="left"> <img src="./media/list.png" width="550"> </p>list: -
Protected variables: I have adopted the scilab convention for a predefined (and protected) variable: its name starts with a
%(like%pi,%i,%eps, ...). You can define your own protected variable by using the commandset(see the help ofset). -
Deleting variables: the variables (except the protected ones) can be deleted by the command
clear(delete all variables). To delete a given set of variables, sayAandB, use the commandclear A B(without commas between variables). -
Executing a script: you can write your calmat program in a text file and execute it by using the calmat command
<p align="left"> <img src="./media/exec.png" width="550"> </p>exec(as in scilab), for examplewill execute the set of calmat instructions present in the file "laplacian2d".
Remark: when the
<p align="left"> <img src="./media/error0.png" width="550"> </p>execcommand is used or when an expression contains several statements (separated by commas or semicolons) the entire "stream" of statements is first parsed before any evaluation. If an error is detected during this parsing phase no evaluation will be performed even for statements preceding this error. Example:The behaviour is obviously different when a runtime error occurs:
<p align="left"> <img src="./media/error1.png" width="550"> </p> -
Control structures: there are only two control structures:
<p align="left"> <img src="./media/forNif.png" width="550"> </p>ifandforconstructs. A notable difference with Matlab/Scilab is that these blocks construct end with the keywordsendif(orend if) andendfor(orend for), respectively. I find that it enhances the readability of a program. Moreover, the keywordthenis always required in anifstatement or anif-elseif-elseconstruct (non-existent with Matlab and optional with scilab). Example:(note that, as a reminder, calmat adapts its prompt by putting in
