qlang 0.0.27180000 → 0.0.27182000

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,426 @@
1
+ from __future__ import division, print_function, absolute_import
2
+
3
+ __all__ = ['fixed_quad','quadrature','romberg','trapz','simps','romb',
4
+ 'cumtrapz','newton_cotes']
5
+
6
+ from scipy.special.orthogonal import p_roots
7
+ from scipy.special import gammaln
8
+ from numpy import sum, ones, add, diff, isinf, isscalar, \
9
+ asarray, real, trapz, arange, empty
10
+ import numpy as np
11
+ import math
12
+ import warnings
13
+
14
+ from scipy.lib.six import xrange
15
+
16
+
17
+ class AccuracyWarning(Warning):
18
+ pass
19
+
20
+
21
+ def _cached_p_roots(n):
22
+
23
+ if n in _cached_p_roots.cache:
24
+ return _cached_p_roots.cache[n]
25
+
26
+ _cached_p_roots.cache[n] = p_roots(n)
27
+ return _cached_p_roots.cache[n]
28
+ _cached_p_roots.cache = dict()
29
+
30
+
31
+ def fixed_quad(func,a,b,args=(),n=5):
32
+
33
+ [x,w] = _cached_p_roots(n)
34
+ x = real(x)
35
+ ainf, binf = map(isinf,(a,b))
36
+ if ainf or binf:
37
+ raise ValueError("Gaussian quadrature is only available for "
38
+ "finite limits.")
39
+ y = (b-a)*(x+1)/2.0 + a
40
+ return (b-a)/2.0*sum(w*func(y,*args),0), None
41
+
42
+
43
+ def vectorize1(func, args=(), vec_func=False):
44
+ if vec_func:
45
+ def vfunc(x):
46
+ return func(x, *args)
47
+ else:
48
+ def vfunc(x):
49
+ if isscalar(x):
50
+ return func(x, *args)
51
+ x = asarray(x)
52
+ # call with first point to get output type
53
+ y0 = func(x[0], *args)
54
+ n = len(x)
55
+ if hasattr(y0, 'dtype'):
56
+ output = empty((n,), dtype=y0.dtype)
57
+ else:
58
+ output = empty((n,), dtype=type(y0))
59
+ output[0] = y0
60
+ for i in xrange(1, n):
61
+ output[i] = func(x[i], *args)
62
+ return output
63
+ return vfunc
64
+
65
+
66
+ def quadrature(func, a, b, args=(), tol=1.49e-8, rtol=1.49e-8, maxiter=50,
67
+ vec_func=True, miniter=1):
68
+
69
+ if not isinstance(args, tuple):
70
+ args = (args,)
71
+ vfunc = vectorize1(func, args, vec_func=vec_func)
72
+ val = np.inf
73
+ err = np.inf
74
+ maxiter = max(miniter+1, maxiter)
75
+ for n in xrange(miniter, maxiter+1):
76
+ newval = fixed_quad(vfunc, a, b, (), n)[0]
77
+ err = abs(newval-val)
78
+ val = newval
79
+
80
+ if err < tol or err < rtol*abs(val):
81
+ break
82
+ else:
83
+ warnings.warn(
84
+ "maxiter (%d) exceeded. Latest difference = %e" % (maxiter, err),
85
+ AccuracyWarning)
86
+ return val, err
87
+
88
+
89
+ def tupleset(t, i, value):
90
+ l = list(t)
91
+ l[i] = value
92
+ return tuple(l)
93
+
94
+
95
+ def cumtrapz(y, x=None, dx=1.0, axis=-1, initial=None):
96
+ y = asarray(y)
97
+ if x is None:
98
+ d = dx
99
+ else:
100
+ x = asarray(x)
101
+ if x.ndim == 1:
102
+ d = diff(x)
103
+ # reshape to correct shape
104
+ shape = [1] * y.ndim
105
+ shape[axis] = -1
106
+ d = d.reshape(shape)
107
+ elif len(x.shape) != len(y.shape):
108
+ raise ValueError("If given, shape of x must be 1-d or the "
109
+ "same as y.")
110
+ else:
111
+ d = diff(x, axis=axis)
112
+
113
+ if d.shape[axis] != y.shape[axis] - 1:
114
+ raise ValueError("If given, length of x along axis must be the "
115
+ "same as y.")
116
+
117
+ nd = len(y.shape)
118
+ slice1 = tupleset((slice(None),)*nd, axis, slice(1, None))
119
+ slice2 = tupleset((slice(None),)*nd, axis, slice(None, -1))
120
+ res = add.accumulate(d * (y[slice1] + y[slice2]) / 2.0, axis)
121
+
122
+ if initial is not None:
123
+ if not np.isscalar(initial):
124
+ raise ValueError("`initial` parameter should be a scalar.")
125
+
126
+ shape = list(res.shape)
127
+ shape[axis] = 1
128
+ res = np.concatenate([np.ones(shape, dtype=res.dtype) * initial, res],
129
+ axis=axis)
130
+
131
+ return res
132
+
133
+
134
+ def _basic_simps(y,start,stop,x,dx,axis):
135
+ nd = len(y.shape)
136
+ if start is None:
137
+ start = 0
138
+ step = 2
139
+ all = (slice(None),)*nd
140
+ slice0 = tupleset(all, axis, slice(start, stop, step))
141
+ slice1 = tupleset(all, axis, slice(start+1, stop+1, step))
142
+ slice2 = tupleset(all, axis, slice(start+2, stop+2, step))
143
+
144
+ if x is None: # Even spaced Simpson's rule.
145
+ result = add.reduce(dx/3.0 * (y[slice0]+4*y[slice1]+y[slice2]),
146
+ axis)
147
+ else:
148
+ # Account for possibly different spacings.
149
+ # Simpson's rule changes a bit.
150
+ h = diff(x,axis=axis)
151
+ sl0 = tupleset(all, axis, slice(start, stop, step))
152
+ sl1 = tupleset(all, axis, slice(start+1, stop+1, step))
153
+ h0 = h[sl0]
154
+ h1 = h[sl1]
155
+ hsum = h0 + h1
156
+ hprod = h0 * h1
157
+ h0divh1 = h0 / h1
158
+ result = add.reduce(hsum/6.0*(y[slice0]*(2-1.0/h0divh1) +
159
+ y[slice1]*hsum*hsum/hprod +
160
+ y[slice2]*(2-h0divh1)),axis)
161
+ return result
162
+
163
+
164
+ def simps(y, x=None, dx=1, axis=-1, even='avg'):
165
+
166
+ y = asarray(y)
167
+ nd = len(y.shape)
168
+ N = y.shape[axis]
169
+ last_dx = dx
170
+ first_dx = dx
171
+ returnshape = 0
172
+ if x is not None:
173
+ x = asarray(x)
174
+ if len(x.shape) == 1:
175
+ shapex = ones(nd)
176
+ shapex[axis] = x.shape[0]
177
+ saveshape = x.shape
178
+ returnshape = 1
179
+ x = x.reshape(tuple(shapex))
180
+ elif len(x.shape) != len(y.shape):
181
+ raise ValueError("If given, shape of x must be 1-d or the "
182
+ "same as y.")
183
+ if x.shape[axis] != N:
184
+ raise ValueError("If given, length of x along axis must be the "
185
+ "same as y.")
186
+ if N % 2 == 0:
187
+ val = 0.0
188
+ result = 0.0
189
+ slice1 = (slice(None),)*nd
190
+ slice2 = (slice(None),)*nd
191
+ if even not in ['avg', 'last', 'first']:
192
+ raise ValueError("Parameter 'even' must be 'avg', 'last', or 'first'.")
193
+ # Compute using Simpson's rule on first intervals
194
+ if even in ['avg', 'first']:
195
+ slice1 = tupleset(slice1, axis, -1)
196
+ slice2 = tupleset(slice2, axis, -2)
197
+ if x is not None:
198
+ last_dx = x[slice1] - x[slice2]
199
+ val += 0.5*last_dx*(y[slice1]+y[slice2])
200
+ result = _basic_simps(y,0,N-3,x,dx,axis)
201
+ # Compute using Simpson's rule on last set of intervals
202
+ if even in ['avg', 'last']:
203
+ slice1 = tupleset(slice1, axis, 0)
204
+ slice2 = tupleset(slice2, axis, 1)
205
+ if x is not None:
206
+ first_dx = x[tuple(slice2)] - x[tuple(slice1)]
207
+ val += 0.5*first_dx*(y[slice2]+y[slice1])
208
+ result += _basic_simps(y,1,N-2,x,dx,axis)
209
+ if even == 'avg':
210
+ val /= 2.0
211
+ result /= 2.0
212
+ result = result + val
213
+ else:
214
+ result = _basic_simps(y,0,N-2,x,dx,axis)
215
+ if returnshape:
216
+ x = x.reshape(saveshape)
217
+ return result
218
+
219
+
220
+ def romb(y, dx=1.0, axis=-1, show=False):
221
+
222
+ y = asarray(y)
223
+ nd = len(y.shape)
224
+ Nsamps = y.shape[axis]
225
+ Ninterv = Nsamps-1
226
+ n = 1
227
+ k = 0
228
+ while n < Ninterv:
229
+ n <<= 1
230
+ k += 1
231
+ if n != Ninterv:
232
+ raise ValueError("Number of samples must be one plus a "
233
+ "non-negative power of 2.")
234
+
235
+ R = {}
236
+ all = (slice(None),) * nd
237
+ slice0 = tupleset(all, axis, 0)
238
+ slicem1 = tupleset(all, axis, -1)
239
+ h = Ninterv*asarray(dx)*1.0
240
+ R[(0,0)] = (y[slice0] + y[slicem1])/2.0*h
241
+ slice_R = all
242
+ start = stop = step = Ninterv
243
+ for i in range(1,k+1):
244
+ start >>= 1
245
+ slice_R = tupleset(slice_R, axis, slice(start,stop,step))
246
+ step >>= 1
247
+ R[(i,0)] = 0.5*(R[(i-1,0)] + h*add.reduce(y[slice_R],axis))
248
+ for j in range(1,i+1):
249
+ R[(i,j)] = R[(i,j-1)] + \
250
+ (R[(i,j-1)]-R[(i-1,j-1)]) / ((1 << (2*j))-1)
251
+ h = h / 2.0
252
+
253
+ if show:
254
+ if not isscalar(R[(0,0)]):
255
+ print("*** Printing table only supported for integrals" +
256
+ " of a single data set.")
257
+ else:
258
+ try:
259
+ precis = show[0]
260
+ except (TypeError, IndexError):
261
+ precis = 5
262
+ try:
263
+ width = show[1]
264
+ except (TypeError, IndexError):
265
+ width = 8
266
+ formstr = "%" + str(width) + '.' + str(precis)+'f'
267
+
268
+ print("\n Richardson Extrapolation Table for Romberg Integration ")
269
+ print("====================================================================")
270
+ for i in range(0,k+1):
271
+ for j in range(0,i+1):
272
+ print(formstr % R[(i,j)], end=' ')
273
+ print()
274
+ print("====================================================================\n")
275
+
276
+ return R[(k,k)]
277
+
278
+
279
+ def _difftrap(function, interval, numtraps):
280
+ if numtraps <= 0:
281
+ raise ValueError("numtraps must be > 0 in difftrap().")
282
+ elif numtraps == 1:
283
+ return 0.5*(function(interval[0])+function(interval[1]))
284
+ else:
285
+ numtosum = numtraps/2
286
+ h = float(interval[1]-interval[0])/numtosum
287
+ lox = interval[0] + 0.5 * h
288
+ points = lox + h * arange(0, numtosum)
289
+ s = sum(function(points),0)
290
+ return s
291
+
292
+
293
+ def _romberg_diff(b, c, k):
294
+
295
+ tmp = 4.0**k
296
+ return (tmp * c - b)/(tmp - 1.0)
297
+
298
+
299
+ def _printresmat(function, interval, resmat):
300
+ # Print the Romberg result matrix.
301
+ i = j = 0
302
+ print('Romberg integration of', repr(function), end=' ')
303
+ print('from', interval)
304
+ print('')
305
+ print('%6s %9s %9s' % ('Steps', 'StepSize', 'Results'))
306
+ for i in range(len(resmat)):
307
+ print('%6d %9f' % (2**i, (interval[1]-interval[0])/(2.**i)), end=' ')
308
+ for j in range(i+1):
309
+ print('%9f' % (resmat[i][j]), end=' ')
310
+ print('')
311
+ print('')
312
+ print('The final result is', resmat[i][j], end=' ')
313
+ print('after', 2**(len(resmat)-1)+1, 'function evaluations.')
314
+
315
+
316
+ def romberg(function, a, b, args=(), tol=1.48e-8, rtol=1.48e-8, show=False,
317
+ divmax=10, vec_func=False):
318
+ if isinf(a) or isinf(b):
319
+ raise ValueError("Romberg integration only available for finite limits.")
320
+ vfunc = vectorize1(function, args, vec_func=vec_func)
321
+ n = 1
322
+ interval = [a,b]
323
+ intrange = b-a
324
+ ordsum = _difftrap(vfunc, interval, n)
325
+ result = intrange * ordsum
326
+ resmat = [[result]]
327
+ err = np.inf
328
+ for i in xrange(1, divmax+1):
329
+ n = n * 2
330
+ ordsum = ordsum + _difftrap(vfunc, interval, n)
331
+ resmat.append([])
332
+ resmat[i].append(intrange * ordsum / n)
333
+ for k in range(i):
334
+ resmat[i].append(_romberg_diff(resmat[i-1][k], resmat[i][k], k+1))
335
+ result = resmat[i][i]
336
+ lastresult = resmat[i-1][i-1]
337
+
338
+ err = abs(result - lastresult)
339
+ if err < tol or err < rtol*abs(result):
340
+ break
341
+ else:
342
+ warnings.warn(
343
+ "divmax (%d) exceeded. Latest difference = %e" % (divmax, err),
344
+ AccuracyWarning)
345
+
346
+ if show:
347
+ _printresmat(vfunc, interval, resmat)
348
+ return result
349
+
350
+ _builtincoeffs = {
351
+ 1:(1,2,[1,1],-1,12),
352
+ 2:(1,3,[1,4,1],-1,90),
353
+ 3:(3,8,[1,3,3,1],-3,80),
354
+ 4:(2,45,[7,32,12,32,7],-8,945),
355
+ 5:(5,288,[19,75,50,50,75,19],-275,12096),
356
+ 6:(1,140,[41,216,27,272,27,216,41],-9,1400),
357
+ 7:(7,17280,[751,3577,1323,2989,2989,1323,3577,751],-8183,518400),
358
+ 8:(4,14175,[989,5888,-928,10496,-4540,10496,-928,5888,989],
359
+ -2368,467775),
360
+ 9:(9,89600,[2857,15741,1080,19344,5778,5778,19344,1080,
361
+ 15741,2857], -4671, 394240),
362
+ 10:(5,299376,[16067,106300,-48525,272400,-260550,427368,
363
+ -260550,272400,-48525,106300,16067],
364
+ -673175, 163459296),
365
+ 11:(11,87091200,[2171465,13486539,-3237113, 25226685,-9595542,
366
+ 15493566,15493566,-9595542,25226685,-3237113,
367
+ 13486539,2171465], -2224234463, 237758976000),
368
+ 12:(1, 5255250, [1364651,9903168,-7587864,35725120,-51491295,
369
+ 87516288,-87797136,87516288,-51491295,35725120,
370
+ -7587864,9903168,1364651], -3012, 875875),
371
+ 13:(13, 402361344000,[8181904909, 56280729661, -31268252574,
372
+ 156074417954,-151659573325,206683437987,
373
+ -43111992612,-43111992612,206683437987,
374
+ -151659573325,156074417954,-31268252574,
375
+ 56280729661,8181904909], -2639651053,
376
+ 344881152000),
377
+ 14:(7, 2501928000, [90241897,710986864,-770720657,3501442784,
378
+ -6625093363,12630121616,-16802270373,19534438464,
379
+ -16802270373,12630121616,-6625093363,3501442784,
380
+ -770720657,710986864,90241897], -3740727473,
381
+ 1275983280000)
382
+ }
383
+
384
+
385
+ def newton_cotes(rn, equal=0):
386
+ try:
387
+ N = len(rn)-1
388
+ if equal:
389
+ rn = np.arange(N+1)
390
+ elif np.all(np.diff(rn) == 1):
391
+ equal = 1
392
+ except:
393
+ N = rn
394
+ rn = np.arange(N+1)
395
+ equal = 1
396
+
397
+ if equal and N in _builtincoeffs:
398
+ na, da, vi, nb, db = _builtincoeffs[N]
399
+ return na*np.array(vi,float)/da, float(nb)/db
400
+
401
+ if (rn[0] != 0) or (rn[-1] != N):
402
+ raise ValueError("The sample positions must start at 0"
403
+ " and end at N")
404
+ yi = rn / float(N)
405
+ ti = 2.0*yi - 1
406
+ nvec = np.arange(0,N+1)
407
+ C = ti**nvec[:,np.newaxis]
408
+ Cinv = np.linalg.inv(C)
409
+ # improve precision of result
410
+ for i in range(2):
411
+ Cinv = 2*Cinv - Cinv.dot(C).dot(Cinv)
412
+ vec = 2.0 / (nvec[::2]+1)
413
+ ai = np.dot(Cinv[:,::2],vec) * N/2
414
+
415
+ if (N % 2 == 0) and equal:
416
+ BN = N/(N+3.)
417
+ power = N+2
418
+ else:
419
+ BN = N/(N+2.)
420
+ power = N+1
421
+
422
+ BN = BN - np.dot(yi**power, ai)
423
+ p1 = power+1
424
+ fac = power*math.log(N) - gammaln(p1)
425
+ fac = math.exp(fac)
426
+ return ai, BN*fac
@@ -0,0 +1,426 @@
1
+ from __future__ import division, print_function, absolute_import
2
+
3
+ __all__ = ['fixed_quad','quadrature','romberg','trapz','simps','romb',
4
+ 'cumtrapz','newton_cotes']
5
+
6
+ from scipy.special.orthogonal import p_roots
7
+ from scipy.special import gammaln
8
+ from numpy import sum, ones, add, diff, isinf, isscalar, \
9
+ asarray, real, trapz, arange, empty
10
+ import numpy as np
11
+ import math
12
+ import warnings
13
+
14
+ from scipy.lib.six import xrange
15
+
16
+
17
+ class AccuracyWarning(Warning):
18
+ pass
19
+
20
+
21
+ def _cached_p_roots(n):
22
+
23
+ if n in _cached_p_roots.cache:
24
+ return _cached_p_roots.cache[n]
25
+
26
+ _cached_p_roots.cache[n] = p_roots(n)
27
+ return _cached_p_roots.cache[n]
28
+ _cached_p_roots.cache = dict()
29
+
30
+
31
+ def fixed_quad(func,a,b,args=(),n=5):
32
+
33
+ [x,w] = _cached_p_roots(n)
34
+ x = real(x)
35
+ ainf, binf = map(isinf,(a,b))
36
+ if ainf or binf:
37
+ raise ValueError("Gaussian quadrature is only available for "
38
+ "finite limits.")
39
+ y = (b-a)*(x+1)/2.0 + a
40
+ return (b-a)/2.0*sum(w*func(y,*args),0), None
41
+
42
+
43
+ def vectorize1(func, args=(), vec_func=False):
44
+ if vec_func:
45
+ def vfunc(x):
46
+ return func(x, *args)
47
+ else:
48
+ def vfunc(x):
49
+ if isscalar(x):
50
+ return func(x, *args)
51
+ x = asarray(x)
52
+ # call with first point to get output type
53
+ y0 = func(x[0], *args)
54
+ n = len(x)
55
+ if hasattr(y0, 'dtype'):
56
+ output = empty((n,), dtype=y0.dtype)
57
+ else:
58
+ output = empty((n,), dtype=type(y0))
59
+ output[0] = y0
60
+ for i in xrange(1, n):
61
+ output[i] = func(x[i], *args)
62
+ return output
63
+ return vfunc
64
+
65
+
66
+ def quadrature(func, a, b, args=(), tol=1.49e-8, rtol=1.49e-8, maxiter=50,
67
+ vec_func=True, miniter=1):
68
+
69
+ if not isinstance(args, tuple):
70
+ args = (args,)
71
+ vfunc = vectorize1(func, args, vec_func=vec_func)
72
+ val = np.inf
73
+ err = np.inf
74
+ maxiter = max(miniter+1, maxiter)
75
+ for n in xrange(miniter, maxiter+1):
76
+ newval = fixed_quad(vfunc, a, b, (), n)[0]
77
+ err = abs(newval-val)
78
+ val = newval
79
+
80
+ if err < tol or err < rtol*abs(val):
81
+ break
82
+ else:
83
+ warnings.warn(
84
+ "maxiter (%d) exceeded. Latest difference = %e" % (maxiter, err),
85
+ AccuracyWarning)
86
+ return val, err
87
+
88
+
89
+ def tupleset(t, i, value):
90
+ l = list(t)
91
+ l[i] = value
92
+ return tuple(l)
93
+
94
+
95
+ def cumtrapz(y, x=None, dx=1.0, axis=-1, initial=None):
96
+ y = asarray(y)
97
+ if x is None:
98
+ d = dx
99
+ else:
100
+ x = asarray(x)
101
+ if x.ndim == 1:
102
+ d = diff(x)
103
+ # reshape to correct shape
104
+ shape = [1] * y.ndim
105
+ shape[axis] = -1
106
+ d = d.reshape(shape)
107
+ elif len(x.shape) != len(y.shape):
108
+ raise ValueError("If given, shape of x must be 1-d or the "
109
+ "same as y.")
110
+ else:
111
+ d = diff(x, axis=axis)
112
+
113
+ if d.shape[axis] != y.shape[axis] - 1:
114
+ raise ValueError("If given, length of x along axis must be the "
115
+ "same as y.")
116
+
117
+ nd = len(y.shape)
118
+ slice1 = tupleset((slice(None),)*nd, axis, slice(1, None))
119
+ slice2 = tupleset((slice(None),)*nd, axis, slice(None, -1))
120
+ res = add.accumulate(d * (y[slice1] + y[slice2]) / 2.0, axis)
121
+
122
+ if initial is not None:
123
+ if not np.isscalar(initial):
124
+ raise ValueError("`initial` parameter should be a scalar.")
125
+
126
+ shape = list(res.shape)
127
+ shape[axis] = 1
128
+ res = np.concatenate([np.ones(shape, dtype=res.dtype) * initial, res],
129
+ axis=axis)
130
+
131
+ return res
132
+
133
+
134
+ def _basic_simps(y,start,stop,x,dx,axis):
135
+ nd = len(y.shape)
136
+ if start is None:
137
+ start = 0
138
+ step = 2
139
+ all = (slice(None),)*nd
140
+ slice0 = tupleset(all, axis, slice(start, stop, step))
141
+ slice1 = tupleset(all, axis, slice(start+1, stop+1, step))
142
+ slice2 = tupleset(all, axis, slice(start+2, stop+2, step))
143
+
144
+ if x is None: # Even spaced Simpson's rule.
145
+ result = add.reduce(dx/3.0 * (y[slice0]+4*y[slice1]+y[slice2]),
146
+ axis)
147
+ else:
148
+ # Account for possibly different spacings.
149
+ # Simpson's rule changes a bit.
150
+ h = diff(x,axis=axis)
151
+ sl0 = tupleset(all, axis, slice(start, stop, step))
152
+ sl1 = tupleset(all, axis, slice(start+1, stop+1, step))
153
+ h0 = h[sl0]
154
+ h1 = h[sl1]
155
+ hsum = h0 + h1
156
+ hprod = h0 * h1
157
+ h0divh1 = h0 / h1
158
+ result = add.reduce(hsum/6.0*(y[slice0]*(2-1.0/h0divh1) +
159
+ y[slice1]*hsum*hsum/hprod +
160
+ y[slice2]*(2-h0divh1)),axis)
161
+ return result
162
+
163
+
164
+ def simps(y, x=None, dx=1, axis=-1, even='avg'):
165
+
166
+ y = asarray(y)
167
+ nd = len(y.shape)
168
+ N = y.shape[axis]
169
+ last_dx = dx
170
+ first_dx = dx
171
+ returnshape = 0
172
+ if x is not None:
173
+ x = asarray(x)
174
+ if len(x.shape) == 1:
175
+ shapex = ones(nd)
176
+ shapex[axis] = x.shape[0]
177
+ saveshape = x.shape
178
+ returnshape = 1
179
+ x = x.reshape(tuple(shapex))
180
+ elif len(x.shape) != len(y.shape):
181
+ raise ValueError("If given, shape of x must be 1-d or the "
182
+ "same as y.")
183
+ if x.shape[axis] != N:
184
+ raise ValueError("If given, length of x along axis must be the "
185
+ "same as y.")
186
+ if N % 2 == 0:
187
+ val = 0.0
188
+ result = 0.0
189
+ slice1 = (slice(None),)*nd
190
+ slice2 = (slice(None),)*nd
191
+ if even not in ['avg', 'last', 'first']:
192
+ raise ValueError("Parameter 'even' must be 'avg', 'last', or 'first'.")
193
+ # Compute using Simpson's rule on first intervals
194
+ if even in ['avg', 'first']:
195
+ slice1 = tupleset(slice1, axis, -1)
196
+ slice2 = tupleset(slice2, axis, -2)
197
+ if x is not None:
198
+ last_dx = x[slice1] - x[slice2]
199
+ val += 0.5*last_dx*(y[slice1]+y[slice2])
200
+ result = _basic_simps(y,0,N-3,x,dx,axis)
201
+ # Compute using Simpson's rule on last set of intervals
202
+ if even in ['avg', 'last']:
203
+ slice1 = tupleset(slice1, axis, 0)
204
+ slice2 = tupleset(slice2, axis, 1)
205
+ if x is not None:
206
+ first_dx = x[tuple(slice2)] - x[tuple(slice1)]
207
+ val += 0.5*first_dx*(y[slice2]+y[slice1])
208
+ result += _basic_simps(y,1,N-2,x,dx,axis)
209
+ if even == 'avg':
210
+ val /= 2.0
211
+ result /= 2.0
212
+ result = result + val
213
+ else:
214
+ result = _basic_simps(y,0,N-2,x,dx,axis)
215
+ if returnshape:
216
+ x = x.reshape(saveshape)
217
+ return result
218
+
219
+
220
+ def romb(y, dx=1.0, axis=-1, show=False):
221
+
222
+ y = asarray(y)
223
+ nd = len(y.shape)
224
+ Nsamps = y.shape[axis]
225
+ Ninterv = Nsamps-1
226
+ n = 1
227
+ k = 0
228
+ while n < Ninterv:
229
+ n <<= 1
230
+ k += 1
231
+ if n != Ninterv:
232
+ raise ValueError("Number of samples must be one plus a "
233
+ "non-negative power of 2.")
234
+
235
+ R = {}
236
+ all = (slice(None),) * nd
237
+ slice0 = tupleset(all, axis, 0)
238
+ slicem1 = tupleset(all, axis, -1)
239
+ h = Ninterv*asarray(dx)*1.0
240
+ R[(0,0)] = (y[slice0] + y[slicem1])/2.0*h
241
+ slice_R = all
242
+ start = stop = step = Ninterv
243
+ for i in range(1,k+1):
244
+ start >>= 1
245
+ slice_R = tupleset(slice_R, axis, slice(start,stop,step))
246
+ step >>= 1
247
+ R[(i,0)] = 0.5*(R[(i-1,0)] + h*add.reduce(y[slice_R],axis))
248
+ for j in range(1,i+1):
249
+ R[(i,j)] = R[(i,j-1)] + \
250
+ (R[(i,j-1)]-R[(i-1,j-1)]) / ((1 << (2*j))-1)
251
+ h = h / 2.0
252
+
253
+ if show:
254
+ if not isscalar(R[(0,0)]):
255
+ print("*** Printing table only supported for integrals" +
256
+ " of a single data set.")
257
+ else:
258
+ try:
259
+ precis = show[0]
260
+ except (TypeError, IndexError):
261
+ precis = 5
262
+ try:
263
+ width = show[1]
264
+ except (TypeError, IndexError):
265
+ width = 8
266
+ formstr = "%" + str(width) + '.' + str(precis)+'f'
267
+
268
+ print("\n Richardson Extrapolation Table for Romberg Integration ")
269
+ print("====================================================================")
270
+ for i in range(0,k+1):
271
+ for j in range(0,i+1):
272
+ print(formstr % R[(i,j)], end=' ')
273
+ print()
274
+ print("====================================================================\n")
275
+
276
+ return R[(k,k)]
277
+
278
+
279
+ def _difftrap(function, interval, numtraps):
280
+ if numtraps <= 0:
281
+ raise ValueError("numtraps must be > 0 in difftrap().")
282
+ elif numtraps == 1:
283
+ return 0.5*(function(interval[0])+function(interval[1]))
284
+ else:
285
+ numtosum = numtraps/2
286
+ h = float(interval[1]-interval[0])/numtosum
287
+ lox = interval[0] + 0.5 * h
288
+ points = lox + h * arange(0, numtosum)
289
+ s = sum(function(points),0)
290
+ return s
291
+
292
+
293
+ def _romberg_diff(b, c, k):
294
+
295
+ tmp = 4.0**k
296
+ return (tmp * c - b)/(tmp - 1.0)
297
+
298
+
299
+ def _printresmat(function, interval, resmat):
300
+ # Print the Romberg result matrix.
301
+ i = j = 0
302
+ print('Romberg integration of', repr(function), end=' ')
303
+ print('from', interval)
304
+ print('')
305
+ print('%6s %9s %9s' % ('Steps', 'StepSize', 'Results'))
306
+ for i in range(len(resmat)):
307
+ print('%6d %9f' % (2**i, (interval[1]-interval[0])/(2.**i)), end=' ')
308
+ for j in range(i+1):
309
+ print('%9f' % (resmat[i][j]), end=' ')
310
+ print('')
311
+ print('')
312
+ print('The final result is', resmat[i][j], end=' ')
313
+ print('after', 2**(len(resmat)-1)+1, 'function evaluations.')
314
+
315
+
316
+ def romberg(function, a, b, args=(), tol=1.48e-8, rtol=1.48e-8, show=False,
317
+ divmax=10, vec_func=False):
318
+ if isinf(a) or isinf(b):
319
+ raise ValueError("Romberg integration only available for finite limits.")
320
+ vfunc = vectorize1(function, args, vec_func=vec_func)
321
+ n = 1
322
+ interval = [a,b]
323
+ intrange = b-a
324
+ ordsum = _difftrap(vfunc, interval, n)
325
+ result = intrange * ordsum
326
+ resmat = [[result]]
327
+ err = np.inf
328
+ for i in xrange(1, divmax+1):
329
+ n = n * 2
330
+ ordsum = ordsum + _difftrap(vfunc, interval, n)
331
+ resmat.append([])
332
+ resmat[i].append(intrange * ordsum / n)
333
+ for k in range(i):
334
+ resmat[i].append(_romberg_diff(resmat[i-1][k], resmat[i][k], k+1))
335
+ result = resmat[i][i]
336
+ lastresult = resmat[i-1][i-1]
337
+
338
+ err = abs(result - lastresult)
339
+ if err < tol or err < rtol*abs(result):
340
+ break
341
+ else:
342
+ warnings.warn(
343
+ "divmax (%d) exceeded. Latest difference = %e" % (divmax, err),
344
+ AccuracyWarning)
345
+
346
+ if show:
347
+ _printresmat(vfunc, interval, resmat)
348
+ return result
349
+
350
+ _builtincoeffs = {
351
+ 1:(1,2,[1,1],-1,12),
352
+ 2:(1,3,[1,4,1],-1,90),
353
+ 3:(3,8,[1,3,3,1],-3,80),
354
+ 4:(2,45,[7,32,12,32,7],-8,945),
355
+ 5:(5,288,[19,75,50,50,75,19],-275,12096),
356
+ 6:(1,140,[41,216,27,272,27,216,41],-9,1400),
357
+ 7:(7,17280,[751,3577,1323,2989,2989,1323,3577,751],-8183,518400),
358
+ 8:(4,14175,[989,5888,-928,10496,-4540,10496,-928,5888,989],
359
+ -2368,467775),
360
+ 9:(9,89600,[2857,15741,1080,19344,5778,5778,19344,1080,
361
+ 15741,2857], -4671, 394240),
362
+ 10:(5,299376,[16067,106300,-48525,272400,-260550,427368,
363
+ -260550,272400,-48525,106300,16067],
364
+ -673175, 163459296),
365
+ 11:(11,87091200,[2171465,13486539,-3237113, 25226685,-9595542,
366
+ 15493566,15493566,-9595542,25226685,-3237113,
367
+ 13486539,2171465], -2224234463, 237758976000),
368
+ 12:(1, 5255250, [1364651,9903168,-7587864,35725120,-51491295,
369
+ 87516288,-87797136,87516288,-51491295,35725120,
370
+ -7587864,9903168,1364651], -3012, 875875),
371
+ 13:(13, 402361344000,[8181904909, 56280729661, -31268252574,
372
+ 156074417954,-151659573325,206683437987,
373
+ -43111992612,-43111992612,206683437987,
374
+ -151659573325,156074417954,-31268252574,
375
+ 56280729661,8181904909], -2639651053,
376
+ 344881152000),
377
+ 14:(7, 2501928000, [90241897,710986864,-770720657,3501442784,
378
+ -6625093363,12630121616,-16802270373,19534438464,
379
+ -16802270373,12630121616,-6625093363,3501442784,
380
+ -770720657,710986864,90241897], -3740727473,
381
+ 1275983280000)
382
+ }
383
+
384
+
385
+ def newton_cotes(rn, equal=0):
386
+ try:
387
+ N = len(rn)-1
388
+ if equal:
389
+ rn = np.arange(N+1)
390
+ elif np.all(np.diff(rn) == 1):
391
+ equal = 1
392
+ except:
393
+ N = rn
394
+ rn = np.arange(N+1)
395
+ equal = 1
396
+
397
+ if equal and N in _builtincoeffs:
398
+ na, da, vi, nb, db = _builtincoeffs[N]
399
+ return na*np.array(vi,float)/da, float(nb)/db
400
+
401
+ if (rn[0] != 0) or (rn[-1] != N):
402
+ raise ValueError("The sample positions must start at 0"
403
+ " and end at N")
404
+ yi = rn / float(N)
405
+ ti = 2.0*yi - 1
406
+ nvec = np.arange(0,N+1)
407
+ C = ti**nvec[:,np.newaxis]
408
+ Cinv = np.linalg.inv(C)
409
+ # improve precision of result
410
+ for i in range(2):
411
+ Cinv = 2*Cinv - Cinv.dot(C).dot(Cinv)
412
+ vec = 2.0 / (nvec[::2]+1)
413
+ ai = np.dot(Cinv[:,::2],vec) * N/2
414
+
415
+ if (N % 2 == 0) and equal:
416
+ BN = N/(N+3.)
417
+ power = N+2
418
+ else:
419
+ BN = N/(N+2.)
420
+ power = N+1
421
+
422
+ BN = BN - np.dot(yi**power, ai)
423
+ p1 = power+1
424
+ fac = power*math.log(N) - gammaln(p1)
425
+ fac = math.exp(fac)
426
+ return ai, BN*fac