~jtaylor/ubuntu/precise/python-numpy/multiarch-fix-818867

« back to all changes in this revision

Viewing changes to numpy/lib/polynomial.py

  • Committer: Bazaar Package Importer
  • Author(s): Ondrej Certik, Riku Voipio, Tiziano Zito, Carlos Galisteo, Ondrej Certik
  • Date: 2008-07-08 15:08:16 UTC
  • mfrom: (0.1.21 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080708150816-ekf992jcp2k1eua3
Tags: 1:1.1.0-3
[ Riku Voipio ]
* debian/control: atlas is not available on armel, and after a quick look
  neither on alpha. I'd also suggest dropping
  libatlas-sse-dev|libatlas-sse2-dev|libatlas-3dnow-dev alternative combo
  away, these are potentially dangerous on buildd's. Ondrej: dropped.
  (Closes: #489568)

[ Tiziano Zito ]
* patch: build _dotblas.c when ATLAS is not installed, build-conflict with
  atlas, build-depend on blas+lapack only, as it used to be (Closes: #489726)

[ Carlos Galisteo ]
* debian/control
  - Added Homepage field.

[ Ondrej Certik ]
* Checked the package on i386 and amd64, both with and without atlas, all
  tests run and the numpy package is faster if atlas is around. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
def poly(seq_of_zeros):
51
51
    """ Return a sequence representing a polynomial given a sequence of roots.
52
52
 
53
 
        If the input is a matrix, return the characteristic polynomial.
54
 
 
55
 
        Example:
56
 
 
57
 
         >>> b = roots([1,3,1,5,6])
58
 
         >>> poly(b)
59
 
         array([1., 3., 1., 5., 6.])
 
53
    If the input is a matrix, return the characteristic polynomial.
 
54
 
 
55
    Example:
 
56
 
 
57
        >>> b = roots([1,3,1,5,6])
 
58
        >>> poly(b)
 
59
        array([ 1.,  3.,  1.,  5.,  6.])
 
60
 
60
61
    """
61
62
    seq_of_zeros = atleast_1d(seq_of_zeros)
62
63
    sh = seq_of_zeros.shape
181
182
def polyfit(x, y, deg, rcond=None, full=False):
182
183
    """Least squares polynomial fit.
183
184
 
184
 
    Required arguments
185
 
 
186
 
        x -- vector of sample points
187
 
        y -- vector or 2D array of values to fit
188
 
        deg -- degree of the fitting polynomial
189
 
 
190
 
    Keyword arguments
191
 
 
192
 
        rcond -- relative condition number of the fit (default len(x)*eps)
193
 
        full -- return full diagnostic output (default False)
194
 
 
195
 
    Returns
196
 
 
197
 
        full == False -- coefficients
198
 
        full == True -- coefficients, residuals, rank, singular values, rcond.
199
 
 
200
 
    Warns
201
 
 
202
 
        RankWarning -- if rank is reduced and not full output
203
 
 
204
185
    Do a best fit polynomial of degree 'deg' of 'x' to 'y'.  Return value is a
205
186
    vector of polynomial coefficients [pk ... p1 p0].  Eg, for n=2
206
187
 
207
 
      p2*x0^2 +  p1*x0 + p0 = y1
208
 
      p2*x1^2 +  p1*x1 + p0 = y1
209
 
      p2*x2^2 +  p1*x2 + p0 = y2
210
 
      .....
211
 
      p2*xk^2 +  p1*xk + p0 = yk
212
 
 
213
 
 
214
 
    Method: if X is a the Vandermonde Matrix computed from x (see
 
188
        p2*x0^2 +  p1*x0 + p0 = y1
 
189
        p2*x1^2 +  p1*x1 + p0 = y1
 
190
        p2*x2^2 +  p1*x2 + p0 = y2
 
191
        .....
 
192
        p2*xk^2 +  p1*xk + p0 = yk
 
193
 
 
194
    Parameters
 
195
    ----------
 
196
    x : array_like
 
197
        1D vector of sample points.
 
198
    y : array_like
 
199
        1D vector or 2D array of values to fit. The values should run down the
 
200
        columes in the 2D case.
 
201
    deg : integer
 
202
        Degree of the fitting polynomial
 
203
    rcond: {None, float}, optional
 
204
        Relative condition number of the fit. Singular values smaller than this
 
205
        relative to the largest singular value will be ignored. The defaul value
 
206
        is len(x)*eps, where eps is the relative precision of the float type,
 
207
        about 2e-16 in most cases.
 
208
    full : {False, boolean}, optional
 
209
        Switch determining nature of return value. When it is False just the
 
210
        coefficients are returned, when True diagnostic information from the
 
211
        singular value decomposition is also returned.
 
212
 
 
213
    Returns
 
214
    -------
 
215
    coefficients, [residuals, rank, singular_values, rcond] : variable
 
216
        When full=False, only the coefficients are returned, running down the
 
217
        appropriate colume when y is a 2D array. When full=True, the rank of the
 
218
        scaled Vandermonde matrix, it's effective rank in light of the rcond
 
219
        value, its singular values, and the specified value of rcond are also
 
220
        returned.
 
221
 
 
222
    Warns
 
223
    -----
 
224
    RankWarning : if rank is reduced and not full output
 
225
        The warnings can be turned off by:
 
226
        >>> import numpy as np
 
227
        >>> import warnings
 
228
        >>> warnings.simplefilter('ignore',np.RankWarning)
 
229
 
 
230
 
 
231
    See Also
 
232
    --------
 
233
    polyval : computes polynomial values.
 
234
 
 
235
    Notes
 
236
    -----
 
237
    If X is a the Vandermonde Matrix computed from x (see
215
238
    http://mathworld.wolfram.com/VandermondeMatrix.html), then the
216
239
    polynomial least squares solution is given by the 'p' in
217
240
 
218
 
      X*p = y
 
241
        X*p = y
219
242
 
220
 
    where X is a len(x) x N+1 matrix, p is a N+1 length vector, and y
221
 
    is a len(x) x 1 vector
 
243
    where X.shape is a matrix of dimensions (len(x), deg + 1), p is a vector of
 
244
    dimensions (deg + 1, 1), and y is a vector of dimensions (len(x), 1).
222
245
 
223
246
    This equation can be solved as
224
247
 
225
 
      p = (XT*X)^-1 * XT * y
 
248
        p = (XT*X)^-1 * XT * y
226
249
 
227
250
    where XT is the transpose of X and -1 denotes the inverse. However, this
228
251
    method is susceptible to rounding errors and generally the singular value
229
 
    decomposition is preferred and that is the method used here. The singular
230
 
    value method takes a paramenter, 'rcond', which sets a limit on the
231
 
    relative size of the smallest singular value to be used in solving the
232
 
    equation. This may result in lowering the rank of the Vandermonde matrix,
233
 
    in which case a RankWarning is issued. If polyfit issues a RankWarning, try
234
 
    a fit of lower degree or replace x by x - x.mean(), both of which will
 
252
    decomposition of the matrix X is preferred and that is what is done here.
 
253
    The singular value method takes a paramenter, 'rcond', which sets a limit on
 
254
    the relative size of the smallest singular value to be used in solving the
 
255
    equation. This may result in lowering the rank of the Vandermonde matrix, in
 
256
    which case a RankWarning is issued. If polyfit issues a RankWarning, try a
 
257
    fit of lower degree or replace x by x - x.mean(), both of which will
235
258
    generally improve the condition number. The routine already normalizes the
236
259
    vector x by its maximum absolute value to help in this regard. The rcond
237
 
    parameter may also be set to a value smaller than its default, but this may
238
 
    result in bad fits. The current default value of rcond is len(x)*eps, where
 
260
    parameter can be set to a value smaller than its default, but the resulting
 
261
    fit may be spurious. The current default value of rcond is len(x)*eps, where
239
262
    eps is the relative precision of the floating type being used, generally
240
263
    around 1e-7 and 2e-16 for IEEE single and double precision respectively.
241
264
    This value of rcond is fairly conservative but works pretty well when x -
242
265
    x.mean() is used in place of x.
243
266
 
244
 
    The warnings can be turned off by:
245
 
 
246
 
    >>> import numpy
247
 
    >>> import warnings
248
 
    >>> warnings.simplefilter('ignore',numpy.RankWarning)
249
267
 
250
268
    DISCLAIMER: Power series fits are full of pitfalls for the unwary once the
251
269
    degree of the fit becomes large or the interval of sample points is badly
252
 
    centered. The basic problem is that the powers x**n are generally a poor
253
 
    basis for the functions on the sample interval with the result that the
254
 
    Vandermonde matrix is ill conditioned and computation of the polynomial
255
 
    values is sensitive to coefficient error. The quality of the resulting fit
256
 
    should be checked against the data whenever the condition number is large,
257
 
    as the quality of polynomial fits *can not* be taken for granted. If all
258
 
    you want to do is draw a smooth curve through the y values and polyfit is
259
 
    not doing the job, try centering the sample range or look into
260
 
    scipy.interpolate, which includes some nice spline fitting functions that
261
 
    may be of use.
 
270
    centered. The problem is that the powers x**n are generally a poor basis for
 
271
    the polynomial functions on the sample interval, resulting in a Vandermonde
 
272
    matrix is ill conditioned and coefficients sensitive to rounding erros. The
 
273
    computation of the polynomial values will also sensitive to rounding errors.
 
274
    Consequently, the quality of the polynomial fit should be checked against
 
275
    the data whenever the condition number is large.  The quality of polynomial
 
276
    fits *can not* be taken for granted. If all you want to do is draw a smooth
 
277
    curve through the y values and polyfit is not doing the job, try centering
 
278
    the sample range or look into scipy.interpolate, which includes some nice
 
279
    spline fitting functions that may be of use.
262
280
 
263
281
    For more info, see
264
282
    http://mathworld.wolfram.com/LeastSquaresFittingPolynomial.html,
265
283
    but note that the k's and n's in the superscripts and subscripts
266
284
    on that page.  The linear algebra is correct, however.
267
285
 
268
 
    See also polyval
269
 
 
270
286
    """
271
287
    order = int(deg) + 1
272
288
    x = NX.asarray(x) + 0.0
275
291
    # check arguments.
276
292
    if deg < 0 :
277
293
        raise ValueError, "expected deg >= 0"
278
 
    if x.ndim != 1 or x.size == 0:
 
294
    if x.ndim != 1:
 
295
        raise TypeError, "expected 1D vector for x"
 
296
    if x.size == 0:
279
297
        raise TypeError, "expected non-empty vector for x"
280
298
    if y.ndim < 1 or y.ndim > 2 :
281
299
        raise TypeError, "expected 1D or 2D array for y"
306
324
 
307
325
    # scale returned coefficients
308
326
    if scale != 0 :
309
 
        c /= vander([scale], order)[0]
 
327
        if c.ndim == 1 :
 
328
            c /= vander([scale], order)[0]
 
329
        else :
 
330
            c /= vander([scale], order).T
310
331
 
311
332
    if full :
312
333
        return c, resids, rank, s, rcond
316
337
 
317
338
 
318
339
def polyval(p, x):
319
 
    """Evaluate the polynomial p at x.  If x is a polynomial then composition.
320
 
 
321
 
    Description:
322
 
 
323
 
      If p is of length N, this function returns the value:
324
 
      p[0]*(x**N-1) + p[1]*(x**N-2) + ... + p[N-2]*x + p[N-1]
325
 
 
326
 
      x can be a sequence and p(x) will be returned for all elements of x.
327
 
      or x can be another polynomial and the composite polynomial p(x) will be
328
 
      returned.
329
 
 
330
 
      Notice:  This can produce inaccurate results for polynomials with
331
 
      significant variability. Use carefully.
 
340
    """Evaluate the polynomial p at x.
 
341
 
 
342
    If p is of length N, this function returns the value:
 
343
 
 
344
        p[0]*(x**N-1) + p[1]*(x**N-2) + ... + p[N-2]*x + p[N-1]
 
345
 
 
346
    If x is a sequence then p(x) will be returned for all elements of x. If x is
 
347
    another polynomial then the composite polynomial p(x) will be returned.
 
348
 
 
349
    Parameters
 
350
    ----------
 
351
    p : {array_like, poly1d}
 
352
        1D array of polynomial coefficients from highest degree to zero or an
 
353
        instance of poly1d.
 
354
    x : {array_like, poly1d}
 
355
        A number, a 1D array of numbers, or an instance of poly1d.
 
356
 
 
357
    Returns
 
358
    -------
 
359
    values : {array, poly1d}
 
360
        If either p or x is an instance of poly1d, then an instance of poly1d is
 
361
        returned, otherwise a 1D array is returned. In the case where x is a
 
362
        poly1d, the result is the composition of the two polynomials, i.e.,
 
363
        substitution is used.
 
364
 
 
365
    Notes
 
366
    -----
 
367
    Horners method is used to evaluate the polynomial. Even so, for polynomial
 
368
    if high degree the values may be inaccurate due to rounding errors. Use
 
369
    carefully.
 
370
 
332
371
    """
333
372
    p = NX.asarray(p)
334
373
    if isinstance(x, poly1d):
383
422
    """Multiplies two polynomials represented as sequences.
384
423
    """
385
424
    truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d))
 
425
    a1,a2 = poly1d(a1),poly1d(a2)
386
426
    val = NX.convolve(a1, a2)
387
427
    if truepoly:
388
428
        val = poly1d(val)
398
438
    m = len(u) - 1
399
439
    n = len(v) - 1
400
440
    scale = 1. / v[0]
401
 
    q = NX.zeros((m-n+1,), float)
 
441
    q = NX.zeros((max(m-n+1,1),), float)
402
442
    r = u.copy()
403
443
    for k in range(0, m-n+1):
404
444
        d = scale * r[k]
498
538
        return self.order
499
539
 
500
540
    def __str__(self):
501
 
        N = self.order
502
541
        thestr = "0"
503
542
        var = self.variable
504
 
        for k in range(len(self.coeffs)):
505
 
            coefstr ='%.4g' % abs(self.coeffs[k])
 
543
 
 
544
        # Remove leading zeros
 
545
        coeffs = self.coeffs[NX.logical_or.accumulate(self.coeffs != 0)]
 
546
        N = len(coeffs)-1
 
547
 
 
548
        for k in range(len(coeffs)):
 
549
            coefstr ='%.4g' % abs(coeffs[k])
506
550
            if coefstr[-4:] == '0000':
507
551
                coefstr = coefstr[:-5]
508
552
            power = (N-k)
531
575
 
532
576
            if k > 0:
533
577
                if newstr != '':
534
 
                    if self.coeffs[k] < 0:
 
578
                    if coeffs[k] < 0:
535
579
                        thestr = "%s - %s" % (thestr, newstr)
536
580
                    else:
537
581
                        thestr = "%s + %s" % (thestr, newstr)
538
 
            elif (k == 0) and (newstr != '') and (self.coeffs[k] < 0):
 
582
            elif (k == 0) and (newstr != '') and (coeffs[k] < 0):
539
583
                thestr = "-%s" % (newstr,)
540
584
            else:
541
585
                thestr = newstr
545
589
    def __call__(self, val):
546
590
        return polyval(self.coeffs, val)
547
591
 
 
592
    def __neg__(self):
 
593
        return poly1d(-self.coeffs)
 
594
 
 
595
    def __pos__(self):
 
596
        return self
 
597
 
548
598
    def __mul__(self, other):
549
599
        if isscalar(other):
550
600
            return poly1d(self.coeffs * other)
598
648
            return polydiv(other, self)
599
649
 
600
650
    def __eq__(self, other):
601
 
        return (self.coeffs == other.coeffs).all()
 
651
        return NX.alltrue(self.coeffs == other.coeffs)
602
652
 
603
653
    def __ne__(self, other):
604
 
        return (self.coeffs != other.coeffs).any()
 
654
        return NX.any(self.coeffs != other.coeffs)
605
655
 
606
656
    def __setattr__(self, key, val):
607
657
        raise ValueError, "Attributes cannot be changed this way."
614
664
        elif key in ['o']:
615
665
            return self.order
616
666
        else:
617
 
            return self.__dict__[key]
 
667
            try:
 
668
                return self.__dict__[key]
 
669
            except KeyError:
 
670
                raise AttributeError("'%s' has no attribute '%s'" % (self.__class__, key))
618
671
 
619
672
    def __getitem__(self, val):
620
673
        ind = self.order - val
636
689
        self.__dict__['coeffs'][ind] = val
637
690
        return
638
691
 
 
692
    def __iter__(self):
 
693
        return iter(self.coeffs)
 
694
 
639
695
    def integ(self, m=1, k=0):
640
696
        """Return the mth analytical integral of this polynomial.
641
697
        See the documentation for polyint.
650
706
# Stuff to do on module import
651
707
 
652
708
warnings.simplefilter('always',RankWarning)
653