#!/bin/bash

function compare {
    local layer=$3
    local line=$4
    local expected=$(echo "$1" | tr ',' '\n')
    local actual=$(echo "$2" \
                       | tail -n+$line \
                       | head -n 1 \
                       | tr ',' '\n' \
                       | { tee >(head -n 10 >&2) | tail -n 10; } 2>&1 )
    echo "$actual" \
        | paste -d- - <(echo "$expected") \
        | bc \
        | ruby -e 'STDIN.each_line { |line| raise "Expected and actual differ by > 1E-6: " + line unless line.to_f.abs < 1E-6 }'
    if [ $? -ne 0 ];
    then
        echo "Comparison failed at $layer for example $line"
    fi
}

layer0="../layer full -w weights.keras_mnist_mlp.0.csv -b biases.keras_mnist_mlp.0.csv --input-shape=784 -f sigmoid"
layer1="../layer full -w weights.keras_mnist_mlp.1.csv -b biases.keras_mnist_mlp.1.csv --input-shape=32  -f relu"
layer2="../layer full -w weights.keras_mnist_mlp.2.csv -b biases.keras_mnist_mlp.2.csv --input-shape=16  -f softmax"

# Layer 0 tests
echo "Testing layer 0: $layer0"

expected_layer0_x1="0.46968474984169006,0.5044270157814026,0.590981125831604,0.26980718970298767,0.4006352424621582,0.5741773247718811,0.695325493812561,0.6393222808837891,0.6564003229141235,0.39609262347221375,0.4363888204097748,0.45385563373565674,0.5995831489562988,0.7468971610069275,0.2713189423084259,0.6897799968719482,0.2980523109436035,0.3865453600883484,0.5309172868728638,0.46104171872138977"
actual_layer0_x1=$(cat mnist_x_10.csv | $layer0)
compare "$expected_layer0_x1" "$actual_layer0_x1" 0 1

expected_layer0_x4="0.4839942753314972,0.4607725143432617,0.48132139444351196,0.4052985608577728,0.4844565987586975,0.4191582500934601,0.5782468914985657,0.6500292420387268,0.4398307204246521,0.4187796115875244,0.6325455904006958,0.5055210590362549,0.6233657598495483,0.40879756212234497,0.5612363815307617,0.5285711288452148,0.44392117857933044,0.3242703974246979,0.33930253982543945,0.46059396862983704"
actual_layer0_x4=$(cat mnist_x_10.csv | $layer0)
compare "$expected_layer0_x4" "$actual_layer0_x4" 0 4

expected_layer0_x7="0.5258949995040894,0.42825475335121155,0.5082485675811768,0.4638459086418152,0.4710676074028015,0.39583268761634827,0.5278728604316711,0.6498907804489136,0.3778584599494934,0.551715075969696,0.4468076527118683,0.5058813095092773,0.639255940914154,0.5346152782440186,0.27023059129714966,0.564570426940918,0.33937495946884155,0.370738685131073,0.48760131001472473,0.45881402492523193"
actual_layer0_x7=$(cat mnist_x_10.csv | $layer0)
compare "$expected_layer0_x7" "$actual_layer0_x7" 0 7

expected_layer0_x10="0.5672911405563354,0.3915395140647888,0.5514141917228699,0.5451692938804626,0.40763530135154724,0.5980116128921509,0.5515854358673096,0.6701422929763794,0.5499566197395325,0.5736289024353027,0.6427804231643677,0.5238101482391357,0.509374737739563,0.45320916175842285,0.4765453040599823,0.5785587430000305,0.3825787305831909,0.3323952555656433,0.4137732982635498,0.4889243543148041"
actual_layer0_x10=$(cat mnist_x_10.csv | $layer0)
compare "$expected_layer0_x10" "$actual_layer0_x10" 0 10

# Layer 1 tests
echo "Testing layer 1: $layer1"

expected_layer1_x2="0.9640750885009766,0.7466605305671692,0.0,0.0,0.0,0.0,0.33264046907424927,0.0,0.7493124604225159,0.8038330674171448,0.33264046907424927,0.0,0.7493124604225159,0.8038330674171448,0.0,0.5303158164024353,0.0,0.0,0.7602857947349548,0.24084851145744324"
actual_layer1_x2=$(cat mnist_x_10.csv | $layer0 | $layer1)
compare "$expected_layer1_x2" "$actual_layer1_x2" 1 2

expected_layer1_x3="0.9824855923652649,0.756685733795166,0.0,0.0,0.0,0.0,0.1854132115840912,0.0,0.7233110666275024,0.6369828581809998,0.1854132115840912,0.0,0.7233110666275024,0.6369828581809998,0.0,0.6293150782585144,0.0,0.0,1.0296781063079834,0.08498675376176834"
actual_layer1_x3=$(cat mnist_x_10.csv | $layer0 | $layer1)
compare "$expected_layer1_x3" "$actual_layer1_x3" 1 3

expected_layer1_x6="0.8453606963157654,0.741368293762207,0.0,0.0,0.0,0.0,0.11267518997192383,0.06682741641998291,0.5682740807533264,0.9394508600234985,0.11267518997192383,0.06682741641998291,0.5682740807533264,0.9394508600234985,0.0,0.7104471921920776,0.0,0.0,0.9984039068222046,0.0"
actual_layer1_x6=$(cat mnist_x_10.csv | $layer0 | $layer1)
compare "$expected_layer1_x6" "$actual_layer1_x6" 1 6

expected_layer1_x9="0.9727324843406677,0.7991101145744324,0.0,0.0,0.0,0.0,0.29540368914604187,0.14007195830345154,0.6839665770530701,0.8919571042060852,0.29540368914604187,0.14007195830345154,0.6839665770530701,0.8919571042060852,0.0,0.49109071493148804,0.0,0.0,1.009200096130371,0.0"
actual_layer1_x9=$(cat mnist_x_10.csv | $layer0 | $layer1)
compare "$expected_layer1_x9" "$actual_layer1_x9" 1 9

# Layer 2 tests
echo "Testing layer 2: $layer2"

expected_layer2_x5="0.05621287599205971,0.0999031811952591,0.07224798947572708,0.11724083125591278,0.04720408096909523,0.09120805561542511,0.11009061336517334,0.06975344568490982,0.2707977890968323,0.06534109264612198,0.05621287599205971,0.0999031811952591,0.07224798947572708,0.11724083125591278,0.04720408096909523,0.09120805561542511,0.11009061336517334,0.06975344568490982,0.2707977890968323,0.06534109264612198"
actual_layer2_x5=$(cat mnist_x_10.csv | $layer0 | $layer1 | $layer2)
compare "$expected_layer2_x5" "$actual_layer2_x5" 2 5

expected_layer2_x8="0.0668817013502121,0.0829777643084526,0.07864955067634583,0.10060559213161469,0.044900842010974884,0.08170913904905319,0.11694636940956116,0.07278165966272354,0.281049907207489,0.07349754124879837,0.0668817013502121,0.0829777643084526,0.07864955067634583,0.10060559213161469,0.044900842010974884,0.08170913904905319,0.11694636940956116,0.07278165966272354,0.281049907207489,0.07349754124879837"
actual_layer2_x8=$(cat mnist_x_10.csv | $layer0 | $layer1 | $layer2)
compare "$expected_layer2_x8" "$actual_layer2_x8" 2 8
