#! /bin/sh

# script uses Reduce + Scope to optimise a vector
# either global (an entire vector) or local (line-by-line)

extent=$1			# global or local
system=$2
representation=$3

# error codes
E_REP_NOT_SUPPORTED=-19
E_FILE_NOT_EXIST=-20

case $representation in
    ae)
	matrix=yz ;
	nmatrix=`mtt_getsize $system yz` ;;
    cse | csex)
	matrix=edx ;
	nmatrix=`mtt_getsize $system x` ;;
    ode)
	matrix=dx ;
	nmatrix=`mtt_getsize $system x` ;;
    cseo | odeo)
	matrix=y ;
	nmatrix=`mtt_getsize $system y` ;;
    *)
	exit $E_REP_NOT_SUPPORTED;;
esac

# Global optimisation: Generate a command of the form
# optimise mtt?(1,1) :=: mtt?(1,1), mtt?(2,1) :=: mtt?(2,1), ..., INAME mtt_tmp$
#
# Local optimisation: Generate a command of the form
# optimise mtt?(1,1) :=: mtt?(1,1) INAME mtt_tmp$ \
# optimise mtt?(2,1) :=: mtt?(2,1) INAME mtt_tmp$ ...
case $extent in
    "global" )
	delimiter=", "
	terminate="INAME mtt_tmp$"
	;;
    "local" )
	delimiter=" INAME mtt_tmp$ optimize"
	terminate="$"
	;;
    * )
	echo "*** unknown scope for optimisation"
	echo "*** should be global or local"
	exit -1
	;;
esac

if [ $nmatrix -gt 0 ]; then
    command="optimize"
    counter=1
    while [ $counter -le $nmatrix ]; do
	command="$command mtt$matrix($counter,1) :=: mtt$matrix($counter,1)$delimiter"
	counter=`expr $counter + 1`
    done
    command="$command $terminate"
else
    command=""
fi

logfile=${system}_${representation}_optimisation.log
tmpfile=${system}_${representation}_optimisation.tmp
outfile=${system}_${representation}.r

if [ ! -f $outfile ]; then
    exit $E_FILE_NOT_EXIST
fi

find_code ()
{
    file_in=${1:-${IN}}
    portion=${2:-"body"}
    head=`cat ${file_in} | gawk '($2 == "Begin" && $3 == "Matrix") { print NR }'`
    foot=`cat ${file_in} | gawk '($2 == "End"   && $3 == "Matrix") { print NR }'`
    case ${portion} in
	head)
	    start=0
	    end=${head}
	    ;;
	body)
	    start=${head}
	    end=${foot}
	    ;;
	foot)
	    start=${foot}
	    end=end
	    ;;
	*)
	    echo "Error in find_code: portion unknown"
	    return -1
	    ;;
    esac
    cat ${file_in} |\
    gawk --assign start=${start} --assign end=${end} '
	(start < NR && NR < end) { print $0 }'
};


# Use Reduce to perform the optimisation
${SYMBOLIC:-reduce} <<EOF > $logfile 2>&1
off nat;
in "${system}_def.r";
in "$outfile";
load scope;
out "$tmpfile";
$command;
shut "$tmpfile";
$end;
EOF

cp $outfile $outfile.unoptimised
cp $tmpfile $outfile.tmp

find_code $outfile head > $tmpfile.head
cat $tmpfile | mtt_fix_integers > $tmpfile.body
find_code $outfile foot > $tmpfile.foot
cat $tmpfile.head $tmpfile.body $tmpfile.foot > $outfile
echo ";end;" >> $outfile

mtt_error_r $logfile
