Overview
Comment:Numerical solution of algebraic equations implemented for S-function target.

Equation solving requires the Matlab Optimization Toolbox to be installed.

Code has been changed from C++ to C to allow mex files to be built with LCC,
the compiler bundled with Matlab.

Parameters are now obtained from numpar.c instead of a dialogue box.

`mtt <sys> sfun zip` creates all necessary files for building the model mex files.

Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | origin/master | trunk
Files: files | file ages | folders
SHA3-256: 062029b187822b39851e505d09f272f96134572e888bb0a690899a8f846ed0fa
User & Date: geraint@users.sourceforge.net on 2002-05-19 13:01:22.000
Other Links: branch diff | manifest | tags
Context
2002-05-20
07:12:05
Trying to get oct files generated with -oct check-in: 039197b659 user: gawthrop@users.sourceforge.net tags: origin/master, trunk
2002-05-19
13:01:22
Numerical solution of algebraic equations implemented for S-function target.

Equation solving requires the Matlab Optimization Toolbox to be installed.

Code has been changed from C++ to C to allow mex files to be built with LCC,
the compiler bundled with Matlab.

Parameters are now obtained from numpar.c instead of a dialogue box.

`mtt <sys> sfun zip` creates all necessary files for building the model mex files. check-in: 062029b187 user: geraint@users.sourceforge.net tags: origin/master, trunk

2002-05-17
11:17:35
No longer uses df() if corresponding sensitivity parameter is 0. check-in: a29cbd4fd9 user: gawthrop@users.sourceforge.net tags: origin/master, trunk
Changes
8
9
10
11
12
13
14








15
16
17
18
19
20
21
# 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.
##







>
>
>
>
>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Copyright (C) 2000 by Peter J. Gawthrop

###############################################################
## Version control history
###############################################################
## $Id$
## $Log$
## Revision 1.50  2002/05/15 14:22:25  geraint
## 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.
##
## 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.
##
206
207
208
209
210
211
212



213
214
215
216
217
218
219
# 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









>
>
>







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# Arguments
system=$1
rep=$2
language=$3
fun_name=${1}_${2}

other=$4 # Anything else eg stdin

insertor=\<\<			# help emacs sh-mode out with C++ lines


if [ -z "$system" ]; then
  echo 'Usage: mtt_header sys rep lang [stdin]'
  exit
fi


465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480
481
482
483
484
485
486
	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







<
>
|
|
|


<
<







476
477
478
479
480
481
482

483
484
485
486
487
488


489
490
491
492
493
494
495
	oct_header=yes;
        constant_declaration="const double "
        var_declaration="double "
	minusone="-1"
	map="_map"
        declaredummies=yes
	;;

    c)
	modeline="/* -*-c-*- Put Emacs into c-mode */";
	Lc='/*'
	Rc='*/'
	Lb='['
	Rb=']'


	constant_declaration="const double "
	var_declaration="double "
	minusone="-1"
	;;
    *)
	echo Language $language not supported - sorry; exit 1
esac
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
	    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"







|








|






|







858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
	    ColumnVector | Matrix | *)
		printf "  ${arg_type}\t${w}\t= args(${j}).%s ();\n" ${vector_value}
		;;
	esac
    done
}	

map_mex_cc_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 $insertor "${fun_name} expected " $insertor ${c} $insertor " argument(s): ${s}" $insertor 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"
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
  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







|













|







913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
  return retval;
}
#endif // (CODEGENTARGET == OCTAVEDLD)

EOF
}

write_mex_cc ()
{
    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_cc_inputs ${args}
cat <<EOF
  plhs[0] = mtt_mxArray (${func} (${args}));
  }
}
#endif

EOF
951
952
953
954
955
956
957
958






959
960
961
962
963
964
965
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 ...







|
>
>
>
>
>
>







960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
if [ ${language} = "oct" ];then
# standalone
    write_cc_header
    array2constant
    write_cc_footer
# oct and mex code
    write_oct ${system}_${rep} ${args}
    write_mex_cc ${system}_${rep} ${args}
elif [ $language = "c" ]; then
    array2constant
    cat <<EOF
/* BEGIN Code */
/* END Code */
EOF
else

if [ -n "$noglobals" ]; then
cat<<EOF

## Horrible fudge to make mtt_m2p work
global ...
96
97
98
99
100
101
102


103
104




105
106

107
108
109
110
111
112
113
	cat
	;;
esac
};

fix_comment_delimiter ()
{


    # it would be preferable if we didn't use '%' as a delimiter
    # (a % b) gives the remainder of ((int)a / (int)b) in C/C++




    sed 's/[%#]/\/\//g' | sed 's/\/\/\/\//\/\//g'
    

};

decrement_indices ()
{    
    # first section appends '-1' to container indices
    # to convert from FORTRAN-type numbering to C-type numbering
    sed 's/mtta(\([0-9][0-9]*\),\([0-9][0-9]*\))/mtta[\1-1,\2-1]/g'	|\







>
>


>
>
>
>
|
|
>







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
	cat
	;;
esac
};

