Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/polynomial/polytemplate.py @ 87:2a2c65a20a8b
Add Python libs and headers
author | Chris Cannam |
---|---|
date | Wed, 25 Feb 2015 14:05:22 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
86:413a9d26189e | 87:2a2c65a20a8b |
---|---|
1 """ | |
2 Template for the Chebyshev and Polynomial classes. | |
3 | |
4 This module houses a Python string module Template object (see, e.g., | |
5 http://docs.python.org/library/string.html#template-strings) used by | |
6 the `polynomial` and `chebyshev` modules to implement their respective | |
7 `Polynomial` and `Chebyshev` classes. It provides a mechanism for easily | |
8 creating additional specific polynomial classes (e.g., Legendre, Jacobi, | |
9 etc.) in the future, such that all these classes will have a common API. | |
10 | |
11 """ | |
12 from __future__ import division, absolute_import, print_function | |
13 | |
14 import string | |
15 import sys | |
16 import warnings | |
17 from number import Number | |
18 | |
19 from numpy import ModuleDeprecationWarning | |
20 | |
21 warnings.warn("The polytemplate module will be removed in Numpy 1.10.0.", | |
22 ModuleDeprecationWarning) | |
23 | |
24 polytemplate = string.Template(''' | |
25 from __future__ import division, absolute_import, print_function | |
26 import numpy as np | |
27 import warnings | |
28 from . import polyutils as pu | |
29 | |
30 class $name(pu.PolyBase) : | |
31 """A $name series class. | |
32 | |
33 $name instances provide the standard Python numerical methods '+', | |
34 '-', '*', '//', '%', 'divmod', '**', and '()' as well as the listed | |
35 methods. | |
36 | |
37 Parameters | |
38 ---------- | |
39 coef : array_like | |
40 $name coefficients, in increasing order. For example, | |
41 ``(1, 2, 3)`` implies ``P_0 + 2P_1 + 3P_2`` where the | |
42 ``P_i`` are a graded polynomial basis. | |
43 domain : (2,) array_like, optional | |
44 Domain to use. The interval ``[domain[0], domain[1]]`` is mapped to | |
45 the interval ``[window[0], window[1]]`` by shifting and scaling. | |
46 The default value is $domain. | |
47 window : (2,) array_like, optional | |
48 Window, see ``domain`` for its use. The default value is $domain. | |
49 .. versionadded:: 1.6.0 | |
50 | |
51 Attributes | |
52 ---------- | |
53 coef : (N,) ndarray | |
54 $name coefficients, from low to high. | |
55 domain : (2,) ndarray | |
56 Domain that is mapped to ``window``. | |
57 window : (2,) ndarray | |
58 Window that ``domain`` is mapped to. | |
59 | |
60 Class Attributes | |
61 ---------------- | |
62 maxpower : int | |
63 Maximum power allowed, i.e., the largest number ``n`` such that | |
64 ``p(x)**n`` is allowed. This is to limit runaway polynomial size. | |
65 domain : (2,) ndarray | |
66 Default domain of the class. | |
67 window : (2,) ndarray | |
68 Default window of the class. | |
69 | |
70 Notes | |
71 ----- | |
72 It is important to specify the domain in many cases, for instance in | |
73 fitting data, because many of the important properties of the | |
74 polynomial basis only hold in a specified interval and consequently | |
75 the data must be mapped into that interval in order to benefit. | |
76 | |
77 Examples | |
78 -------- | |
79 | |
80 """ | |
81 # Limit runaway size. T_n^m has degree n*2^m | |
82 maxpower = 16 | |
83 # Default domain | |
84 domain = np.array($domain) | |
85 # Default window | |
86 window = np.array($domain) | |
87 # Don't let participate in array operations. Value doesn't matter. | |
88 __array_priority__ = 1000 | |
89 # Not hashable | |
90 __hash__ = None | |
91 | |
92 def has_samecoef(self, other): | |
93 """Check if coefficients match. | |
94 | |
95 Parameters | |
96 ---------- | |
97 other : class instance | |
98 The other class must have the ``coef`` attribute. | |
99 | |
100 Returns | |
101 ------- | |
102 bool : boolean | |
103 True if the coefficients are the same, False otherwise. | |
104 | |
105 Notes | |
106 ----- | |
107 .. versionadded:: 1.6.0 | |
108 | |
109 """ | |
110 if len(self.coef) != len(other.coef): | |
111 return False | |
112 elif not np.all(self.coef == other.coef): | |
113 return False | |
114 else: | |
115 return True | |
116 | |
117 def has_samedomain(self, other): | |
118 """Check if domains match. | |
119 | |
120 Parameters | |
121 ---------- | |
122 other : class instance | |
123 The other class must have the ``domain`` attribute. | |
124 | |
125 Returns | |
126 ------- | |
127 bool : boolean | |
128 True if the domains are the same, False otherwise. | |
129 | |
130 Notes | |
131 ----- | |
132 .. versionadded:: 1.6.0 | |
133 | |
134 """ | |
135 return np.all(self.domain == other.domain) | |
136 | |
137 def has_samewindow(self, other): | |
138 """Check if windows match. | |
139 | |
140 Parameters | |
141 ---------- | |
142 other : class instance | |
143 The other class must have the ``window`` attribute. | |
144 | |
145 Returns | |
146 ------- | |
147 bool : boolean | |
148 True if the windows are the same, False otherwise. | |
149 | |
150 Notes | |
151 ----- | |
152 .. versionadded:: 1.6.0 | |
153 | |
154 """ | |
155 return np.all(self.window == other.window) | |
156 | |
157 def has_sametype(self, other): | |
158 """Check if types match. | |
159 | |
160 Parameters | |
161 ---------- | |
162 other : object | |
163 Class instance. | |
164 | |
165 Returns | |
166 ------- | |
167 bool : boolean | |
168 True if other is same class as self | |
169 | |
170 Notes | |
171 ----- | |
172 .. versionadded:: 1.7.0 | |
173 | |
174 """ | |
175 return isinstance(other, self.__class__) | |
176 | |
177 def __init__(self, coef, domain=$domain, window=$domain) : | |
178 [coef, dom, win] = pu.as_series([coef, domain, window], trim=False) | |
179 if len(dom) != 2 : | |
180 raise ValueError("Domain has wrong number of elements.") | |
181 if len(win) != 2 : | |
182 raise ValueError("Window has wrong number of elements.") | |
183 self.coef = coef | |
184 self.domain = dom | |
185 self.window = win | |
186 | |
187 def __repr__(self): | |
188 format = "%s(%s, %s, %s)" | |
189 coef = repr(self.coef)[6:-1] | |
190 domain = repr(self.domain)[6:-1] | |
191 window = repr(self.window)[6:-1] | |
192 return format % ('$name', coef, domain, window) | |
193 | |
194 def __str__(self) : | |
195 format = "%s(%s)" | |
196 coef = str(self.coef) | |
197 return format % ('$nick', coef) | |
198 | |
199 # Pickle and copy | |
200 | |
201 def __getstate__(self) : | |
202 ret = self.__dict__.copy() | |
203 ret['coef'] = self.coef.copy() | |
204 ret['domain'] = self.domain.copy() | |
205 ret['window'] = self.window.copy() | |
206 return ret | |
207 | |
208 def __setstate__(self, dict) : | |
209 self.__dict__ = dict | |
210 | |
211 # Call | |
212 | |
213 def __call__(self, arg) : | |
214 off, scl = pu.mapparms(self.domain, self.window) | |
215 arg = off + scl*arg | |
216 return ${nick}val(arg, self.coef) | |
217 | |
218 def __iter__(self) : | |
219 return iter(self.coef) | |
220 | |
221 def __len__(self) : | |
222 return len(self.coef) | |
223 | |
224 # Numeric properties. | |
225 | |
226 def __neg__(self) : | |
227 return self.__class__(-self.coef, self.domain, self.window) | |
228 | |
229 def __pos__(self) : | |
230 return self | |
231 | |
232 def __add__(self, other) : | |
233 """Returns sum""" | |
234 if isinstance(other, pu.PolyBase): | |
235 if not self.has_sametype(other): | |
236 raise TypeError("Polynomial types differ") | |
237 elif not self.has_samedomain(other): | |
238 raise TypeError("Domains differ") | |
239 elif not self.has_samewindow(other): | |
240 raise TypeError("Windows differ") | |
241 else: | |
242 coef = ${nick}add(self.coef, other.coef) | |
243 else : | |
244 try : | |
245 coef = ${nick}add(self.coef, other) | |
246 except : | |
247 return NotImplemented | |
248 return self.__class__(coef, self.domain, self.window) | |
249 | |
250 def __sub__(self, other) : | |
251 """Returns difference""" | |
252 if isinstance(other, pu.PolyBase): | |
253 if not self.has_sametype(other): | |
254 raise TypeError("Polynomial types differ") | |
255 elif not self.has_samedomain(other): | |
256 raise TypeError("Domains differ") | |
257 elif not self.has_samewindow(other): | |
258 raise TypeError("Windows differ") | |
259 else: | |
260 coef = ${nick}sub(self.coef, other.coef) | |
261 else : | |
262 try : | |
263 coef = ${nick}sub(self.coef, other) | |
264 except : | |
265 return NotImplemented | |
266 return self.__class__(coef, self.domain, self.window) | |
267 | |
268 def __mul__(self, other) : | |
269 """Returns product""" | |
270 if isinstance(other, pu.PolyBase): | |
271 if not self.has_sametype(other): | |
272 raise TypeError("Polynomial types differ") | |
273 elif not self.has_samedomain(other): | |
274 raise TypeError("Domains differ") | |
275 elif not self.has_samewindow(other): | |
276 raise TypeError("Windows differ") | |
277 else: | |
278 coef = ${nick}mul(self.coef, other.coef) | |
279 else : | |
280 try : | |
281 coef = ${nick}mul(self.coef, other) | |
282 except : | |
283 return NotImplemented | |
284 return self.__class__(coef, self.domain, self.window) | |
285 | |
286 def __div__(self, other): | |
287 # set to __floordiv__, /, for now. | |
288 return self.__floordiv__(other) | |
289 | |
290 def __truediv__(self, other) : | |
291 # there is no true divide if the rhs is not a Number, although it | |
292 # could return the first n elements of an infinite series. | |
293 # It is hard to see where n would come from, though. | |
294 if not isinstance(other, Number) or isinstance(other, bool): | |
295 form = "unsupported types for true division: '%s', '%s'" | |
296 raise TypeError(form % (type(self), type(other))) | |
297 return self.__floordiv__(other) | |
298 | |
299 def __floordiv__(self, other) : | |
300 """Returns the quotient.""" | |
301 if isinstance(other, pu.PolyBase): | |
302 if not self.has_sametype(other): | |
303 raise TypeError("Polynomial types differ") | |
304 elif not self.has_samedomain(other): | |
305 raise TypeError("Domains differ") | |
306 elif not self.has_samewindow(other): | |
307 raise TypeError("Windows differ") | |
308 else: | |
309 quo, rem = ${nick}div(self.coef, other.coef) | |
310 else : | |
311 try : | |
312 quo, rem = ${nick}div(self.coef, other) | |
313 except : | |
314 return NotImplemented | |
315 return self.__class__(quo, self.domain, self.window) | |
316 | |
317 def __mod__(self, other) : | |
318 """Returns the remainder.""" | |
319 if isinstance(other, pu.PolyBase): | |
320 if not self.has_sametype(other): | |
321 raise TypeError("Polynomial types differ") | |
322 elif not self.has_samedomain(other): | |
323 raise TypeError("Domains differ") | |
324 elif not self.has_samewindow(other): | |
325 raise TypeError("Windows differ") | |
326 else: | |
327 quo, rem = ${nick}div(self.coef, other.coef) | |
328 else : | |
329 try : | |
330 quo, rem = ${nick}div(self.coef, other) | |
331 except : | |
332 return NotImplemented | |
333 return self.__class__(rem, self.domain, self.window) | |
334 | |
335 def __divmod__(self, other) : | |
336 """Returns quo, remainder""" | |
337 if isinstance(other, self.__class__) : | |
338 if not self.has_samedomain(other): | |
339 raise TypeError("Domains are not equal") | |
340 elif not self.has_samewindow(other): | |
341 raise TypeError("Windows are not equal") | |
342 else: | |
343 quo, rem = ${nick}div(self.coef, other.coef) | |
344 else : | |
345 try : | |
346 quo, rem = ${nick}div(self.coef, other) | |
347 except : | |
348 return NotImplemented | |
349 quo = self.__class__(quo, self.domain, self.window) | |
350 rem = self.__class__(rem, self.domain, self.window) | |
351 return quo, rem | |
352 | |
353 def __pow__(self, other) : | |
354 try : | |
355 coef = ${nick}pow(self.coef, other, maxpower = self.maxpower) | |
356 except : | |
357 raise | |
358 return self.__class__(coef, self.domain, self.window) | |
359 | |
360 def __radd__(self, other) : | |
361 try : | |
362 coef = ${nick}add(other, self.coef) | |
363 except : | |
364 return NotImplemented | |
365 return self.__class__(coef, self.domain, self.window) | |
366 | |
367 def __rsub__(self, other): | |
368 try : | |
369 coef = ${nick}sub(other, self.coef) | |
370 except : | |
371 return NotImplemented | |
372 return self.__class__(coef, self.domain, self.window) | |
373 | |
374 def __rmul__(self, other) : | |
375 try : | |
376 coef = ${nick}mul(other, self.coef) | |
377 except : | |
378 return NotImplemented | |
379 return self.__class__(coef, self.domain, self.window) | |
380 | |
381 def __rdiv__(self, other): | |
382 # set to __floordiv__ /. | |
383 return self.__rfloordiv__(other) | |
384 | |
385 def __rtruediv__(self, other) : | |
386 # An instance of PolyBase is not considered a | |
387 # Number. | |
388 return NotImplemented | |
389 | |
390 def __rfloordiv__(self, other) : | |
391 try : | |
392 quo, rem = ${nick}div(other, self.coef) | |
393 except: | |
394 return NotImplemented | |
395 return self.__class__(quo, self.domain, self.window) | |
396 | |
397 def __rmod__(self, other) : | |
398 try : | |
399 quo, rem = ${nick}div(other, self.coef) | |
400 except : | |
401 return NotImplemented | |
402 return self.__class__(rem, self.domain, self.window) | |
403 | |
404 def __rdivmod__(self, other) : | |
405 try : | |
406 quo, rem = ${nick}div(other, self.coef) | |
407 except : | |
408 return NotImplemented | |
409 quo = self.__class__(quo, self.domain, self.window) | |
410 rem = self.__class__(rem, self.domain, self.window) | |
411 return quo, rem | |
412 | |
413 # Enhance me | |
414 # some augmented arithmetic operations could be added here | |
415 | |
416 def __eq__(self, other) : | |
417 res = isinstance(other, self.__class__) \ | |
418 and self.has_samecoef(other) \ | |
419 and self.has_samedomain(other) \ | |
420 and self.has_samewindow(other) | |
421 return res | |
422 | |
423 def __ne__(self, other) : | |
424 return not self.__eq__(other) | |
425 | |
426 # | |
427 # Extra methods. | |
428 # | |
429 | |
430 def copy(self) : | |
431 """Return a copy. | |
432 | |
433 Return a copy of the current $name instance. | |
434 | |
435 Returns | |
436 ------- | |
437 new_instance : $name | |
438 Copy of current instance. | |
439 | |
440 """ | |
441 return self.__class__(self.coef, self.domain, self.window) | |
442 | |
443 def degree(self) : | |
444 """The degree of the series. | |
445 | |
446 Notes | |
447 ----- | |
448 .. versionadded:: 1.5.0 | |
449 | |
450 """ | |
451 return len(self) - 1 | |
452 | |
453 def cutdeg(self, deg) : | |
454 """Truncate series to the given degree. | |
455 | |
456 Reduce the degree of the $name series to `deg` by discarding the | |
457 high order terms. If `deg` is greater than the current degree a | |
458 copy of the current series is returned. This can be useful in least | |
459 squares where the coefficients of the high degree terms may be very | |
460 small. | |
461 | |
462 Parameters | |
463 ---------- | |
464 deg : non-negative int | |
465 The series is reduced to degree `deg` by discarding the high | |
466 order terms. The value of `deg` must be a non-negative integer. | |
467 | |
468 Returns | |
469 ------- | |
470 new_instance : $name | |
471 New instance of $name with reduced degree. | |
472 | |
473 Notes | |
474 ----- | |
475 .. versionadded:: 1.5.0 | |
476 | |
477 """ | |
478 return self.truncate(deg + 1) | |
479 | |
480 def trim(self, tol=0) : | |
481 """Remove small leading coefficients | |
482 | |
483 Remove leading coefficients until a coefficient is reached whose | |
484 absolute value greater than `tol` or the beginning of the series is | |
485 reached. If all the coefficients would be removed the series is set to | |
486 ``[0]``. A new $name instance is returned with the new coefficients. | |
487 The current instance remains unchanged. | |
488 | |
489 Parameters | |
490 ---------- | |
491 tol : non-negative number. | |
492 All trailing coefficients less than `tol` will be removed. | |
493 | |
494 Returns | |
495 ------- | |
496 new_instance : $name | |
497 Contains the new set of coefficients. | |
498 | |
499 """ | |
500 coef = pu.trimcoef(self.coef, tol) | |
501 return self.__class__(coef, self.domain, self.window) | |
502 | |
503 def truncate(self, size) : | |
504 """Truncate series to length `size`. | |
505 | |
506 Reduce the $name series to length `size` by discarding the high | |
507 degree terms. The value of `size` must be a positive integer. This | |
508 can be useful in least squares where the coefficients of the | |
509 high degree terms may be very small. | |
510 | |
511 Parameters | |
512 ---------- | |
513 size : positive int | |
514 The series is reduced to length `size` by discarding the high | |
515 degree terms. The value of `size` must be a positive integer. | |
516 | |
517 Returns | |
518 ------- | |
519 new_instance : $name | |
520 New instance of $name with truncated coefficients. | |
521 | |
522 """ | |
523 isize = int(size) | |
524 if isize != size or isize < 1 : | |
525 raise ValueError("size must be a positive integer") | |
526 if isize >= len(self.coef) : | |
527 coef = self.coef | |
528 else : | |
529 coef = self.coef[:isize] | |
530 return self.__class__(coef, self.domain, self.window) | |
531 | |
532 def convert(self, domain=None, kind=None, window=None) : | |
533 """Convert to different class and/or domain. | |
534 | |
535 Parameters | |
536 ---------- | |
537 domain : array_like, optional | |
538 The domain of the converted series. If the value is None, | |
539 the default domain of `kind` is used. | |
540 kind : class, optional | |
541 The polynomial series type class to which the current instance | |
542 should be converted. If kind is None, then the class of the | |
543 current instance is used. | |
544 window : array_like, optional | |
545 The window of the converted series. If the value is None, | |
546 the default window of `kind` is used. | |
547 | |
548 Returns | |
549 ------- | |
550 new_series_instance : `kind` | |
551 The returned class can be of different type than the current | |
552 instance and/or have a different domain. | |
553 | |
554 Notes | |
555 ----- | |
556 Conversion between domains and class types can result in | |
557 numerically ill defined series. | |
558 | |
559 Examples | |
560 -------- | |
561 | |
562 """ | |
563 if kind is None: | |
564 kind = $name | |
565 if domain is None: | |
566 domain = kind.domain | |
567 if window is None: | |
568 window = kind.window | |
569 return self(kind.identity(domain, window=window)) | |
570 | |
571 def mapparms(self) : | |
572 """Return the mapping parameters. | |
573 | |
574 The returned values define a linear map ``off + scl*x`` that is | |
575 applied to the input arguments before the series is evaluated. The | |
576 map depends on the ``domain`` and ``window``; if the current | |
577 ``domain`` is equal to the ``window`` the resulting map is the | |
578 identity. If the coefficients of the ``$name`` instance are to be | |
579 used by themselves outside this class, then the linear function | |
580 must be substituted for the ``x`` in the standard representation of | |
581 the base polynomials. | |
582 | |
583 Returns | |
584 ------- | |
585 off, scl : floats or complex | |
586 The mapping function is defined by ``off + scl*x``. | |
587 | |
588 Notes | |
589 ----- | |
590 If the current domain is the interval ``[l_1, r_1]`` and the window | |
591 is ``[l_2, r_2]``, then the linear mapping function ``L`` is | |
592 defined by the equations:: | |
593 | |
594 L(l_1) = l_2 | |
595 L(r_1) = r_2 | |
596 | |
597 """ | |
598 return pu.mapparms(self.domain, self.window) | |
599 | |
600 def integ(self, m=1, k=[], lbnd=None) : | |
601 """Integrate. | |
602 | |
603 Return an instance of $name that is the definite integral of the | |
604 current series. Refer to `${nick}int` for full documentation. | |
605 | |
606 Parameters | |
607 ---------- | |
608 m : non-negative int | |
609 The number of integrations to perform. | |
610 k : array_like | |
611 Integration constants. The first constant is applied to the | |
612 first integration, the second to the second, and so on. The | |
613 list of values must less than or equal to `m` in length and any | |
614 missing values are set to zero. | |
615 lbnd : Scalar | |
616 The lower bound of the definite integral. | |
617 | |
618 Returns | |
619 ------- | |
620 integral : $name | |
621 The integral of the series using the same domain. | |
622 | |
623 See Also | |
624 -------- | |
625 ${nick}int : similar function. | |
626 ${nick}der : similar function for derivative. | |
627 | |
628 """ | |
629 off, scl = self.mapparms() | |
630 if lbnd is None : | |
631 lbnd = 0 | |
632 else : | |
633 lbnd = off + scl*lbnd | |
634 coef = ${nick}int(self.coef, m, k, lbnd, 1./scl) | |
635 return self.__class__(coef, self.domain, self.window) | |
636 | |
637 def deriv(self, m=1): | |
638 """Differentiate. | |
639 | |
640 Return an instance of $name that is the derivative of the current | |
641 series. Refer to `${nick}der` for full documentation. | |
642 | |
643 Parameters | |
644 ---------- | |
645 m : non-negative int | |
646 The number of integrations to perform. | |
647 | |
648 Returns | |
649 ------- | |
650 derivative : $name | |
651 The derivative of the series using the same domain. | |
652 | |
653 See Also | |
654 -------- | |
655 ${nick}der : similar function. | |
656 ${nick}int : similar function for integration. | |
657 | |
658 """ | |
659 off, scl = self.mapparms() | |
660 coef = ${nick}der(self.coef, m, scl) | |
661 return self.__class__(coef, self.domain, self.window) | |
662 | |
663 def roots(self) : | |
664 """Return list of roots. | |
665 | |
666 Return ndarray of roots for this series. See `${nick}roots` for | |
667 full documentation. Note that the accuracy of the roots is likely to | |
668 decrease the further outside the domain they lie. | |
669 | |
670 See Also | |
671 -------- | |
672 ${nick}roots : similar function | |
673 ${nick}fromroots : function to go generate series from roots. | |
674 | |
675 """ | |
676 roots = ${nick}roots(self.coef) | |
677 return pu.mapdomain(roots, self.window, self.domain) | |
678 | |
679 def linspace(self, n=100, domain=None): | |
680 """Return x,y values at equally spaced points in domain. | |
681 | |
682 Returns x, y values at `n` linearly spaced points across domain. | |
683 Here y is the value of the polynomial at the points x. By default | |
684 the domain is the same as that of the $name instance. This method | |
685 is intended mostly as a plotting aid. | |
686 | |
687 Parameters | |
688 ---------- | |
689 n : int, optional | |
690 Number of point pairs to return. The default value is 100. | |
691 domain : {None, array_like} | |
692 If not None, the specified domain is used instead of that of | |
693 the calling instance. It should be of the form ``[beg,end]``. | |
694 The default is None. | |
695 | |
696 Returns | |
697 ------- | |
698 x, y : ndarrays | |
699 ``x`` is equal to linspace(self.domain[0], self.domain[1], n) | |
700 ``y`` is the polynomial evaluated at ``x``. | |
701 | |
702 .. versionadded:: 1.5.0 | |
703 | |
704 """ | |
705 if domain is None: | |
706 domain = self.domain | |
707 x = np.linspace(domain[0], domain[1], n) | |
708 y = self(x) | |
709 return x, y | |
710 | |
711 | |
712 | |
713 @staticmethod | |
714 def fit(x, y, deg, domain=None, rcond=None, full=False, w=None, | |
715 window=$domain): | |
716 """Least squares fit to data. | |
717 | |
718 Return a `$name` instance that is the least squares fit to the data | |
719 `y` sampled at `x`. Unlike `${nick}fit`, the domain of the returned | |
720 instance can be specified and this will often result in a superior | |
721 fit with less chance of ill conditioning. Support for NA was added | |
722 in version 1.7.0. See `${nick}fit` for full documentation of the | |
723 implementation. | |
724 | |
725 Parameters | |
726 ---------- | |
727 x : array_like, shape (M,) | |
728 x-coordinates of the M sample points ``(x[i], y[i])``. | |
729 y : array_like, shape (M,) or (M, K) | |
730 y-coordinates of the sample points. Several data sets of sample | |
731 points sharing the same x-coordinates can be fitted at once by | |
732 passing in a 2D-array that contains one dataset per column. | |
733 deg : int | |
734 Degree of the fitting polynomial. | |
735 domain : {None, [beg, end], []}, optional | |
736 Domain to use for the returned $name instance. If ``None``, | |
737 then a minimal domain that covers the points `x` is chosen. If | |
738 ``[]`` the default domain ``$domain`` is used. The default | |
739 value is $domain in numpy 1.4.x and ``None`` in later versions. | |
740 The ``[]`` value was added in numpy 1.5.0. | |
741 rcond : float, optional | |
742 Relative condition number of the fit. Singular values smaller | |
743 than this relative to the largest singular value will be | |
744 ignored. The default value is len(x)*eps, where eps is the | |
745 relative precision of the float type, about 2e-16 in most | |
746 cases. | |
747 full : bool, optional | |
748 Switch determining nature of return value. When it is False | |
749 (the default) just the coefficients are returned, when True | |
750 diagnostic information from the singular value decomposition is | |
751 also returned. | |
752 w : array_like, shape (M,), optional | |
753 Weights. If not None the contribution of each point | |
754 ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the | |
755 weights are chosen so that the errors of the products | |
756 ``w[i]*y[i]`` all have the same variance. The default value is | |
757 None. | |
758 .. versionadded:: 1.5.0 | |
759 window : {[beg, end]}, optional | |
760 Window to use for the returned $name instance. The default | |
761 value is ``$domain`` | |
762 .. versionadded:: 1.6.0 | |
763 | |
764 Returns | |
765 ------- | |
766 least_squares_fit : instance of $name | |
767 The $name instance is the least squares fit to the data and | |
768 has the domain specified in the call. | |
769 | |
770 [residuals, rank, singular_values, rcond] : only if `full` = True | |
771 Residuals of the least squares fit, the effective rank of the | |
772 scaled Vandermonde matrix and its singular values, and the | |
773 specified value of `rcond`. For more details, see | |
774 `linalg.lstsq`. | |
775 | |
776 See Also | |
777 -------- | |
778 ${nick}fit : similar function | |
779 | |
780 """ | |
781 if domain is None: | |
782 domain = pu.getdomain(x) | |
783 elif type(domain) is list and len(domain) == 0: | |
784 domain = $domain | |
785 | |
786 if type(window) is list and len(window) == 0: | |
787 window = $domain | |
788 | |
789 xnew = pu.mapdomain(x, domain, window) | |
790 res = ${nick}fit(xnew, y, deg, w=w, rcond=rcond, full=full) | |
791 if full : | |
792 [coef, status] = res | |
793 return $name(coef, domain=domain, window=window), status | |
794 else : | |
795 coef = res | |
796 return $name(coef, domain=domain, window=window) | |
797 | |
798 @staticmethod | |
799 def fromroots(roots, domain=$domain, window=$domain) : | |
800 """Return $name instance with specified roots. | |
801 | |
802 Returns an instance of $name representing the product | |
803 ``(x - r[0])*(x - r[1])*...*(x - r[n-1])``, where ``r`` is the | |
804 list of roots. | |
805 | |
806 Parameters | |
807 ---------- | |
808 roots : array_like | |
809 List of roots. | |
810 domain : {array_like, None}, optional | |
811 Domain for the resulting instance of $name. If none the domain | |
812 is the interval from the smallest root to the largest. The | |
813 default is $domain. | |
814 window : array_like, optional | |
815 Window for the resulting instance of $name. The default value | |
816 is $domain. | |
817 | |
818 Returns | |
819 ------- | |
820 object : $name instance | |
821 Series with the specified roots. | |
822 | |
823 See Also | |
824 -------- | |
825 ${nick}fromroots : equivalent function | |
826 | |
827 """ | |
828 [roots] = pu.as_series([roots], trim=False) | |
829 if domain is None : | |
830 domain = pu.getdomain(roots) | |
831 deg = len(roots) | |
832 off, scl = pu.mapparms(domain, window) | |
833 rnew = off + scl*roots | |
834 coef = ${nick}fromroots(rnew) / scl**deg | |
835 return $name(coef, domain=domain, window=window) | |
836 | |
837 @staticmethod | |
838 def identity(domain=$domain, window=$domain) : | |
839 """Identity function. | |
840 | |
841 If ``p`` is the returned $name object, then ``p(x) == x`` for all | |
842 values of x. | |
843 | |
844 Parameters | |
845 ---------- | |
846 domain : array_like | |
847 The resulting array must be of the form ``[beg, end]``, where | |
848 ``beg`` and ``end`` are the endpoints of the domain. | |
849 window : array_like | |
850 The resulting array must be if the form ``[beg, end]``, where | |
851 ``beg`` and ``end`` are the endpoints of the window. | |
852 | |
853 Returns | |
854 ------- | |
855 identity : $name instance | |
856 | |
857 """ | |
858 off, scl = pu.mapparms(window, domain) | |
859 coef = ${nick}line(off, scl) | |
860 return $name(coef, domain, window) | |
861 | |
862 @staticmethod | |
863 def basis(deg, domain=$domain, window=$domain): | |
864 """$name polynomial of degree `deg`. | |
865 | |
866 Returns an instance of the $name polynomial of degree `d`. | |
867 | |
868 Parameters | |
869 ---------- | |
870 deg : int | |
871 Degree of the $name polynomial. Must be >= 0. | |
872 domain : array_like | |
873 The resulting array must be of the form ``[beg, end]``, where | |
874 ``beg`` and ``end`` are the endpoints of the domain. | |
875 window : array_like | |
876 The resulting array must be if the form ``[beg, end]``, where | |
877 ``beg`` and ``end`` are the endpoints of the window. | |
878 | |
879 Returns | |
880 p : $name instance | |
881 | |
882 Notes | |
883 ----- | |
884 .. versionadded:: 1.7.0 | |
885 | |
886 """ | |
887 ideg = int(deg) | |
888 if ideg != deg or ideg < 0: | |
889 raise ValueError("deg must be non-negative integer") | |
890 return $name([0]*ideg + [1], domain, window) | |
891 | |
892 @staticmethod | |
893 def cast(series, domain=$domain, window=$domain): | |
894 """Convert instance to equivalent $name series. | |
895 | |
896 The `series` is expected to be an instance of some polynomial | |
897 series of one of the types supported by by the numpy.polynomial | |
898 module, but could be some other class that supports the convert | |
899 method. | |
900 | |
901 Parameters | |
902 ---------- | |
903 series : series | |
904 The instance series to be converted. | |
905 domain : array_like | |
906 The resulting array must be of the form ``[beg, end]``, where | |
907 ``beg`` and ``end`` are the endpoints of the domain. | |
908 window : array_like | |
909 The resulting array must be if the form ``[beg, end]``, where | |
910 ``beg`` and ``end`` are the endpoints of the window. | |
911 | |
912 Returns | |
913 p : $name instance | |
914 A $name series equal to the `poly` series. | |
915 | |
916 See Also | |
917 -------- | |
918 convert -- similar instance method | |
919 | |
920 Notes | |
921 ----- | |
922 .. versionadded:: 1.7.0 | |
923 | |
924 """ | |
925 return series.convert(domain, $name, window) | |
926 | |
927 ''') |