make table compare normalize data by type (scaler, vector, tensor)

This commit is contained in:
Chen 2016-09-02 14:30:08 -04:00 committed by chen
parent d9077805e4
commit 2b3faf204c
1 changed files with 85 additions and 84 deletions

View File

@ -5,6 +5,7 @@ import os,sys,shutil
import logging,logging.config import logging,logging.config
import damask import damask
import numpy as np import numpy as np
import itertools
from collections import Iterable from collections import Iterable
from optparse import OptionParser from optparse import OptionParser
@ -467,17 +468,15 @@ class Test():
columns = [None], # list of list of column labels (per file) columns = [None], # list of list of column labels (per file)
rtol = 1e-5, rtol = 1e-5,
atol = 1e-8, atol = 1e-8,
preFilter = -1.0,
postFilter = -1.0,
debug = False): debug = False):
""" """
compare tables with np.allclose compare tables with np.allclose
threshold can be used to ignore small values (a negative number disables this feature)
""" """
if not (isinstance(files, Iterable) and not isinstance(files, str)): # check whether list of files is requested if not (isinstance(files, Iterable) and not isinstance(files, str)): # check whether list of files is requested
files = [str(files)] files = [str(files)]
if len(files) < 2: return True # single table is always close to itself...
tables = [damask.ASCIItable(name = filename,readonly = True) for filename in files] tables = [damask.ASCIItable(name = filename,readonly = True) for filename in files]
for table in tables: for table in tables:
table.head_read() table.head_read()
@ -486,7 +485,7 @@ class Test():
columns = columns[:len(files)] # truncate to same length as files columns = columns[:len(files)] # truncate to same length as files
for i,column in enumerate(columns): for i,column in enumerate(columns):
if column is None: columns[i] = tables[i].labels(raw = True) # if no column is given, read all if column is None: columns[i] = tables[i].labels(raw = True) # if no column is given, use all
logging.info('comparing ASCIItables') logging.info('comparing ASCIItables')
for i in xrange(len(columns)): for i in xrange(len(columns)):
@ -496,37 +495,37 @@ class Test():
) )
logging.info(files[i]+':'+','.join(columns[i])) logging.info(files[i]+':'+','.join(columns[i]))
if len(files) < 2: return True # single table is always close to itself... # peek into the ASCII table to figure out real table size
# the cryptic table header does not share the same size as real
maximum = np.zeros(len(columns[0]),dtype='f') # table
data = [] table.data_readArray(columns[0])
for table,labels in zip(tables,columns): maximum = np.zeros(table.data.shape[1], dtype='f')
data = [] # list of feature table extracted from each file (ASCII table)
for table, labels in zip(tables, columns):
table.data_readArray(labels) table.data_readArray(labels)
data.append(np.where(np.abs(table.data)<preFilter,np.zeros_like(table.data),table.data)) for label in labels:
maximum += np.abs(table.data).max(axis=0) idx = table.label_indexrange(label)
maximum[idx] = np.maximum(maximum[idx],
np.amax(np.linalg.norm(table.data[:,idx],axis=1)))
data.append(table.data)
table.close() table.close()
maximum /= len(tables) maximum = np.where(maximum > 0.0, maximum, 1) # avoid div by zero for empty columns
maximum = np.where(maximum >0.0, maximum, 1) # avoid div by zero for empty columns
# normalize each table
for i in xrange(len(data)): for i in xrange(len(data)):
data[i] /= maximum data[i] /= maximum
mask = np.zeros_like(table.data,dtype='bool') if debug:
logging.debug(str(maximum))
for table in data: allclose = np.absolute(data[0]-data[1]) <= (atol + rtol*np.absolute(data[1]))
mask |= np.where(np.abs(table)<postFilter,True,False) # mask out (all) tiny values for ok,valA,valB in zip(allclose,data[0],data[1]):
logging.debug('{}:\n {}\n{}\n'.format(ok,valA,valB))
allclose = True # start optimistic allclose = True # start optimistic
for i in xrange(1,len(data)): for i in xrange(1,len(data)):
if debug: allclose &= np.allclose(data[i-1],data[i],rtol,atol) # accumulate "pessimism"
t0 = np.where(mask,0.0,data[i-1])
t1 = np.where(mask,0.0,data[i ])
j = np.argmin(np.abs(t1)*rtol+atol-np.abs(t0-t1))
logging.info('{:f}'.format(np.amax(np.abs(t0-t1)/(np.abs(t1)*rtol+atol))))
logging.info('{:f} {:f}'.format((t0*maximum).flatten()[j],(t1*maximum).flatten()[j]))
allclose &= np.allclose(np.where(mask,0.0,data[i-1]),
np.where(mask,0.0,data[i ]),rtol,atol) # accumulate "pessimism"
return allclose return allclose
@ -554,14 +553,16 @@ class Test():
def report_Success(self,culprit): def report_Success(self,culprit):
ret = culprit
if culprit == 0: if culprit == 0:
logging.critical(('The test' if len(self.variants) == 1 else 'All {} tests'.format(len(self.variants))) + ' passed') msg = 'The test passed' if len(self.variants) == 1 \
logging.critical('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') else 'All {} tests passed.'.format(len(self.variants))
return 0 elif culprit == -1:
if culprit == -1: msg = 'Warning: Could not start test...'
logging.warning('Warning: Could not start test') ret = 0
return 0
else: else:
logging.critical(' ********\n * Test {} failed...\n ********'.format(culprit)) msg = ' * Test "{}" failed.'.format(self.variants[culprit-1])
logging.critical('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
return culprit logging.critical('\n'.join(['*'*40,msg,'*'*40]) + '\n')
return ret