def ramp2d( xMin, xMax, down = 0 ) : """Returns an endl2dmath instance of a ramp from xMin to xMax with height 0 at xMin and 1 at xMax if down = 0, and 1 at xMin and 0 at xMax otherwise.""" if( xMin >= xMax ) : raise Exception( "\nError in ramp2d: xMin >= xMax" ) if( down != 0 ) : return endl2dmathClasses.endl2dmath( [ [ xMin, 1. ], [ xMax, 0. ] ], checkDataType = 0 ) else : return endl2dmathClasses.endl2dmath( [ [ xMin, 0. ], [ xMax, 1. ] ], checkDataType = 0 )
def flattop2d(xMin, xMax): """Returns an endl2dmath instance of a flattop from xMin to xMax with height 1. 0 < xMin < xMax.""" if (xMin >= xMax): raise Exception("\nError in flattop2d: ( xMin < 0 ) or xMin >= xMax") return endl2dmathClasses.endl2dmath([[xMin, 1.], [xMax, 1.]], checkDataType=0)
def triangle2d( x0, x1, x2 ) : """Returns an endl2dmath instance of a triangle that starts at x0 with height 0, ramps up to 1 at x1 and ramps down to 0 at x2.""" if( ( x0 > x1 ) or ( x1 > x2 ) ) : raise Exception( "\nError in triangle2d: triangle points must have x0 <= x1 <= x2" ) return endl2dmathClasses.endl2dmath( [ [ x0, 0. ], [ x1, 1. ], [ x2, 0. ] ], checkDataType = 0 )
def convertFunctionToLinLin( f, xMin, xMax, accuracy ): ''' Returns a new endl2dmath object that represents the function f(x) as a lin-lin table to the specified absolute accuracy on the interval xMin to xMax. ''' def convertFunctionToLinLin2( f, xMin, yMin, xMax, yMax, accuracy, data, level ) : if( level > 16 ) : return xMid, yMid = 0.5 * ( xMin + xMax ), 0.5 * ( yMin + yMax ) y = f( xMid ) if( abs( yMid - y ) > abs( y * accuracy ) ) : convertFunctionToLinLin2( f, xMin, yMin, xMid, y, accuracy, data, level + 1 ) data.append( [ xMid, y ] ) convertFunctionToLinLin2( f, xMid, y, xMax, yMax, accuracy, data, level + 1 ) data = [ [ xMin, f( xMin ) ] ] convertFunctionToLinLin2( f, xMin, data[0][1], xMax, f( xMax ), accuracy, data, 0 ) data.append( [ xMax, f( xMax ) ] ) return( endl2dmathClasses.endl2dmath( data = data ) )
def interpolate3d(x, data, unitBase=False, extrapolation=noExtrapolation, endl2dmathObject=False): """Returns the interpolation of data (an endl3dmath object or suitable data) at x as a list of [y,z] pairs. If x is outside the domain of data, then [] is returned. If x is one of the x-values of data, then its yz-data is returned. Otherwise, for xl < x < xu where xl and xu are consecutive x-values in data linear interpolation is performed on the yz data of xl and xu. If unitBase is True, then unit base interpolation is performed.""" points = get3dmathData(data, "endl3dmathmisc.interpolate3d", "") ubiData = [] if (len(points) > 0): if (x < points[0][0]): if (extrapolation == flatExtrapolation): ubiData = [[y, z] for y, z in points[0][1]] elif (points[-1][0] < x): if (extrapolation == flatExtrapolation): ubiData = [[y, z] for y, z in points[-1][1]] else: i = 0 for x_, yz in points: if (x <= x_): break i += 1 data_u = points[i] xu = data_u[0] u = data_u[1] if (xu == x): for y, z in u: ubiData.append([y, z]) else: # Note, if xl == xu or i is the last element in data we would not be here. data_l = points[i - 1] xl = data_l[0] l = data_l[1] f = (xu - x) / (xu - xl) g = 1. - f if (unitBase and ((l[0][0] != u[0][0]) or (l[-1][0] != u[-1][0]))): unitBase = True yl = (f * l[0][0] + g * u[0][0]) yu = (f * l[-1][0] + g * u[-1][0]) s = (yu - yl) / (l[-1][0] - l[0][0]) lp = [] y0 = l[0][0] for y, z in l: lp.append([s * (y - y0) + yl, z / s]) l = lp s = (yu - yl) / (u[-1][0] - u[0][0]) up = [] y0 = u[0][0] for y, z in u: up.append([s * (y - y0) + yl, z / s]) up[-1][0] = lp[-1][ 0] # Make sure the last x values are the same. u = up l = endl2dmathClasses.endl2dmath(data=l, checkDataType=False) u = endl2dmathClasses.endl2dmath(data=u, checkDataType=False) if (not unitBase): l = l.copyData() u = u.copyData() if ((l.data[0][0] < u.data[0][0]) and (l.data[0][1] != 0.)): v = (1.0 - 1e-6) * u.data[0][0] if (v == 0.): v = -1e-12 u.data.insert(0, [v, 0.]) elif ((l.data[0][0] > u.data[0][0]) and (u.data[0][1] != 0.)): v = (1.0 - 1e-6) * l.data[0][0] if (v == 0.): v = -1e-12 l.data.insert(0, [v, 0.]) if ((l.data[-1][0] < u.data[-1][0]) and (l.data[-1][1] != 0.)): v = (1.0 + 1e-6) * l.data[-1][0] if (v == 0.): v = 1e-12 l.data.append([v, 0.]) elif ((l.data[-1][0] > u.data[-1][0]) and (u.data[-1][1] != 0.)): v = (1.0 + 1e-6) * u.data[-1][0] if (v == 0.): v = 1e-12 u.data.append([v, 0.]) ubiData = f * l + g * u ubiData = ubiData.data if (endl2dmathObject): ubiData = endl2dmathClasses.endl2dmath(ubiData) return (ubiData)
def point2d(x): "Returns an endl2dmath instance of [ x, 1. ]." return endl2dmathClasses.endl2dmath([[x, 1.]], checkDataType=0)
def gauss2d(xc, xw, f=1e-3, xsigmax=4, xMin=None, xMax=None): """Returns an endl2dmath instance the has a Gaussian shape centered at xc with width xw (i.e., Exp( -( (x - xc) / xw )^2 / 2 ). The points are generated such that linear interpolation is accurate to f. The x value's range is limited by xMin, xMax and abs(x - xc) / xw <= xsigmax.""" def addpoints(xmin, xmax, x, a, f, DoPoints): fs = 1. if (x > 1.): fs = -1. y = (1. + fs * f) * math.exp(-x * x / 2.) xl = -x yl = y if (DoPoints[0]): if (xl < xmin): DoPoints[0] = 0 if (len(a) > 0): yl = ((xmin - a[0][0]) * yl + (xl - xmin) * a[0][1]) / float(xl - a[0][0]) xl = xmin if (xl >= xmin): a.insert(0, [xl, yl]) if (DoPoints[1]): if (x > xmax): DoPoints[1] = 0 if (len(a) > 0): y = ((xmax - a[-1][0]) * y + (x - xmax) * a[-1][1]) / float(x - a[-1][0]) x = xmax if (x <= xmax): a.append([x, y]) def nextpoint(xs_, xe_, f): xs = xs_ xe = xe_ fs = -1 if (xs < 1): fs = 1 x1 = xs y1 = math.exp(-x1 * x1 / 2.) for i in range(40): x = (xs + xe) / 2. if (xe - x < 1e-14 * x): break s = (math.exp((x1 - x) * (x1 + x) / 2.) - 1.) / (x - x1) z = 0.5 * (-1. / s + x1) xr = z - fs * math.sqrt(z * z - 1) r = 1. - (s * (xr - x1) + 1.) * y1 * math.exp(xr * xr / 2.) if (fs * r < 2. * f): xs = x else: xe = x return x f = max(min(1e-2, f), 1e-8) if (xMin == None): xmin = -xsigmax else: xmin = (xMin - xc) / float(xw) if (xMax == None): xmax = xsigmax else: xmax = (xMax - xc) / float(xw) if (xmin < 0) and (xmin < -xsigmax): xmin = -xsigmax if (xsigmax < xmax): xmax = xsigmax if (xmin <= 0) and (xmax >= 0): xamin = 0 else: xamin = min(abs(xmin), abs(xmax)) xamax = max(abs(xmin), abs(xmax)) DoPoints = [1, 1] a = [] if (xamin != 0.): # The curve does not go through x = 0. addpoints(xmin, xmax, xamin, a, f, DoPoints) x1 = xamin else: a.append([0., 1.]) # The center and the next point. s = math.sqrt(2. * (math.sqrt(1. + 6. * f) - 1.) / 3.) x0 = 2. * s / (1. - s * s) s = (math.exp(-x0 * x0 / 2.) - 1.) / x0 c = s * (s * x0 + 1.) b = x0 + c c = x0 * x0 / 2. + c * x0 + 0.5 e = (-b + math.sqrt(b * b + 4. * f * c)) / (2. * c) x1 = x0 + e addpoints(xmin, xmax, x1, a, f, DoPoints) e = pow(3. * f / 2., 1. / 3.) # Treat the points around x = 1 as special. e = pow(3. * f / 2. / (1. - 9. * e / 8. + 63. * e * e / 40.), 2. / 3.) xs = 0. xe = 1. for i in range(40): x = (xs + xe) / 2. if (xe - x < 1e-14 * x): break d = 1. - math.exp((x * x - 1.) / 2.) * (1. - (1. - e) * (x - 1.)) + f if (d < 0.): xs = x else: xe = x x = 1. - .9 * (1 - x) x1m = x # Point < 1. x1p = 1. + (1. - x) # Point > 1. x = x1 if (x < x1m): while (x < 1.): xs = x x = nextpoint(xs, x1m, f) if (abs(x1m - x) < 1e-2 * (x - xs)): break addpoints(xmin, xmax, x, a, f, DoPoints) if (x < x1m): addpoints(xmin, xmax, x1m, a, f, DoPoints) x = x1m if (x < x1p): addpoints(xmin, xmax, x1p, a, f, DoPoints) x = x1p while (x < xamax): x = nextpoint(x, xamax + 1, f) addpoints(xmin, xmax, x, a, f, DoPoints) for e in a: e[0] = e[0] * xw + xc return endl2dmathClasses.endl2dmath(a, checkDataType=0)
# <<END-copyright>> """ This file compares the results of evaluate from an endl2dmathClasses.endl2dmath and pointwiseXY_C instances for the same data at random x values. If a relative difference greater than eps is found an error is printed. This should be repeatable. """ import sys sys.path.append('../../../lib') import time import random import endl2dmathClasses, endlmisc import pointwiseXY_C eps = sys.float_info.epsilon data = endl2dmathClasses.endl2dmath(endlmisc.read2dDataFile('Data/t3.py.in')) f = pointwiseXY_C.pointwiseXY_C(initialSize=40, overflowSize=10) t0 = time.clock() f.setData(data.data) print '# time =', time.clock() - t0 print 'len( data ) =', len(data) print 'len( f ) =', len(f) random.seed(314159) n = 10000 np = n / 10 xMin, xMax = data.domainMin(), data.domainMax() r = random.random() x = xMin * r + xMax * (1. - r) print '# time =', time.clock() - t0