fix_comment_delimiter ()
{
    language=${1:-cc}
    case $language in
    # it would be preferable if we didn't use '%' as a delimiter
    # (a % b) gives the remainder of ((int)a / (int)b) in C/C++
	c)
	    sed 's/[%#]\(.*\)/\/* \1 *\//'
	    ;;
	cc | *)
	    sed 's/[%#]/\/\//g' | sed 's/\/\/\/\//\/\//g'
	    ;;
    esac
};

decrement_indices ()
{    
    # first section appends '-1' to container indices
    # to convert from FORTRAN-type numbering to C-type numbering
    sed 's/mtta(\([0-9][0-9]*\),\([0-9][0-9]*\))/mtta[\1-1,\2-1]/g'	|\
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
    sed 's/\([0-9]*\)\(\.\)\{0,1\}\([0-9]*\)\^\([0-9]*\)\(\.\)\{0,1\}\([0-9]*\)/pow \(\1\2\3,\4\5\6\)/g'
};


echo Creating ${OUT}

case ${TARGET} in
    sfun)

	mtt_header ${SYS} ${REP} "sfun"	>  ${TMP}
	echo "## END Code"		>> ${TMP}
	find_code ${TMP} head		>  ${OUT}
	find_code ${IN} body		|\
	    decrement_indices		|\
	    fix_comment_delimiter	|\
	    fix_pow			|\
	    strip_junk			|\
	    ${PARSER}			>> ${OUT}
	find_code ${TMP} foot		>> ${OUT}
	rm ${TMP}
	;;
    cc | *)
	mtt_header ${SYS} ${REP} "oct"	>  ${TMP}
	find_code ${TMP} head		>  ${OUT}
	rep_declarations		>> ${OUT}
	find_code ${IN} body   		|\
	    decrement_indices		|\
	    fortran_to_c_paren		|\
	    fix_comment_delimiter	|\
	    fix_pow			|\
	    strip_junk			|\
	    ${PARSER}			>> ${OUT}
	rep_footer			>> ${OUT}
	find_code ${TMP} foot		>> ${OUT}
	rm ${TMP}
	;;
esac









<
>
|
<



|













|










175
176
177
178
179
180
181

182
183

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
    sed 's/\([0-9]*\)\(\.\)\{0,1\}\([0-9]*\)\^\([0-9]*\)\(\.\)\{0,1\}\([0-9]*\)/pow \(\1\2\3,\4\5\6\)/g'
};


echo Creating ${OUT}

case ${TARGET} in

    c)
	mtt_header ${SYS} ${REP} "c"	>  ${TMP}

	find_code ${TMP} head		>  ${OUT}
	find_code ${IN} body		|\
	    decrement_indices		|\
	    fix_comment_delimiter c	|\
	    fix_pow			|\
	    strip_junk			|\
	    ${PARSER}			>> ${OUT}
	find_code ${TMP} foot		>> ${OUT}
	rm ${TMP}
	;;
    cc | *)
	mtt_header ${SYS} ${REP} "oct"	>  ${TMP}
	find_code ${TMP} head		>  ${OUT}
	rep_declarations		>> ${OUT}
	find_code ${IN} body   		|\
	    decrement_indices		|\
	    fortran_to_c_paren		|\
	    fix_comment_delimiter cc	|\
	    fix_pow			|\
	    strip_junk			|\
	    ${PARSER}			>> ${OUT}
	rep_footer			>> ${OUT}
	find_code ${TMP} foot		>> ${OUT}
	rm ${TMP}
	;;
esac


1
2
3




4
5
6
7
8
9
10
#! /bin/sh
# $Id$
# $Log$




# Revision 1.4  2001/08/24 21:41:04  geraint
# Fixed problem with declaration when there are no numerical parameters.
#
# Revision 1.3  2001/03/19 02:28:53  geraint
# Branch merge: merging-ode2odes-exe back to MAIN.
#
# Revision 1.2.2.1  2001/03/16 03:56:54  geraint



>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
#! /bin/sh
# $Id$
# $Log$
# Revision 1.5  2002/04/28 18:58:06  geraint
# Fixed [ 549658 ] awk should be gawk.
# Replaced calls to awk with call to gawk.
#
# Revision 1.4  2001/08/24 21:41:04  geraint
# Fixed problem with declaration when there are no numerical parameters.
#
# Revision 1.3  2001/03/19 02:28:53  geraint
# Branch merge: merging-ode2odes-exe back to MAIN.
#
# Revision 1.2.2.1  2001/03/16 03:56:54  geraint
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
TMP_VAR_NAMES="mtt_tmp mtt_o $*"

IN=${SYS}_sympar.txt
OUT=${SYS}_sympar.h

declare_sys_param ()
{
cat ${IN} | gawk '(NF>0){printf ("static double %s MTT_UNUSED;\t// %s\n", tolower($1), $2)}'
}

