'''
Created on Jan 8, 2015
@author: Atanas Pavlov
'''
import numpy as np
import math
def cart2pol(x, y):
'''
Converts Cartesian coordinates (x,y) to Polar coordinates (rho, phi)
'''
rho = np.sqrt(x**2 + y**2)
phi = np.arctan2(y, x)
return (rho, phi)
def pol2cart(rho, phi):
'''
Converts Polar coordinates (rho, phi) to Cartesian coordinates (x,y)
'''
x = rho * np.cos(phi)
y = rho * np.sin(phi)
return (x, y)
[docs]class Interpolator1D(object):
"""
1D interpolator using numpy.interp. Allows the values to be
set only once in the constructor, and then called as a function.
"""
def __init__(self, xValues, yValues, outOfRange = 'value'):
self.xValues = np.array(xValues);
self.yValues = np.array(yValues);
def __call__(self, inputValues):
from numpy import interp
return interp(inputValues, self.xValues, self.yValues)
[docs]class SectionCalculator(object):
"""
Perform calculations over a sectioned array object,
using different callable objects for each section
"""
def __init__(self):
self.sectionIndices = []
self.calculators = []
[docs] def addSection(self, sectionIndices, calculator):
"""
:param sectionIndices: a tuple (x1, x2) where x1 is the first
index of the section and x2 is the last index
:param calculator: a callable fn(x) accepting a single argument
that will be use used to calculate z = fn(y) over this section
"""
self.sectionIndices.append(sectionIndices)
self.calculators.append(calculator)
def __call__(self, inputValues):
results = np.zeros((len(inputValues)))
for section, calc in zip(self.sectionIndices, self.calculators):
sectionInputs = inputValues[section[0]:(section[1] + 1)]
sectionResults = calc(sectionInputs)
results[section[0]:(section[1] + 1)] = sectionResults
return results
@classmethod
def test(cls):
calc = cls()
calc.addSection((0, 3), lambda x: 2 * x)
calc.addSection((5, 9), Interpolator1D(xValues = np.arange(20), yValues = np.arange(20)**2))
print calc(np.arange(15) + 1)
[docs]class NamedStateVector(object):
"""
A data structure which has two different views.
On one hand it is a vector of values (of the same type),
on the other hand each value can be accessed by name, as though
it is a member variable of the class.
"""
def __init__(self, stateList):
from collections import OrderedDict
self.__dict__['stateMap'] = OrderedDict((zip(stateList, range(len(stateList)))))
self.__dict__['_values'] = np.zeros((len(stateList)))
[docs] def set(self, values, copy = False):
'''
Sets variable values from a numpy vector
'''
if (copy):
self.__dict__['_values'] = values[:]
else:
self.__dict__['_values'] = values
[docs] def get(self, copy = False):
'''
Sets numpy array's values from the internal storage
'''
if (copy):
values = self._values[:]
else:
values = self._values
return values
def getColIndex(self, colName):
colIndex = self.stateMap.get(colName, None)
return colIndex
def __setattr__(self, attr, value):
self._values[self.stateMap[attr]] = value
def __getattr__(self, attr):
return self._values[self.stateMap[attr]]
@staticmethod
def test():
a = NamedStateVector(['T', 'p', 'h'])
n1 = np.array([3, 7, 4], copy = True)
a.set(n1)
print('T = {}, p = {}, h = {}'.format(a.T, a.p, a.h))
a.T = 56
a.h = -20
print('T = {}, p = {}, h = {}'.format(a.T, a.p, a.h))
print (a.get())
class RecArrayManipulator(object):
@staticmethod
def removeNaN(a, maxConsecutiveNaNs = -1):
cols = a.dtype.fields.keys()
stat = {}
nanRows = np.zeros(shape = (a.shape[0],), dtype = np.bool)
for col in cols:
testNaN = np.isnan(a[col])
nanRows |= testNaN
numRowToRemove = len(a[nanRows])
stat['numRemoved'] = numRowToRemove
if (numRowToRemove > 0):
# Check for the length of consequtive NaN sequences
if (maxConsecutiveNaNs > 0):
NaNLocs = np.diff(nanRows).nonzero()[0] + 1
NaNLocs = NaNLocs.tolist()
if (nanRows[0]):
NaNLocs.insert(0, 0)
if (nanRows[-1]):
NaNLocs.append(len(nanRows))
NaNLocs = np.array(NaNLocs)
NaNLens = NaNLocs[1::2] - NaNLocs[::2]
iMaxNanLen = NaNLens.argmax()
if (NaNLens[iMaxNanLen] > maxConsecutiveNaNs):
raise ValueError('NaN segment with length {}, higher than maxConsecutiveNaNs = {}, found starting at index {}'.format(NaNLens[iMaxNanLen], maxConsecutiveNaNs, NaNLocs[2 * iMaxNanLen]))
stat['maxConsecutiveNaN'] = NaNLens[iMaxNanLen]
newArray = np.empty((len(a) - numRowToRemove,), dtype=a.dtype)
for col in cols:
newArray[col] = a[col][~nanRows]
else:
newArray = a
return newArray, stat
if __name__ == '__main__':
SectionCalculator.test()
NamedStateVector.test()