annotate DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/polynomial/polytemplate.py @ 133:4acb5d8d80b6 tip

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