#!/bin/sh eval 'exec perl -S -x -w $0 ${1+"$@"}' #!perl # # compareSimulationResults.pl: program to do a toleranced comparison of compact model simulation results # # Rel Date Who Comments # ==== ========== ============= ======== # 1.0 04/13/06 Colin McAndrew Initial version # sub usage() { print " $prog: compare simulation results between two files Usage: $prog [options] refFile simFile Files: refFile reference results file simFile simulated results file Options: -c CLIP match numbers n1 and n2 with abs(n1)) { s/\s+$//; push(@Ref,$_); } close(IF); return("ERROR: cannot open file $simFile") if (!open(IF,"$simFile")); while () { s/\s+$//; push(@Sim,$_); } close(IF); return("FAIL (probably from some simulation failure)") if ($#Ref != $#Sim || $#Sim<1); return("FAIL (simulation output quantities differ)") if ($Ref[0] ne $Sim[0]); $maxAbsErr=0;$maxRelErr=0;$matchType=0; for ($j=1;$j<=$#Ref;++$j) { @RefRes=split(/\s+/,$Ref[$j]); @SimRes=split(/\s+/,$Sim[$j]); return("FAIL (number of quantities simulated are different") if ($#RefRes != $#SimRes); for ($i=1;$i<=$#RefRes;++$i) { # ignore first column, this is the sweep variable if ($RefRes[$i] !~ /^$main::number$/ || $SimRes[$i] !~ /^$main::number$/) { return("FAIL (non-numeric results"); } next if ($RefRes[$i] == $SimRes[$i]); $matchType=1 if ($matchType<1); #next if (abs($RefRes[$i]) < $clip && abs($SimRes[$i]) < $clip); next if (abs($RefRes[$i]) < $clip || abs($SimRes[$i]) < $clip); if ($RefRes[$i]*$SimRes[$i] <= 0.0) { $matchType=2 if ($matchType<2); $absErr=abs($RefRes[$i]-$SimRes[$i]); $relErr=$absErr/(0.5*(abs($RefRes[$i])+abs($SimRes[$i])+$absErr)); $maxRelErr=$relErr if ($relErr > $maxRelErr); if ($main::verbose) {print STDERR $RefRes[$i],$SimRes[$i],100*$relErr."\%"} next; } $lo=abs($RefRes[$i]); if (abs($SimRes[$i]) < $lo) { $hi=$lo; $lo=abs($SimRes[$i]); } else { $hi=abs($SimRes[$i]); } $mag=int(log($lo)/log(10))+1; if ($lo < 1) {$mag-=1} $lo=int(0.5+$lo*10**($nDigits+1-$mag)); $hi=int(0.5+$hi*10**($nDigits+1-$mag)); next if (abs($lo-$hi)<=10); $absErr=abs($RefRes[$i]-$SimRes[$i]); $relErr=$absErr/(0.5*(abs($RefRes[$i])+abs($SimRes[$i])+$absErr)); next if ($relErr<$relTol); if ($main::verbose) {print STDERR $RefRes[$i],$SimRes[$i],100*$relErr."\%"} $matchType=2 if ($matchType<2); $maxRelErr=$relErr if ($relErr > $maxRelErr); } } if ($matchType==0) { return("MATCH (exact)"); } elsif ($matchType==1) { return("MATCH (within specified tolerances)"); } elsif ($matchType==2) { $mag=int(log($maxRelErr)/log(10)); $i=$maxRelErr/10**$mag; $maxRelErr=100*10**$mag*int(0.5+1e3*$i)/1e3; return("DIFFER (max rel error is $maxRelErr\%)"); } }