예제 #1
0
def fidw(xs, ds, beta=2):
    '''Interpolate using using U{Inverse Distance Weighting
       <https://WikiPedia.org/wiki/Inverse_distance_weighting>} (IDW).

       @arg xs: Known values (C{scalar}[]).
       @arg ds: Non-negative distances (C{scalar}[]).
       @kwarg beta: Inverse distance power (C{int}, 0, 1, 2, or 3).

       @return: Interpolated value C{x} (C{float}).

       @raise ValueError: Invalid B{C{beta}}, negative B{C{ds}} value,
                          weighted B{C{ds}} below L{EPS} or unequal
                          C{len}C{(}B{C{ds}}C{)} and C{len}C{(}B{C{xs}}C{)}.

       @note: Using B{C{beta}}C{=0} returns the mean of B{C{xs}}.
    '''
    n, xs = len2(xs)
    d, ds = len2(ds)
    if n != d or n < 1:
        raise LenError(fidw, xs=n, ds=d)

    d, x = min(zip(ds, xs))
    if d > EPS and n > 1:
        b = -Int_(beta, name=_beta_, low=0, high=3)
        if b < 0:
            ds = tuple(d**b for d in ds)
            d = fsum(ds)
            if d < EPS:
                raise _ValueError(ds=d)
            x = fdot(xs, *ds) / d
        else:
            x = fmean(xs)
    elif d < 0:
        raise _ValueError(_item_sq('ds', ds.index(d)), d)
    return x
예제 #2
0
def fdot3(a, b, c, start=0):
    '''Return the precision dot product M{start +
       sum(a[i] * b[i] * c[i] for i=0..len(a))}.

       @arg a: List, sequence, tuple, etc. (C{scalar}[]).
       @arg b: List, sequence, tuple, etc. (C{scalar}[]).
       @arg c: List, sequence, tuple, etc. (C{scalar}[]).
       @kwarg start: Optional bias (C{scalar}).

       @return: Dot product (C{float}).

       @raise LenError: Unequal C{len(B{a})}, C{len(B{b})}
                        and/or C{len(B{c})}.

       @raise OverflowError: Partial C{2sum} overflow.
    '''
    def _mul3(a, b, c):  # map function
        return a * b * c  # PYCHOK returns

    if not len(a) == len(b) == len(c):
        raise LenError(fdot3, a=len(a), b=len(b), c=len(c))

    if start:
        f = Fsum(start)
        return f.fsum(map(_mul3, a, b, c))
    else:
        return fsum(map(_mul3, a, b, c))
예제 #3
0
파일: named.py 프로젝트: rbpdqdat/PyGeodesy
    def __new__(cls, *args, **name_only):
        '''New L{_NamedTuple} initialized with B{C{positional}} arguments.

           @arg args: Tuple items (C{any}), all positional arguments.
           @kwarg name_only: Only C{B{name}='name'} is used, anu other
                             keyword arguments are I{silently} ignored.

           @raise LenError: Unequal number of positional arguments and
                            number of item C{_Names_} or C{_Units_}.

           @raise TypeError: The C{_Names_} or C{_Units_} attribute is
                             not a C{tuple} of at least 2 items.

           @raise ValueError: Item name is not a C{str} or valid C{identifier}
                              or starts with C{underscore}.
        '''
        self = tuple.__new__(cls, args)
        if not self._validated:
            self._validate()

        n = len(self._Names_)
        if len(args) != n:
            raise LenError(self.__class__, args=len(args), _Names_=n)
        if name_only:  # name=NN
            n = name_only.get(_name_, NN)
            if n:
                self.name = n
        return self
예제 #4
0
    def __init__(self, knots, weight=None, name=NN):
        '''New L{HeightLSQBiSpline} interpolator.

           @arg knots: The points with known height (C{LatLon}s).
           @kwarg weight: Optional weight or weights for each B{C{knot}}
                          (C{scalar} or C{scalar}s).
           @kwarg name: Optional name for this height interpolator (C{str}).

           @raise HeightError: Insufficient number of B{C{knots}} or
                               an invalid B{C{knot}} or B{C{weight}}.

           @raise LenError: Number of B{C{knots}} and B{C{weight}}s
                            don't match.

           @raise ImportError: Package C{numpy} or C{scipy} not found
                               or not installed.

           @raise SciPyError: A C{LSQSphereBivariateSpline} issue.

           @raise SciPyWarning: A C{LSQSphereBivariateSpline} warning
                                as exception.
        '''
        np, spi = self._NumSciPy()

        xs, ys, hs = self._xyhs3(knots)
        n = len(hs)

        w = weight
        if isscalar(w):
            w = float(w)
            if w <= 0:
                raise HeightError(weight=w)
            w = [w] * n
        elif w is not None:
            m, w = len2(w)
            if m != n:
                raise LenError(HeightLSQBiSpline, weight=m, knots=n)
            w = map2(float, w)
            m = min(w)
            if m <= 0:
                raise HeightError(_item_sq(weight=w.find(m)), m)
        try:
            T = 1.0e-4  # like SciPy example
            ps = np.array(_ordedup(xs, T, PI2 - T))
            ts = np.array(_ordedup(ys, T, PI - T))
            self._ev = spi.LSQSphereBivariateSpline(ys,
                                                    xs,
                                                    hs,
                                                    ts,
                                                    ps,
                                                    eps=EPS,
                                                    w=w).ev
        except Exception as x:
            raise _SciPyIssue(x)

        if name:
            self.name = name
