# Coverage for rocketcea\biprop_utils\InterpProp_scipy.py : 8%

## 115 statements 9 run 106 missing 0 excluded

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | # Written by Charlie Taylor <cet@appliedpython.com> # Oct,21 2005 '''Interpolated Properties''' from scipy import array, float64, interpolate class InterpProp: '''Interpolate tables of properties will automatically sort input data... (x array must be monotonically increasing)''' def __call__(self, xval=0.0): return self.getValue( xval ) def __name__(self): return 'InterpProp_scipy' def __init__(self, xInp=[0,1], yInp=[10,110], extrapOK=1, linear=0, minY=None, maxY=None): # Sort Data to Make sure that x array is monotonically increasing a = map(float,xInp) b = map(float,yInp) c = [(x,y) for x,y in zip(a,b)] c.sort() a = [] b = [] for aa,bb in c: a.append(aa) b.append(bb) # now turn lists into Numpy/SciPy arrays self.x = array(a,float64) self.y = array(b,float64) self.extrapOK = extrapOK self.linear = linear if len(self.x) <= 1: self.extrapOK = 0 if len(self.x) <= 2: self.linear = 1 if linear: self.Nterp = 1 else: self.Nterp = 2 if len(self.x) > 1: #self.interpFunc = interpolate.interp1d(self.x, self.y, # kind=self.Nterp, bounds_error=False) #self.interpFunc = interpolate.UnivariateSpline(self.x, self.y, k=self.Nterp, s=0) # most smooth interpolation in my testing. self.interpFunc = interpolate.PchipInterpolator(self.x, self.y) #self.interpFunc = interpolate.Akima1DInterpolator(self.x, self.y) #self.interpFunc = interpolate.CubicSpline(self.x, self.y) self.derivFunc = self.interpFunc.derivative() else: self.interpFunc = lambda x : self.y[0] self.derivFunc = lambda X : 0.0 try: self.minY = float(minY) except: self.minY = None try: self.maxY = float(maxY) except: self.maxY = None self.delX = max(self.x) - min(self.x) def getValue(self, xval=0.0): xval = float(xval) if not self.extrapOK: if xval<self.x[0]: return self.y[0] if xval>self.x[-1]: return self.y[-1] #print '1) self.interpFunc( %s ) ='%xval,self.interpFunc( xval ) return float(self.interpFunc( xval )) # if not in data range, linearly extrapoate from end points. if xval<self.x[0]: yval = self.y[0]+(xval-self.x[0])*(self.y[1]-self.y[0])/(self.x[1]-self.x[0]) elif xval>self.x[-1]: yval = self.y[-1]+(xval-self.x[-1])*(self.y[-1]-self.y[-2])/(self.x[-1]-self.x[-2]) else: #print '2) self.interpFunc( %s ) ='%xval,self.interpFunc( xval ) yval = float(self.interpFunc( xval )) # if limits set, use them if self.minY is not None: yval = max(yval, self.minY) if self.maxY is not None: yval = min(yval, self.maxY) return yval def deriv(self, xval=0.0, stepFrac=0.0001): # if possible, use UnivariateSpline for 1st derivative. if xval>=self.x[0] and xval<=self.x[-1]: # for UnivariateSpline, linear has 0th and 1st deriv # quadratic has 0th, 1st and 2nd derivs return self.derivFunc( xval ) #return self.interpFunc.derivatives( xval )[1] # 1 for 1st derivative # otherwise, make a rough estimate. dx = self.delX * stepFrac return (self(xval+dx) - self(xval-dx)) / 2.0 / dx if __name__ == "__main__": #Self Test from pylab import * x = [1,2,6,4,5] y = [10,40,360,160,250] i = InterpProp(x,y) print( 'with extrapOK and no min/max' ) print( 'interpolated x=2.5 =',i.getValue(2.5) ) print( 'extrapolated x=0.0 =',i.getValue(0.0) ) print( 'extrapolated x=7.0 =',i.getValue(7) ) print('') i = InterpProp(x,y,extrapOK=0) print( 'with extrapOK=0 and no min/max') print( 'interpolated x=2.5 =',i.getValue(2.5)) print( 'extrapolated x=0.0 =',i.getValue(0.0)) print( 'extrapolated x=7.0 =',i.getValue(7)) print('') i = InterpProp(x,y,minY=0.0, maxY=300) print( 'with extrapOK and minY=0, maxY=300') print( 'interpolated x=2.5 =',i.getValue(2.5)) print( 'extrapolated x=0.0 =',i.getValue(0.0)) print( 'extrapolated x=7.0 =',i.getValue(7)) print('') x = [6, 1] y = [360, 10] i = InterpProp(x,y,linear=1) print( 'Two point linear with extrapOK and no min/max') print( 'interpolated x=2.5 =',i.getValue(2.5)) print( 'extrapolated x=0.0 =',i.getValue(0.0)) print( 'extrapolated x=7.0 =',i.getValue(7)) print('') x = [6] y = [360] i = InterpProp(x,y) print( 'Single point with extrapOK and no min/max') print( 'interpolated x=2.5 =',i.getValue(2.5)) print( 'extrapolated x=0.0 =',i.getValue(0.0)) print( 'extrapolated x=7.0 =',i.getValue(7)) print( '=' *55) # do rapid laser example from PPT file x = [2.,4.25,5.25,7.81,9.2,10.6] y = [7.2,7.1,6.,5.,3.5,5.] q = InterpProp( x, y, linear=1) xL = [] yL = [] dydxL = [] Npts = 100 for i in range(Npts+1): xL.append( 12.*i/Npts ) yL.append( q(xL[-1]) ) dydxL.append( q.deriv(xL[-1]) ) plt.plot(xL, yL, '-') plt.plot(xL, dydxL, '--') plt.plot( q.x, q.y, 'o-' ) plt.grid() plt.show()