declare_temp_vars ()
{
for name in ${TMP_VAR_NAMES}
do
    echo ""







|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
TMP_VAR_NAMES="mtt_tmp mtt_o $*"

IN=${SYS}_sympar.txt
OUT=${SYS}_sympar.h

declare_sys_param ()
{
cat ${IN} | gawk '(NF>0){printf ("static double %s MTT_UNUSED;\t/* %s\t*/\n", tolower($1), $2)}'
}

declare_temp_vars ()
{
for name in ${TMP_VAR_NAMES}
do
    echo ""
1
2
3
4


5

6
7





8
9
10

11
12
13

14
15




16





17
18
19

20
21
22

23
24
25

26
27
28
29
#! /usr/bin/make -f

SRC = $(SYS)_sfun.cc $(SYS)_def.h $(SYS)_ae.sfun $(SYS)_ode.sfun $(SYS)_odeo.sfun $(SYS)_state.sfun



all: $(SYS)_sfun.mexglx


$(SYS)_sfun.mexglx: $(SRC)





	mex $(SYS)_sfun.cc

$(SYS)_sfun.cc:: ${MTT_REP}/sfun_rep/sfun.cc.tmpl

	cat $^ | sed 's/<mtt_model_name>/$(SYS)/g' > $@

$(SYS)_sfun.zip: $(SRC)

	zip $@ $^





$(SYS)_ae.sfun: $(SYS)_ae.m





	${MTT_CC}/mtt_m2cc.sh $(SYS) ae sfun cat 

$(SYS)_ode.sfun: $(SYS)_ode.m

	${MTT_CC}/mtt_m2cc.sh $(SYS) ode sfun cat

$(SYS)_odeo.sfun: $(SYS)_odeo.m

	${MTT_CC}/mtt_m2cc.sh $(SYS) odeo sfun cat

$(SYS)_state.sfun: $(SYS)_state.m

	${MTT_CC}/mtt_m2cc.sh $(SYS) state sfun cat

%::
	mtt -q $(OPTS) `echo $* | sed 's/\(.*\)_\(.*\)\.\(.*\)/\1 \2 \3/'`


|

>
>
|
>

|
>
>
>
>
>
|

|
>


|
>


>
>
>
>
|
>
>
>
>
>
|

|
>
|

|
>
|

|
>
|



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#! /usr/bin/make -f

all: $(SYS)_sfun.mexglx

$(SYS)_sfun.mexglx: $(SYS)_sfun.c $(SYS)_def.h $(SYS)_sympar.h $(SYS)_numpar.c $(SYS)_ode.c $(SYS)_odeo.c $(SYS)_state.c $(SYS)_sfun_ae.mexglx 
	echo Creating $@
	mex $(SYS)_sfun.c
	cp *_sfun*mexglx ..

$(SYS)_sfun.c:: ${MTT_REP}/sfun_rep/sfun.c.tmpl
	echo Creating $@
	cat $^ | sed 's/<mtt_model_name>/$(SYS)/g' > $@

$(SYS)_sfun_ae.mexglx: $(SYS)_sfun_ae.c $(SYS)_def.h $(SYS)_ae.c
	echo Creating $@
	mex $(SYS)_sfun_ae.c

$(SYS)_sfun_ae.c:: ${MTT_REP}/sfun_rep/ae.c.tmpl
	echo Creating $@
	cat $^ | sed 's/<mtt_model_name>/$(SYS)/g' > $@

$(SYS)_sfun.zip: $(SYS)_sfun.c $(SYS)_sfun_ae.c $(SYS)_def.h $(SYS)_sympar.h $(SYS)_ae.c $(SYS)_numpar.c $(SYS)_ode.c $(SYS)_odeo.c $(SYS)_state.c README
	echo Creating $@
	zip $@ $^

README:: ${MTT_REP}/sfun_rep/README.tmpl
	echo Creating $@
	cat $^ | sed 's/<mtt_model_name>/$(SYS)/g' > $@

$(SYS)_ae.c: $(SYS)_ae.m
	echo Creating $@
	${MTT_CC}/mtt_m2cc.sh $(SYS) ae c cat 

$(SYS)_numpar.c: $(SYS)_numpar.m
	echo Creating $@
	${MTT_CC}/mtt_m2cc.sh $(SYS) numpar c cat

$(SYS)_ode.c: $(SYS)_ode.m
	echo Creating $@
	${MTT_CC}/mtt_m2cc.sh $(SYS) ode c cat

$(SYS)_odeo.c: $(SYS)_odeo.m
	echo Creating $@
	${MTT_CC}/mtt_m2cc.sh $(SYS) odeo c cat

$(SYS)_state.c: $(SYS)_state.m
	echo Creating $@
	${MTT_CC}/mtt_m2cc.sh $(SYS) state c cat

%::
	mtt -q $(OPTS) `echo $* | sed 's/\(.*\)_\(.*\)\.\(.*\)/\1 \2 \3/'`

MTT: Model Transformation Tools
GitHub | SourceHut | Sourceforge | Fossil RSS ]