예제 #5
0
 def _height(self, lats, lons, Error=HeightError):
     LLis, d = self._LLis, self.datum
     if isscalar(lats) and isscalar(lons):
         llis = LLis(lats, lons, datum=d)
     else:
         n, lats = len2(lats)
         m, lons = len2(lons)
         if n != m:
             # format a LenError, but raise an Error
             e = LenError(self.__class__, lats=n, lons=m, txt=None)
             raise e if Error is LenError else Error(str(e))
         llis = [LLis(*ll, datum=d) for ll in zip(lats, lons)]
     return self(llis)  # __call__(lli) or __call__(llis)
예제 #6
0
 def __new__(cls, *args):
     '''New L{_NamedTuple} initialized with B{C{positional}} arguments.
     '''
     self = tuple.__new__(cls, args)
     ns = self._Names_
     if not (isinstance(ns, tuple) and len(ns) > 1):  # XXX > 0
         raise _TypeError(_dot_(self.classname, _Names_), ns)
     if len(ns) != len(args) or not ns:
         raise LenError(cls, args=len(args), ns=len(ns))
     if _name_ in ns:
         t = unstr(_dot_(self.classname, _Names_), *ns)
         raise _NameError(_name_, _name_, txt=t)
     return self
예제 #7
0
def fdot(a, *b):
    '''Return the precision dot product M{sum(a[i] * b[i] for
       i=0..len(a))}.

       @arg a: List, sequence, tuple, etc. (C{scalar}s).
       @arg b: All positional arguments (C{scalar}s).

       @return: Dot product (C{float}).

       @raise LenError: Unequal C{len(B{a})} and C{len(B{b})}.

       @see: Class L{Fdot}.
    '''
    if len(a) != len(b):
        raise LenError(fdot, a=len(a), b=len(b))

    return fsum(map(_mul, a, b))
예제 #8
0
    def __init__(self, a, *b):
        '''New L{Fdot} precision dot product M{sum(a[i] * b[i]
           for i=0..len(a))}.

           @arg a: List, sequence, tuple, etc. (C{scalar}s).
           @arg b: All positional arguments (C{scalar}s).

           @raise OverflowError: Partial C{2sum} overflow.

           @raise LenError: Unequal C{len(B{a})} and C{len(B{b})}.

           @see: Function L{fdot} and method L{Fsum.fadd}.
        '''
        if len(a) != len(b):
            raise LenError(Fdot, a=len(a), b=len(b))

        Fsum.__init__(self)
        self.fadd(map(_mul, a, b))
예제 #9
0
파일: named.py 프로젝트: rbpdqdat/PyGeodesy
    def _validate(self, _OK=False):  # see .EcefMatrix
        '''(INTERNAL) One-time check of C{_Names_} and C{_Units_}
           for each C{_NamedUnit} I{sub-class separately}.
        '''
        ns = self._Names_
        if not (isinstance(ns, tuple) and len(ns) > 1):  # XXX > 0
            raise _TypeError(_DOT_(self.classname, _Names_), ns)
        for i, n in enumerate(ns):
            if not _xvalid(n, _OK=_OK):
                t = Fmt.SQUARE(_Names_, i)
                raise _ValueError(_DOT_(self.classname, t), n)

        us = self._Units_
        if not isinstance(us, tuple):
            raise _TypeError(_DOT_(self.classname, _Units_), us)
        if len(us) != len(ns):
            raise LenError(self.__class__, _Units_=len(us), _Names_=len(ns))
        for i, u in enumerate(us):
            if not (u is None or callable(u)):
                t = Fmt.SQUARE(_Units_, i)
                raise _TypeError(_DOT_(self.classname, t), u)

        self.__class__._validated = True