Artifact c5cc8a3a5244f3176e8550d93f631afb9ec45b4073b1850619aff9b9eda981e2:
- Executable file
mttroot/mtt/bin/trans/mtt_header
— part of check-in
[d9e3b30dc2]
at
2002-05-15 14:22:26
on branch origin/master
— Code for Simulink S-function target written direct to sfun.cc instead of
calling .mexglx files. This eliminates the sfun dependency on Octave
ColumnVectors. sys_sfun.cc should build directly on a MS Windows machine
(can't test this yet).added sfun.zip target to create source code to export. (user: geraint@users.sourceforge.net, size: 20771) [annotate] [blame] [check-ins using] [more...]
#!/bin/sh ###################################### ##### Model Transformation Tools ##### ###################################### # Bourne shell script: mtt_header # Headings for functions # Copyright (C) 2000 by Peter J. Gawthrop ############################################################### ## Version control history ############################################################### ## $Id$ ## $Log$ ## Revision 1.49 2002/05/11 01:14:17 geraint ## Fix for [ 553218 ] simpar.oct and simpar.m different. ## Translation added between ColumnVector in base .cc and Octave_map in .oct. ## ## Revision 1.48 2002/05/08 14:51:03 geraint ## Moved matlab/octave data type conversion functions to a separate file. ## ## Revision 1.47 2002/05/07 23:50:34 geraint ## Preliminary support for Matlab dynamically linked shared objects: ## invoke with: mtt -cc sys rep mexglx ## ode2odes support is not yet included. ## ## Revision 1.46 2002/05/07 13:48:43 geraint ## Improved clarity of code generated for -cc and -oct (except ode2odes). ## Octave DEFUN_DLDs now call (rather than replace) their .cc equivalents. ## ## Revision 1.45 2002/05/02 09:30:22 gawthrop ## _ssim.m now returns t as 4th arg ## ## Revision 1.44 2002/05/01 17:30:56 geraint ## Improved pre-processor directives to better accommodate future alternatives (matlab) ## if necessary. ## ## Revision 1.43 2002/04/30 23:27:00 geraint ## Replaced octave_map with columnvector in simpar.cc. Not quite as descriptive but ## standardises the interfaces somewhat and reduces the dependency on liboctinterp ## (and thus libreadline, libkpathsea, libncurses, etc). ## ## Revision 1.42 2002/04/28 18:41:27 geraint ## Fixed [ 549658 ] awk should be gawk. ## Replaced calls to awk with call to gawk. ## ## Revision 1.41 2002/04/23 17:46:05 gawthrop ## _sim.m now returns time as third argument ## ## Revision 1.40 2002/04/17 16:23:59 geraint ## Partial fix for [ 545113 ] zeros missing in c++. ## Fixes -oct by removing duplicate initialisation (-c is still outstanding). ## ## Revision 1.39 2002/04/15 10:54:31 geraint ## Statically declare outputs and initialise to zero. ## This is necessary to prevent spurious values from being output when no assignments are made (i.e. when "y(i) := 0 for all u" (Reduce:see NERO)). ## ## Revision 1.38 2001/07/23 23:43:15 gawthrop ## header only version does not need to compute sizes from _def.r ## ## Revision 1.37 2001/07/13 04:54:04 geraint ## Branch merge: numerical-algebraic-solution back to main. ## ## Revision 1.36 2001/07/12 04:00:51 gawthrop ## Now zeros y correctly - ie Ny NOT Nx elements ## ## Revision 1.35 2001/06/13 10:39:51 gawthrop ## Zeros output matices in csex and cseo just in case some elements are ## actually zero and not set in code. Works for m and oct. ## ## Revision 1.34 2001/05/26 18:36:43 gawthrop ## Further modifications. Now works on rcPPP ## -- next jobs: ## add identification to ppp_nlin_sim ## create real-time ppp_nlin_run ## ## Revision 1.33 2001/05/26 15:46:38 gawthrop ## Updated to account for new nonlinear ppp ## ## Revision 1.32 2001/05/24 07:42:12 gawthrop ## Included and updated the missing tf_r2m ## ## Revision 1.31.2.2 2001/07/02 00:34:56 geraint ## gcc-3.0 compatibility. ## ## Revision 1.31.2.1 2001/05/04 04:07:24 geraint ## Numerical solution of algebraic equations. ## sys_ae.cc written for unsolved inputs. ## Solution of equations using hybrd from MINPACK (as used by Octave fsolve). ## ## Revision 1.31 2001/04/03 14:49:42 gawthrop ## Revised to incorporate new ssim (sensitivity simulation) ## representation (m only just now). ## ## Revision 1.30 2001/03/30 15:13:58 gawthrop ## Rationalised simulation modes to each return mtt_data ## ## Revision 1.29 2001/03/27 13:10:23 geraint ## Improved determination of Octave version. ## ## Revision 1.28 2001/02/17 03:48:17 geraint ## Use assignment LHS to gather tmp variable names. ## Prevents collection of long expressions, eg: tmp34*(tmp75 ## ## Revision 1.27 2001/02/14 06:06:34 geraint ## Removed octave_value_list wrappers from standalone.exe - speed improvements ## ## Revision 1.26 2001/02/05 08:50:58 geraint ## Octave 2.1.x compatability. ## ## Revision 1.28 2001/01/17 21:16:15 geraint ## uncomment parameter assignments in .m reps ## ## Revision 1.27 2001/01/14 23:51:26 geraint ## declare parameters as variables instead of constants ## ## Revision 1.26 2001/01/07 21:22:47 geraint ## Compatibility with Octave 2.1.x ## vector_value ---> column_vector_value ## ## Revision 1.25 2000/12/05 12:05:26 peterg ## Changed to () form ## ## Revision 1.24 2000/12/05 10:04:52 peterg ## Fixed dummy variable bug ## ## Revision 1.23 2000/12/05 09:47:50 peterg ## Include crs as c files ## ## Revision 1.22 2000/12/04 12:19:12 peterg ## Changed $() to `` and $() to expr for sh compatibility -- geraint ## ## Revision 1.21 2000/12/04 08:52:40 peterg ## Zapped () in functions for sh compatibility ## ## Revision 1.20 2000/12/04 08:19:27 peterg ## Added switch declarations - in logic.cc ## ## Revision 1.19 2000/12/03 16:11:43 peterg ## Corrected bug in logic declatations ## ## Revision 1.18 2000/12/03 16:06:22 peterg ## Fixed bug in generating dummies ## Added logic declarations ## ## Revision 1.17 2000/12/01 20:55:01 peterg ## Added Geraint's fix for zeroing matrices ## ## Revision 1.16 2000/12/01 17:56:30 peterg ## Removed spurious echo '## Set matrices to zero' - thanks Geraint ## ## Revision 1.15 2000/11/29 21:06:16 peterg ## Removed Npar creation - not needed?? ## ## Revision 1.14 2000/11/27 11:51:43 peterg ## Added zero matrices in matlab code ## ## Revision 1.13 2000/11/09 17:19:52 peterg ## Geraint's pow() mods ## ## Revision 1.12 2000/11/09 16:09:46 peterg ## Declare dummy variables (mtt_s1 etc) ## ## Revision 1.11 2000/11/09 15:29:35 peterg ## lower-case declarations ## ## Revision 1.10 2000/11/07 17:20:51 peterg ## useful-functions.hh now included locally ## ## Revision 1.9 2000/11/07 16:56:24 peterg ## Version from Geraint ## ## Revision 1.2 2000/11/03 00:55:42 geraint ## typo: missed out 'd' in mttedx ## todo: need to accommodate mttsimpar ## ## Revision 1.1 2000/11/02 04:28:39 geraint ## Initial revision ## ## Revision 1.8 2000/10/17 16:35:03 peterg ## No parameter,state or input conversion in txt files ## ## Revision 1.7 2000/10/17 09:53:20 peterg ## Fixed logic rep ## ## Revision 1.6 2000/10/17 08:37:23 peterg ## Included logic rep ## ## Revision 1.5 2000/10/14 09:12:14 peterg ## No dies arguments and output itself ## ## Revision 1.4 2000/10/14 06:49:31 peterg ## Make parameter listing representation dependent ## ## Revision 1.3 2000/10/11 08:59:15 peterg ## Added csex rep ## ## Revision 1.2 2000/10/11 08:01:42 peterg ## Added noglobal fudge ## ## Revision 1.1 2000/10/10 21:02:27 peterg ## Initial revision ## ############################################################### # Arguments system=$1 rep=$2 language=$3 fun_name=${1}_${2} other=$4 # Anything else eg stdin if [ -z "$system" ]; then echo 'Usage: mtt_header sys rep lang [stdin]' exit fi # get octave version octave_development=`octave --version | gawk '{print $4}' | gawk -F\. '{print $2}'` case `$MATRIX --version | gawk -F\. '{print $2}'` in 0) # stable vector_value=vector_value ;; 1) # development vector_value=column_vector_value ;; *) vector_value=column_vector_value ;; esac # Representation-specific stuff eqnargs='mttx,mttu,mttt,mttpar' inputeqnargs='mttx,mtty,mttt,mttpar' case $rep in ae) states=yes; inputs=yes; parameters=yes; output=mttyz; args=$eqnargs; ;; cse) states=yes; inputs=yes; parameters=yes; output='mttdx,mtte' args=$eqnargs ;; csex) states=yes; inputs=yes; parameters=yes; output=mttedx args=$eqnargs zeromatrices='edx'; ;; cseo) states=yes; inputs=yes; parameters=yes; output=mtty args=$eqnargs zeromatrices='y'; ;; dm) states=no; inputs=no; parameters=yes; output='mtta,mttb,mttc,mttd,mtte' args=mttpar zeromatrices='a b c d e'; ;; input) inputs=no; output=mttu args=$inputeqnargs if [ "$other" = "stdin" ]; then states=no; parameters=no; declareinputs=no; else states=yes; parameters=yes; declareinputs=yes declarestates=yes fi ;; logic) states=no; inputs=no; parameters=yes; output=mttopen args=$eqnargs declareinputs=yes declarestates=yes declareswitches=yes ;; numpar) states=no; inputs=no; parameters=no; output='mttpar' ;; ode) states=yes; inputs=yes; parameters=yes; output='mttdx' args=$eqnargs ;; odeo) states=yes; inputs=yes; parameters=yes; output='mtty' args=$eqnargs ;; ode2odes) states=no; inputs=no; parameters=no; output='mtt_data' args='x0,par,simpar' ;; simpar) states=no; inputs=no; parameters=no; output='mttsimpar' oct_rep_include="#include <mtt_simpar.hh>" oct_return_type="mtt_simpar" ;; sm) states=no; inputs=no; parameters=yes; output='mtta,mttb,mttc,mttd' args=mttpar; zeromatrices='a b c d'; ;; smxa) states=no; inputs=no; parameters=yes; output='mtta' args=$eqnargs ;; smxax) states=no; inputs=no; parameters=yes; output='mttax' args=$eqnargs ;; state) states=no; inputs=no; parameters=yes; output=mttx args=mttpar declarestates=yes ;; sim) states=no; inputs=no; parameters=no; output='y,x,t' args='x0,par,simpar,u' ;; ssim) states=no; inputs=no; parameters=no; output='y,y_par,x,t' args='x0,par,simpar,u,index' ;; tf) states=no; inputs=no; parameters=yes; output='mttnum,mttden' args=mttpar; ;; type) states=no; inputs=no; parameters=no; header_only=yes; ;; *) echo Representation $rep not supported - sorry; exit 1 esac ## Sort out parentheses if [ -n "$args" ]; then Args='('$args')' fi if [ -n "$output" ]; then Output="[$output] = " fi # Lanuage specific stuff case $language in m) Lc='##'; Rc=''; Lb='('; Rb=')'; function="function" declaration="$Output$1_$rep$Args;" if [ "$other" != "stdin" ]; then noglobals=true; # Fudge to make mtt_m2p work fi start='## BEGIN Code' finish='## END Code' var_declaration= declarestates=no declareinputs=no declareswitches=no ;; sh) modeline='## -*-shell-script-*- Put Emacs into shell-script-mode ##'; Lc='##'; Rc=''; Lb='('; Rb=')'; function="" declaration="" start='' parameters=no states=no inputs=no declarestates=no declareinputs=no declareswitches=no ;; txt) modeline='## -*-octave-*- Put Emacs into octave-mode ##'; Lc='##'; Rc=''; Lb='('; Rb=')'; function="" declaration="" start='' parameters=no states=no inputs=no declarestates=no declareinputs=no declareswitches=no ;; oct) modeline="// -*-c++-*- Put Emacs into c++-mode"; Lc='//'; Lb='('; Rb=')'; oct_header=yes; constant_declaration="const double " var_declaration="double " minusone="-1" map="_map" declaredummies=yes ;; sfun) modeline="// -*-c++-*- Put Emacs into c++-mode"; Lc='//' Rc='' Lb='[' Rb=']' start="## BEGIN Code" finish="## END Code" constant_declaration="const double " var_declaration="double " minusone="-1" ;; *) echo Language $language not supported - sorry; exit 1 esac if [ "$rep" = "simpar" ]; then output=${output}${map} # Output is simpar_map in this case fi get_sizes() { Nx=`mtt_getsize $system x` # States Nxx=`mtt_getsize $system xx` # States x States Nu=`mtt_getsize $system u` # Inputs Ny=`mtt_getsize $system y` # Outputs Nyz=`mtt_getsize $system yz` # Zero outputs ##Npar=`wc -l $system\_sympar.txt | gawk '{print $1}'` } zero_matrices() { ## Set matrices to zero echo ## echo '## Set matrices to zero' for name in $zeromatrices; do case $name in a) N=$Nx; M=$Nx ;; b) N=$Nx; M=$Nu ;; c) N=$Ny; M=$Nx ;; d) N=$Ny; M=$Nu ;; e) N=$Nx; M=$Nx ;; edx) N=$Nx; M=1 ;; y) N=$Ny; M=1 ;; *) esac if [ "${language}" = "oct" ]; then if [ "$M" = "1" ]; then echo " mtt$name = zeros($N);" else echo " mtt$name = zeros($N,$M);" fi else echo " mtt$name = zeros($N,$M);" fi done } declare_dummies() { # Get the dummies dummies="mtt_tmp" rm -f mtt_dummies for dummy in $dummies; do grep "${dummy}[0-9]*[ \t\n]*=" < ${fun_name}.m |\ gawk '{ if (match($1,dummy)==1) print $1 }' dummy=$dummy >> mtt_dummies done dummy_list=`sort -u mtt_dummies` # Comments cat <<EOF $Lc Declarations of dummies $Rc EOF for dummy in $dummy_list; do echo ' ' $var_declaration $dummy';' done } # declare_dummies declare_switches () { cat <<EOF $Lc Declarations of switches $Rc EOF strip_comments <${system}_switch.txt |\ gawk '{printf(" double %s_logic = 0;\n", tolower($1))}' } # declare_switches declare_vars() { # Grab the names names=`gawk '{if ($1==var_type) print tolower($4)}' var_type=$1 ${system}_struc.txt` # Comments cat <<EOF $Lc Declarations for $1 names $Rc EOF # Declarations for name in $names; do echo ' '$var_declaration $name';' done } array2constant() { # Parameters if [ "$parameters" = "yes" ]; then cat <<EOF $Lc Parameters $Rc EOF sympar2par_txt2m ${system} "" "$var_declaration" "$minusone" "$Lb" "$Rb" fi # States if [ "$states" = "yes" ]; then cat <<EOF $Lc States $Rc EOF N=`n2m 1 $Nx` for i in $N; do echo $constant_declaration 'mttx'$i' = mttx'$Lb$i$minusone$Rb ';' done fi if [ "$declarestates" = "yes" ]; then declare_vars state fi # Inputs if [ "$inputs" = "yes" ]; then cat <<EOF $Lc Inputs $Rc EOF N=`n2m 1 $Nu` for i in $N; do echo $constant_declaration 'mttu'$i' = mttu'$Lb$i$minusone$Rb';' done cat <<EOF $Lc Unknown Inputs $Rc EOF Ni=`n2m 1 $Nyz` for i in $Ni; do echo $constant_declaration 'mttui'$i' = mttu'$Lb$Nu+$i$minusone$Rb';' done fi if [ "$declareinputs" = "yes" ]; then declare_vars input fi if [ "$declaredummies" = "yes" ]; then declare_dummies fi if [ "$declareswitches" = "yes" ]; then declare_switches fi zero_matrices; } # Argument specific stuff get_arg_specific_stuff () { arg_name=${1:-""} case ${arg_name} in mtta | mtte) arg_type="Matrix" arg_init="(MTTNX,MTTNX,0.0)" ;; mttb) arg_type="Matrix" arg_init="(MTTNX,MTTNU,0.0)" ;; mttc) arg_type="Matrix" arg_init="(MTTNY,MTTNX,0.0)" ;; mttd) arg_type="Matrix" arg_init="(MTTNY,MTTNU,0.0)" ;; mttax | mttdx | mttedx | mttx | mttopen) arg_type="ColumnVector" arg_init="(MTTNX,0.0)" ;; mttpar) arg_type="ColumnVector" arg_init="(MTTNPAR,0.0)" ;; mttsimpar_map) arg_type="ColumnVector" arg_init="(8,0.0)"; ;; mttu) arg_type="ColumnVector" arg_init="(MTTNU,0.0)" ;; mttyz) arg_type="ColumnVector" arg_init="(MTTNYZ,0.0)" ;; mtty) arg_type="ColumnVector" arg_init="(MTTNY,0.0)" ;; mttt) arg_type="const double" arg_init="" ;; nil) arg_type="void *" arg_init="(0x0)" ;; *) echo "Argument ${arg} not supported - sorry"; exit 1 esac } get_field () { # parse comma separated string s=${1:-""} # comma separated string i=${2:-0} # field number in string if [ 0 -eq ${i} ]; then # return number of fields echo ${s} |\ gawk -F\, '{ print NF }' else # return ith field echo ${s} |\ gawk -F\, -v i=${i} '{ print $i }' fi } get_extra_fields () { # return list of words in s2 and not in s1 s1=${1:-""} # comma separated list s2=${2:-""} # comma separated list c1=`get_field ${s1} 0` # count words in s1 c2=`get_field ${s2} 0` # count words in s2 ans="" i2=0 # s2 word index while [ ${i2} -lt ${c2} ]; do flag=0 # appearance of word in s1 and s2? i2=`expr ${i2} + 1` w2=`get_field ${s2} ${i2}` # i2 th word in s2 i1=0 # s1 word index while [ ${i1} -lt ${c1} ]; do i1=`expr ${i1} + 1` w1=`get_field ${s1} ${i1}` # i1 th word in s1 if [ ${w2} = ${w1} ]; then flag=1 # w2 occurs in s1 fi done if [ ${flag} -eq 0 ]; then # w2 is not in s1? if [ -z ${ans:-""} ]; then # string is empty? ans=${w2} # assign w2 else ans=${ans},${w2} # append w2 fi fi done echo ${ans} } write_cc_header () { get_arg_specific_stuff ${output} cat <<EOF #include <octave/oct.h> #include "useful-functions.hh" #include "${system}_cr.h" #include "${system}_def.h" #include "${system}_sympar.h" // Code generation directives #define STANDALONE 0 #define OCTAVEDLD 1 #define MATLABMEX 2 #ifndef CODEGENTARGET #define CODEGENTARGET STANDALONE #endif // CODEGENTARGET ${arg_type} ${system}_${rep} ( EOF if [ -z ${args:-""} ]; then printf "\tvoid" else c=`get_field ${args:-""} 0` i=0 while [ ${i} -lt ${c} ]; do i=`expr ${i} + 1` if [ ${i} -lt ${c} ]; then comma="," else comma="" fi w=`get_field ${args} ${i}` get_arg_specific_stuff ${w} printf "\t${arg_type}\t&${w}${comma}\n" done fi get_arg_specific_stuff ${output} cat <<EOF ) { static ${arg_type} ${output} ${arg_init}; EOF } write_cc_footer () { cat <<EOF // BEGIN Code // END Code return ${output}; } EOF } map_oct_inputs () { s=${1:-""} # comma separated input list if [ -z ${s:-""} ];then return; fi c=`get_field ${s} 0` # count of inputs i=0 printf " if (${c} != args.length ()) usage (\"${fun_name} expected ${c} argument(s): ${s}\");\n\n" while [ ${i} -lt ${c} ]; do j=${i} i=`expr ${i} + 1` w=`get_field ${s} ${i}` # argument name get_arg_specific_stuff ${w} case ${arg_type} in "const double") printf " ${arg_type}\t${w}\t= args(${j}).double_value ();\n" ;; ColumnVector | Matrix | *) printf " ${arg_type}\t${w}\t= args(${j}).%s ();\n" ${vector_value} ;; esac done } map_mex_inputs () { s=${1:-""} # comma separated input list if [ -z ${s:-""} ];then return; fi c=`get_field ${s} 0` # count of inputs i=0 cat <<EOF if (${c} != nrhs) { std::cerr << "${fun_name} expected " << ${c} << " argument(s): ${s}" << std::endl; return; } EOF while [ ${i} -lt ${c} ]; do j=${i} i=`expr ${i} + 1` w=`get_field ${s} ${i}` # argument name get_arg_specific_stuff ${w} case ${arg_type} in "const double") printf " ${arg_type}\t${w}\t= mtt_double (prhs [${j}]);\n" ;; ColumnVector | Matrix | *) printf " ${arg_type}\t${w}\t= mtt_${arg_type} (prhs [${j}]);\n" ;; esac done } write_oct() { func=${1:-"<insert function name>"} args=${2:-""} cat <<EOF #if (CODEGENTARGET == OCTAVEDLD) $oct_rep_include DEFUN_DLD (${system}_${rep}, args, , "Usage: [$output] = ${system}_${rep}($args)\nOctave ${rep} representation of system ${system}\nGenerated by MTT on `date`") { static octave_value_list retval; EOF map_oct_inputs ${args} cat <<EOF retval (0) = octave_value ($oct_return_type (${func} (${args}))); return retval; } #endif // (CODEGENTARGET == OCTAVEDLD) EOF } write_mex () { func=${1:-"<insert function name>"} args=${2:-""} cat <<EOF #if (CODEGENTARGET == MATLABMEX) #include <mtt_matlab_octave.hh> extern "C" { void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { EOF map_mex_inputs ${args} cat <<EOF plhs[0] = mtt_mxArray (${func} (${args})); } } #endif EOF } # Header information cat<<EOF $modeline $function $declaration $Lc $declaration $Lc System $system, representation $rep, language $language; $Rc $Lc File $1_$rep.$language; $Rc $Lc Generated by MTT on `date`; $Rc EOF if [ -n "${header_only}" ]; then exit else get_sizes; fi if [ ${language} = "oct" ];then # standalone write_cc_header array2constant write_cc_footer # oct and mex code write_oct ${system}_${rep} ${args} write_mex ${system}_${rep} ${args} else if [ -n "$noglobals" ]; then cat<<EOF ## Horrible fudge to make mtt_m2p work global ... mtt_no_globals ; EOF fi ## Arrays array2constant # Mark start of code echo echo $start fi