#!/bin/sh
## smo_multi_class: multi-class wrapper for SMO
##   Usage: smo_multi_class options -- smo-options
##      options must include:
##           -c number-of-classes
##           -f data-file-name
##           -o output-file-name
##           -m svm-file-name-prefix
##      The `smo-options' after `--' are passed to smo.

if [ $# -lt 8 ]
then
    sed -n '/^##/s/^## //p' $0 >&2
    exit 1
fi

number_of_classes=0
data_file_name=NULL
output_file_name=NULL
svm_file_name_prefix=NULL

while getopts c:f:o:m: c
do
    case $c in
        c) number_of_classes=$OPTARG;;
        f) data_file_name=$OPTARG;;
        o) output_file_name=$OPTARG;;
        m) svm_file_name_prefix=$OPTARG;;
       \?) sed -n '/^##/s/^## //p' $0 >&2
           exit 1;;
    esac
done
shift `expr $OPTIND - 1`

if [ $output_file_name = NULL ] || [ $svm_file_name_prefix = NULL ]
then
       sed -n '/^##/s/^## //p' $0 >&2
       exit 1
fi

if [ $number_of_classes -ge 2 ]
then
    :
else
    echo "error: invalid number of classes ($number_of_classes); should be >= 2" >&2
    exit 1
fi

if [ ! -f $data_file_name ]
then
    echo "error: cannot open data file: $data_file_name" >&2
    exit 1
fi

tmp_data_file_name=../tmp/multiclasstmpsvm.data
tmp_output_file_name=../tmp/multiclasstmpsvm.output
all_target_file_name=../tmp/multiclasstmpsvm.all_target
cat $data_file_name | awk '{ print $NF }' > $all_target_file_name
printf "" > $output_file_name
i=0
while [ $i -lt $number_of_classes ]
do
    printf "class $i: "
    individual_svm_file_name=${svm_file_name_prefix}.$i
    cat $data_file_name |
    awk '{ for (i=1; i<NF; i++)
             printf("%s ",$i);
           if ($NF == '$i')
             printf("1\n");
           else
             printf("-1\n");
         }' > $tmp_data_file_name
    ../c/smo "$@" \
         -f $tmp_data_file_name \
         -o $tmp_output_file_name \
         -m $individual_svm_file_name
    paste $output_file_name  $tmp_output_file_name > ${output_file_name}.tmp
    mv ${output_file_name}.tmp $output_file_name 
    rm $tmp_data_file_name $tmp_output_file_name
    i=`expr $i + 1`
done
printf "multi-class: "
paste $output_file_name $all_target_file_name |
awk 'BEGIN { n_total = 0.
             n_error = 0.
           }
     {
        best_val = $1
        best_i = 1
        for (i=2; i<NF; i++)
            if ($i > best_val) {
                best_val = $i
                best_i = i
            }
        best_i--
        if (best_i != $NF)
            n_error++
        n_total++
     }
     END { print n_error/n_total }'
rm $all_target_file_name
