def printRange(row1, row2, col1, col2, HERCMATRIX): if row1 < 0: raise IndexError("row1 may not be less than zero") if row1 > HERCMATRIX.height: raise IndexError("row1 is out of bounds") if row2 < 0: raise IndexError("row2 may not be less than zero") if row2 > HERCMATRIX.height: raise IndexError("row2 is out of bounds") if col1 < 0: raise IndexError("col1 may not be less than zero") if col1 > HERCMATRIX.width: raise IndexError("col1 is out of bounds") if col2 < 0: raise IndexError("col2 may not be less than zero") if col2 > HERCMATRIX.width: raise IndexError("col2 is out of bounds") if row1 > row2: raise ValueError("row1 larger than row2") if col1 > col2: raise ValueError("col1 larger than col2") TMPMATRIX = libHercMatrix.hercMatrix() TMPMATRIX.height = abs(row2 - row1 + 1) TMPMATRIX.width = abs(col2 - col1 + 1) width = HERCMATRIX.width height = HERCMATRIX.height for element in HERCMATRIX.elements: row = element[0] col = element[1] val = element[2] if (row >= row1) and (row <= row2): if (col >= col1) and (col <= col2): try: TMPMATRIX.setValue(row - row1, col - col1, val) except IndexError as e: logging.warning("encountered error {0}".format(e)) logging.warning("writing to row {0} col {1} of " .format(row - row1, col - col1)) logging.warning("row {0} col {1}" .format(TMPMATRIX.height, TMPMATRIX.width)) TMPMATRIX.makeRowMajor() displayMatrix(TMPMATRIX)
def read(path): # hercMatrix instance we will return later MATRIX = libHercMatrix.hercMatrix() # CSR matrix contents row_ptr = numpy.array([]) # row pointer col_idx = numpy.array([]) # column index val = numpy.array([]) # values # read the file FILE = open(path, 'r') lines = FILE.readlines() FILE.close() # read in the header, split it, and save the contents header = lines[0].split() height = int(header[0]) width = int(header[0]) nzentries = int(header[1]) lines.pop(0) # get rid of the header for line in lines: if len(line.split()) == 2: # if the length is 2, we are in the column index + val section val = numpy.append(val, float(line.split()[0])) # col_idx is 1-indexed in valcol col_idx = numpy.append(col_idx, int(line.split()[1]) - 1) elif len(line.split()) == 1: # if line length is 1, we are in the row pointer section row_ptr = numpy.append(row_ptr, int(line)) else: print("WARNING: malformed line for valcol file: {0}".format(line)) # generate a scipy.sparse.csr_matrix instance of # libHercMatrix.hercMatrix.replaceContents() CSRMATRIX = scipy.sparse.csr_matrix((val, col_idx, row_ptr), shape=(height, width)) # move data into the hercMatrix instance MATRIX.nzentries = nzentries MATRIX.height = height MATRIX.width = width MATRIX.replaceContents(CSRMATRIX) # check if the matrix is symmetric if MATRIX.checkLowerTriangle(): print("Lower triangle is empty, assuming symmetric matrix...") MATRIX.symmetry = "SYM" return MATRIX
# utility for exploring and editing the contents of hercm matrix files import readline import libHercMatrix import libHercmIO import matplotlib import matplotlib.pyplot import logging import os import pprint from yapsy.PluginManager import PluginManager import traceback import sys WORKINGMATRIX = libHercMatrix.hercMatrix() pp = pprint.PrettyPrinter() pluginManager = PluginManager() menuItems = [] currentTraceBack = None def loadPlugins(): global pluginManager global menuItems pluginManager.setPluginPlaces(["menuPlugins"]) pluginManager.collectPlugins() for plugin in pluginManager.getAllPlugins(): menuItems.append(plugin.plugin_object)
def readMatrix(filename, form, showProgress=False): HERCMATRIX = libHercMatrix.hercMatrix() logging.info("reading matrix {0} in format {1}".format(filename, form)) if (form == 'hercm') or (form == 'bxf'): # TODO: exception handling HERCMATRIX = libBXF.read(filename) elif form == 'mtx': from scipy import io from scipy.sparse import csr_matrix from numpy import array # reads in an MTX file and converts it to hercm try: if showProgress: print("reading data from file...") rawMatrix = scipy.sparse.coo_matrix(scipy.io.mmread(filename)) if 'symmetric' in io.mminfo(filename): HERCMATRIX.symmetry = "SYM" else: HERCMATRIX.symmetry = "ASYM" hercm = {} # needed to generate verification if showProgress: print("generating header data..") hercm['val'] = rawMatrix.data hercm['col'] = rawMatrix.col.tolist() hercm['row'] = rawMatrix.row.tolist() (matrixWidth, matrixHeight) = rawMatrix.shape HERCMATRIX.height = int(matrixHeight) HERCMATRIX.width = int(matrixWidth) vs = libBXF.generateVerificationSum(hercm) HERCMATRIX.verification = vs HERCMATRIX.remarks = [] # I'm not sure why has to be hard... # http://stackoverflow.com/questions/26018781/numpy-is-it-possible-to-preserve-the-dtype-of-columns-when-using-column-stack if showProgress: print("preparing matrix data...") val = numpy.asarray(hercm['val'], dtype='float64') col = numpy.asarray(hercm['col'], dtype='int32') row = numpy.asarray(hercm['row'], dtype='int32') val = numpy.rec.array(val, dtype=[(('val'), numpy.float64)]) col = numpy.rec.array(col, dtype=[(('col'), numpy.int32)]) row = numpy.rec.array(row, dtype=[(('row'), numpy.int32)]) HERCMATRIX.elements = append_fields(row, 'col', col, usemask=False, dtypes=[numpy.int32]) HERCMATRIX.elements = append_fields(HERCMATRIX.elements, 'val', val, usemask=False, dtypes=[numpy.float64]) HERCMATRIX.nzentries = len(HERCMATRIX.elements['val']) HERCMATRIX.verification = libBXF.generateVerificationSum( HERCMATRIX) if showProgress: print("finished reading matrix") except IOError as e: # make sure the file exists and is readable logging.warning("(lsc-480) could not open matrix file") raise IOError("could not open matrix file for writing...", str(e)) elif form == 'mat': # matlab matrices from scipy import io from scipy import sparse from numpy import array try: rawMatrix = scipy.sparse.coo_matrix( scipy.io.loadmat(filename)['matrix']) hercm = {} # needed to generate verification hercm['val'] = rawMatrix.data hercm['col'] = rawMatrix.col.tolist() hercm['row'] = rawMatrix.row.tolist() (matrixWidth, matrixHeight) = rawMatrix.shape HERCMATRIX.height = int(matrixHeight) HERCMATRIX.width = int(matrixWidth) vs = libBXF.generateVerificationSum(hercm) HERCMATRIX.verification = vs HERCMATRIX.remarks = [] # I'm not sure why has to be hard... # http://stackoverflow.com/questions/26018781/numpy-is-it-possible-to-preserve-the-dtype-of-columns-when-using-column-stack val = numpy.asarray(hercm['val'], dtype='float64') col = numpy.asarray(hercm['col'], dtype='int32') row = numpy.asarray(hercm['row'], dtype='int32') val = numpy.rec.array(val, dtype=[(('val'), numpy.float64)]) col = numpy.rec.array(col, dtype=[(('col'), numpy.int32)]) row = numpy.rec.array(row, dtype=[(('row'), numpy.int32)]) HERCMATRIX.elements = append_fields(row, 'col', col, usemask=False, dtypes=[numpy.int32]) HERCMATRIX.elements = append_fields(HERCMATRIX.elements, 'val', val, usemask=False, dtypes=[numpy.float64]) HERCMATRIX.nzentries = len(HERCMATRIX.elements['val']) if HERCMATRIX.checkSymmetry(): HERCMATRIX.symmetry = 'SYM' HERCMATRIX.verification = libBXF.generateVerificationSum( HERCMATRIX) except IOError as e: # make sure the file exists and is readable logging.warning("(lsc-536)could not open matrix file") raise IOError("could not open matrix file for writing...", str(e)) elif form == 'valcol': HERCMATRIX = libValcolIO.read(filename) else: logging.warning("(lsc-545) format {0} is not valid".format(form)) if showProgress: print("converting matrix to row-major...") logging.info("converting matrix to row-major") HERCMATRIX.makeRowMajor() if showProgress: print("matrix is now row major") if HERCMATRIX.symmetry == 'SYM': logging.info("matrix is symmetric, truncating upper triangle") if showProgress: print("matrix is symmetric, truncating upper triangle...") HERCMATRIX.makeSymmetrical('truncate') if showProgress: print("upper triangle truncated") return HERCMATRIX
def read(filename): # reads in the HeRCM file specified by filename # returns it as an instance of libhsm.hsm # matrix object we will return later HERCMATRIX = libHercMatrix.hercMatrix() # row, col, and val lists we will read the matrix data into later row = [] col = [] val = [] logging.info("Reading BXF file {0}".format(filename)) fileObject = open(filename, 'r') # this may raise OSError, which the caller should catch # Get a list of lines from the file. Might be a good point for future # optimization - lines could be processed one at a time lines = fileObject.readlines() fileObject.close() # read in the header header = lines[0] lines.pop(0) splitHeader = header.split() logging.info("read BXF header: " + header) # stuff we are going to read in from the header version = splitHeader[0] width = None height = None nzentries = None symmetry = None # version specific header parsing logic # deprecated HERCM (BXF 1.0) and BXF 2.0 if version == "HERCM" or version == "BXF": if len(splitHeader) > 6: logging.warning("possibly mangled header - too many " + "fields for BXF 1.0 header. Attempting to read anyway...") elif len(splitHeader) < 6: logging.warning("possibly mangled header - too few fields for " + "BXF 1.0 header. Attempting to read anyway...") elif len(splitHeader) < 5: raise ValueError("Header has too few fields for any known BXF " + "version - unable to read header") # read fields from the header, see doc-extra/bxf-spec.md for more # details width = int(splitHeader[1]) height = int(splitHeader[2]) nzentries = int(splitHeader[3]) symmetry = splitHeader[4].upper() elif (version == "BXF21") or (version == "BXF22"): # bxf 2.1 and 2.2 use # the same header format if len(splitHeader) != 5: raise ValueError("Header has incorrect number of fields for BXF " + " 2.1") width = int(splitHeader[1]) height = int(splitHeader[2]) nzentries = int(splitHeader[3]) symmetry = splitHeader[4].upper() else: raise ValueError("Header did not contain valid BXF version " + "identifier") # verify symmetry if symmetry not in ["SYM", "ASYM"]: logging.warning("Symmetry {0} is not valid, assuming asymmetric" .format(symmetry)) symmetry = "ASYM" logging.info("finished reading header") HERCMATRIX.width = width HERCMATRIX.height = height HERCMATRIX.nzentries = nzentries HERCMATRIX.symmetry = symmetry inField = False currentHeader = '' fieldname = '' vtype = '' currentContents = [] for line in lines: # we are starting a new field if not inField: currentHeader = line.rstrip() splitHeader = currentHeader.split() if (version == "BXF21") or (version == "BXF22"): fieldname = splitHeader[0] vtype = splitHeader[1] else: # if you review previous BXF specifications, field headers # had three fields, the middle of which was either `LIST` or # `SINGLE`. These can both be safely treated as lists, as BXF2.1 # does # fieldname = splitHeader[0] vtype = splitHeader[2] inField = True # this is the end of a field elif 'ENDFIELD' in line: # save the values we read from this field to lists for later use if fieldname.lower() == "val": val = currentContents elif fieldname.lower() == "row": row = currentContents elif fieldname.lower() == "col": col = currentContents elif fieldname.lower() == "remarks": pass else: logging.warning("Ignoring field with unrecognized name: " + fieldname) # discard the contents of this field currentContents = [] inField = False # we are currently reading data from a field else: for value in line.split(): # typecast this element according to the vtype # these may throw TypeError , which the caller should handle if vtype == 'INT': currentContents.append(int(value)) elif vtype == 'FLOAT': currentContents.append(float(value)) else: currentContents.append(value) # do some basic validation if (len(row) != len(col)) or \ (len(row) != len(val)) or \ (len(val) != len(col)): raise ValueError("one or more vectors have non-matching lengths" + ", not a valid COO matrix") elif (len(val) != nzentries): # maybe this should throw an exception? logging.warning("nzentries does not match number of nonzero entries " + "read from file - matrix may be mangled") else: logging.info("matrix seems sane, it is probably not corrupt") # copy matrix data into the matrix object for i in range(0, HERCMATRIX.nzentries): # this could probably be optimized by generating a scipy.sparse # matrix then using hercMatrix.replaceContents() if (version == "HERCM") or (version == "BXF") or (version == "BXF21"): if HERCMATRIX.symmetry == "SYM": # perform an inline transpose HERCMATRIX.addElement([col[i], row[i], val[i]]) else: HERCMATRIX.addElement([row[i], col[i], val[i]]) else: HERCMATRIX.addElement([row[i], col[i], val[i]]) HERCMATRIX.removeZeros() HERCMATRIX.makeRowMajor() return HERCMATRIX