Esempio n. 1
0
    def deriv(self, m, v=None):
        alpha = self.slope
        sig1, sig2, c = m[0], m[1], m[2:]
        if self.logSigma:
            sig1, sig2 = np.exp(sig1), np.exp(sig2)

        # 2D
        if self.mesh.dim == 2:
            X = self.mesh.gridCC[self.actInd, 0]
            Y = self.mesh.gridCC[self.actInd, 1]

            if self.normal == 'X':
                f = polynomial.polyval(Y, c) - X
                V = polynomial.polyvander(Y, len(c) - 1)
            elif self.normal == 'Y':
                f = polynomial.polyval(X, c) - Y
                V = polynomial.polyvander(X, len(c) - 1)
            else:
                raise (Exception("Input for normal = X or Y or Z"))

        # 3D
        elif self.mesh.dim == 3:
            X = self.mesh.gridCC[self.actInd, 0]
            Y = self.mesh.gridCC[self.actInd, 1]
            Z = self.mesh.gridCC[self.actInd, 2]

            if self.normal == 'X':
                f = (polynomial.polyval2d(
                    Y, Z, c.reshape(
                        (self.order[0] + 1, self.order[1] + 1))) - X)
                V = polynomial.polyvander2d(Y, Z, self.order)
            elif self.normal == 'Y':
                f = (polynomial.polyval2d(
                    X, Z, c.reshape(
                        (self.order[0] + 1, self.order[1] + 1))) - Y)
                V = polynomial.polyvander2d(X, Z, self.order)
            elif self.normal == 'Z':
                f = (polynomial.polyval2d(
                    X, Y, c.reshape(
                        (self.order[0] + 1, self.order[1] + 1))) - Z)
                V = polynomial.polyvander2d(X, Y, self.order)
            else:
                raise (Exception("Input for normal = X or Y or Z"))

        if self.logSigma:
            g1 = -(np.arctan(alpha * f) / np.pi + 0.5) * sig1 + sig1
            g2 = (np.arctan(alpha * f) / np.pi + 0.5) * sig2
        else:
            g1 = -(np.arctan(alpha * f) / np.pi + 0.5) + 1.0
            g2 = (np.arctan(alpha * f) / np.pi + 0.5)

        g3 = Utils.sdiag(alpha * (sig2 - sig1) / (1. +
                                                  (alpha * f)**2) / np.pi) * V

        if v is not None:
            return sp.csr_matrix(np.c_[g1, g2, g3]) * v
        return sp.csr_matrix(np.c_[g1, g2, g3])
Esempio n. 2
0
    def deriv(self, m, v=None):
        alpha = self.slope
        sig1, sig2, c = m[0], m[1], m[2:]
        if self.logSigma:
            sig1, sig2 = np.exp(sig1), np.exp(sig2)

        # 2D
        if self.mesh.dim == 2:
            X = self.mesh.gridCC[self.actInd, 0]
            Y = self.mesh.gridCC[self.actInd, 1]

            if self.normal == 'X':
                f = polynomial.polyval(Y, c) - X
                V = polynomial.polyvander(Y, len(c)-1)
            elif self.normal == 'Y':
                f = polynomial.polyval(X, c) - Y
                V = polynomial.polyvander(X, len(c)-1)
            else:
                raise(Exception("Input for normal = X or Y or Z"))

        # 3D
        elif self.mesh.dim == 3:
            X = self.mesh.gridCC[self.actInd, 0]
            Y = self.mesh.gridCC[self.actInd, 1]
            Z = self.mesh.gridCC[self.actInd, 2]

            if self.normal == 'X':
                f = (polynomial.polyval2d(Y, Z, c.reshape((self.order[0]+1,
                     self.order[1]+1))) - X)
                V = polynomial.polyvander2d(Y, Z, self.order)
            elif self.normal == 'Y':
                f = (polynomial.polyval2d(X, Z, c.reshape((self.order[0]+1,
                     self.order[1]+1))) - Y)
                V = polynomial.polyvander2d(X, Z, self.order)
            elif self.normal == 'Z':
                f = (polynomial.polyval2d(X, Y, c.reshape((self.order[0]+1,
                     self.order[1]+1))) - Z)
                V = polynomial.polyvander2d(X, Y, self.order)
            else:
                raise(Exception("Input for normal = X or Y or Z"))

        if self.logSigma:
            g1 = -(np.arctan(alpha*f)/np.pi + 0.5)*sig1 + sig1
            g2 = (np.arctan(alpha*f)/np.pi + 0.5)*sig2
        else:
            g1 = -(np.arctan(alpha*f)/np.pi + 0.5) + 1.0
            g2 = (np.arctan(alpha*f)/np.pi + 0.5)

        g3 = Utils.sdiag(alpha*(sig2-sig1)/(1.+(alpha*f)**2)/np.pi)*V

        if v is not None:
            return sp.csr_matrix(np.c_[g1, g2, g3]) * v
        return sp.csr_matrix(np.c_[g1, g2, g3])
Esempio n. 3
0
    def test_polyvander2d(self):
        # also tests polyval2d for non-square coefficient array
        x1, x2, x3 = self.x
        c = np.random.random((2, 3))
        van = poly.polyvander2d(x1, x2, [1, 2])
        tgt = poly.polyval2d(x1, x2, c)
        res = np.dot(van, c.flat)
        assert_almost_equal(res, tgt)

        # check shape
        van = poly.polyvander2d([x1], [x2], [1, 2])
        assert_(van.shape == (1, 5, 6))
Esempio n. 4
0
    def test_polyvander2d(self) :
        # also tests polyval2d for non-square coefficient array
        x1, x2, x3 = self.x
        c = np.random.random((2, 3))
        van = poly.polyvander2d(x1, x2, [1, 2])
        tgt = poly.polyval2d(x1, x2, c)
        res = np.dot(van, c.flat)
        assert_almost_equal(res, tgt)

        # check shape
        van = poly.polyvander2d([x1], [x2], [1, 2])
        assert_(van.shape == (1, 5, 6))
def polyfit2d(x, y, f, deg):
    """ Returns polynomial coefficients given the values of a function at some point

    Code courtesy of 'klaus se' on stackoverflow.com/questions/7997152

    args:
        x (numpy.ndarray) : x coordinates
        y (numpy.ndarray) : y coordinates
        f (numpy.ndarray) : funtion values 
        deg (iterable of ints) : (max_degree_x, max_degre_y)

    returns:
        c (numpy.ndarray) : array of polynomial coefficients for use with numpy's polyval2d routine
    """
    from numpy.polynomial import polynomial
    import numpy as np
    x = np.asarray(x)
    y = np.asarray(y)
    f = np.asarray(f)
    deg = np.asarray(deg)
    vander = polynomial.polyvander2d(x, y, deg)
    vander = vander.reshape((-1,vander.shape[-1]))
    f = f.reshape((vander.shape[0],))
    c = np.linalg.lstsq(vander, f)[0]
    return c.reshape(deg+1)
Esempio n. 6
0
 def _polyfit2d(x, y, f, deg):
     deg = np.asarray(deg)
     vander = polynomial.polyvander2d(x, y, deg)
     vander = vander.reshape((-1, vander.shape[-1]))
     f = f.reshape((vander.shape[0], ))
     c = np.linalg.lstsq(vander, f, rcond=None)[0]
     return c.reshape(deg + 1)
def polyfit2d(x, y, f, deg):
    """ Returns polynomial coefficients given the values of a function at some point

    Code courtesy of 'klaus se' on stackoverflow.com/questions/7997152

    args:
        x (numpy.ndarray) : x coordinates
        y (numpy.ndarray) : y coordinates
        f (numpy.ndarray) : funtion values 
        deg (iterable of ints) : (max_degree_x, max_degre_y)

    returns:
        c (numpy.ndarray) : array of polynomial coefficients for use with numpy's polyval2d routine
    """
    from numpy.polynomial import polynomial
    import numpy as np
    x = np.asarray(x)
    y = np.asarray(y)
    f = np.asarray(f)
    deg = np.asarray(deg)
    vander = polynomial.polyvander2d(x, y, deg)
    vander = vander.reshape((-1, vander.shape[-1]))
    f = f.reshape((vander.shape[0], ))
    c = np.linalg.lstsq(vander, f)[0]
    return c.reshape(deg + 1)
Esempio n. 8
0
    def polyfit(x=None, y=None, z=None, w=None, order=None):
        """Two-dimensional polynomial fit.
    
        References:
            http://stackoverflow.com/questions/7997152/
            python-3d-polynomial-surface-fit-order-dependent/7997925#7997925

        x: array of coordinates
        y: array of coordinates (2d only)
        z: values of these coordinates (1d array as x and y)
        w: weights
        order: int for 1d, tuple of 2 values (x-order, y-order) for 2d

        Return: matrix of coefficents, for the 2d is ok to be fed into polynomial.polyval2d()
        """
        assert z.shape == w.shape
        if y is None:
            # note that np.polynomial.polynomial.polyfit want sigmas not variances
            m = np.polyfit(x, z, order, w=np.sqrt(w))

        else:
            from numpy.polynomial import polynomial
            x, y = np.meshgrid(np.asarray(x),np.asarray(y), indexing='ij')
            # TODO: unset x,y,z value if flagged
            z = z[(w != 0)]
            x = x[(w != 0)]
            y = y[(w != 0)]
            vander = polynomial.polyvander2d(x, y, order)
            vander = vander.reshape((-1,vander.shape[-1]))
            z = z.reshape((vander.shape[0],))
            m = np.linalg.lstsq(vander, z)[0]
            order = np.asarray(order)
            m = m.reshape(order+1) # matrix of coefficents

        return m
Esempio n. 9
0
    def polyfit(x=None, y=None, z=None, w=None, order=None):
        """Two-dimensional polynomial fit.
    
        References:
            http://stackoverflow.com/questions/7997152/
            python-3d-polynomial-surface-fit-order-dependent/7997925#7997925

        x: array of coordinates
        y: array of coordinates (2d only)
        z: values of these coordinates (1d array as x and y)
        w: weights
        order: int for 1d, tuple of 2 values (x-order, y-order) for 2d

        Return: matrix of coefficents, for the 2d is ok to be fed into polynomial.polyval2d()
        """
        assert z.shape == w.shape
        if y is None:
            # note that np.polynomial.polynomial.polyfit want sigmas not variances
            m = np.polyfit(x, z, order, w=np.sqrt(w))

        else:
            from numpy.polynomial import polynomial
            x, y = np.meshgrid(np.asarray(x), np.asarray(y), indexing='ij')
            # TODO: unset x,y,z value if flagged
            z = z[(w != 0)]
            x = x[(w != 0)]
            y = y[(w != 0)]
            vander = polynomial.polyvander2d(x, y, order)
            vander = vander.reshape((-1, vander.shape[-1]))
            z = z.reshape((vander.shape[0], ))
            m = np.linalg.lstsq(vander, z)[0]
            order = np.asarray(order)
            m = m.reshape(order + 1)  # matrix of coefficents

        return m
def test_polyfit2d(x, y, f, deg=3):
    x = np.asarray(x)
    y = np.asarray(y)
    f = np.asarray(f)
    deg = np.asarray(deg)
    vander = polynomial.polyvander2d(x, y, deg)
    vander = vander.reshape((-1,vander.shape[-1]))
    f = f.reshape((vander.shape[0],))
    c = np.linalg.lstsq(vander, f)[0]
    return c.reshape(deg+1)
Esempio n. 11
0
def polyfit2d(x, y, z, deg):
    # deg : x and y maximum degrees: [x_deg, y_deg].
    x = np.asarray(x)
    y = np.asarray(y)
    z = np.asarray(z)
    deg = np.asarray(deg)
    vander = polynomial.polyvander2d(x, y, deg)
    vander = vander.reshape((-1, vander.shape[-1]))
    z = z.reshape((vander.shape[0], ))
    c = np.linalg.lstsq(vander, z)[0]
    return c.reshape(deg + 1)
Esempio n. 12
0
File: 10-init.py Progetto: UBTC/wipy
def polyfit2d(x, y, z, deg):
    # deg : x and y maximum degrees: [x_deg, y_deg].
    x = np.asarray(x)
    y = np.asarray(y)
    z = np.asarray(z)
    deg = np.asarray(deg)
    vander = polynomial.polyvander2d(x, y, deg)
    vander = vander.reshape((-1, vander.shape[-1]))
    z = z.reshape((vander.shape[0], ))
    c = np.linalg.lstsq(vander, z)[0]
    return c.reshape(deg+1)
Esempio n. 13
0
 def polyfit2d(x, y, f, deg):
     from numpy.polynomial import polynomial
     import numpy as np
     x = np.asarray(x)
     y = np.asarray(y)
     f = np.asarray(f)
     deg = np.asarray(deg)
     vander = polynomial.polyvander2d(x, y, deg)
     vander = vander.reshape((-1, vander.shape[-1]))
     f = f.reshape((vander.shape[0], ))
     c = np.linalg.lstsq(vander, f)[0]
     return c.reshape(deg + 1)
Esempio n. 14
0
def polyfit2d(x, y, f, deg, mask=None):
    """
    Given coordinates and values, fit a polynomial and return parameters.

    Parameters
    ----------
    x : 1D array of coordinates
    y : 1D array of coordinates
    f : 1D array of expression results / data
    deg : degree of polynomial to fit

    Optional Parameters
    -------------------
    mask : 2D array of booleans to exclude factors of full polynomial

    Returns
    -------
    2D array with polynomial factors.
    """

    from numpy.polynomial import polynomial
    import numpy as np
    x = np.asarray(x)
    y = np.asarray(y)
    f = np.asarray(f)
    try:
        len(deg)
    except:
        deg = [deg, deg]
    deg = np.asarray(deg)
    vander = polynomial.polyvander2d(x, y, deg)
    # apply mask to delete terms if desired
    if mask != None:
        mask = np.asarray(mask).flatten()
        vander = vander.transpose()[mask].transpose()


#    vander = np.delete(vander, (7,8,9), 1)
#    vander = vander.reshape((-1,vander.shape[-1]))
#    f = f.reshape((vander.shape[0],))
    c = np.linalg.lstsq(vander, f)[0]
    # insert zeroes to deleted terms if a mask was applied to keep matrix order
    if mask != None:
        cc = np.zeros(mask.size)
        j = 0
        for i, item in enumerate(mask):
            if item:
                cc[i] = c[j]
                j += 1
    else:
        cc = c
    return cc.reshape(deg + 1)
Esempio n. 15
0
def polyfit2d(x, y, f, deg):
    '''
    Fits a 2d polynomyial of degree deg to the points f where f is the value of point [x,y]
    '''
    x = np.asarray(x)
    y = np.asarray(y)
    f = np.asarray(f)
    deg = np.asarray(deg)
    vander = polynomial.polyvander2d(x, y, deg)
    vander = vander.reshape((-1, vander.shape[-1]))
    f = f.reshape((vander.shape[0], ))
    c = np.linalg.lstsq(vander, f, rcond=None)[0]
    return c.reshape(deg + 1)
Esempio n. 16
0
def polyfit2d(x, y, f, deg):
    """
    Fit a 2D polynomial
    """
    x = np.asarray(x)
    y = np.asarray(y)
    f = np.asarray(f)
    deg = np.asarray(deg)
    vander = polynomial.polyvander2d(x, y, deg)
    vander = vander.reshape((-1, vander.shape[-1]))
    f = f.reshape((vander.shape[0], ))
    c = np.linalg.lstsq(vander, f, rcond=None)[0]
    return c.reshape(deg + 1)
Esempio n. 17
0
    def __polyfit2dvander(self, order):
        """
        Performs least square optimisation of a 2D polynomial,
        where a 2D Van der Monde-coefficient matrix is optimised.
        :param order: x and y order tuple
        :return: coefficient matrix of shape (x_order + 1, y_order + 1)
        """
        deg = np.asarray([order[0], order[1]])
        vander = polynomial.polyvander2d(self.x, self.y, deg)
        vander = vander.reshape((-1, vander.shape[-1]))
        f = self.z.reshape((vander.shape[0], ))
        c = np.linalg.lstsq(vander, f, rcond=0)[0]
        #self.c = c.reshape(deg + 1)

        return c.reshape(deg + 1)
Esempio n. 18
0
    def fit(self, X, y):
        # ndim = len(self.deg)
        orders = [n + 1 for n in self.deg]
        order = np.prod(orders)
        self._mean_X = np.mean(X, axis=0, keepdims=True)
        self._mean_y = np.mean(y)
        X_ = X - self._mean_X
        y_ = y - self._mean_y

        x0 = X_[:,0].reshape(-1, 1)
        x1 = X_[:,1].reshape(-1, 1)
        xb_all = polyvander2d(x0.ravel(), x1.ravel(), deg=self.deg).reshape(-1, order)
        # xb has shape (n, order) where order = (deg[0] +1 ) * (deg[1] +1)
        # x.reshape(-1, 1)  # shape = (nx, ny)  => Change into shape (n, 1) where n = nx*ny
        # so that xb is:
        # xb_all = [np.ones(n, 1), x**1  ,   x**2, ...  , x**deg[0], x**1 * y**1, x**2 * y**1,..., x**deg[0] * y**1,... , x**deg[0]*y**deg[1]]
        xb = xb_all[:, 1:]  # drop the constant term
        xtx_inv = np.linalg.pinv(xb.T.dot(xb) + self.lam * np.eye(order-1))
        # beta = [beta_00, beta_10,  beta_20, ..., beta_01       beta_11,  beta_21, ..., beta_20, beta_21,  beta_22, ...]
        beta = np.vstack((0.,
                          xtx_inv.dot(xb.T).dot(y_.reshape(-1, 1)))).reshape(orders)
        self.coefficients = beta

        if self.fulloutput:
            # beta has shape (deg[0] +1, deg[1] +1)
            yhat = polyval2d(x0, x1, beta) + self._mean_y
            # This equal to evaluating the following sum:  sum beta_ij * x**i * y**j for i=0,...deg[0], j=0, ..., deg[1]

            mean_sqared_error = mse(y, yhat)  #
            n = y.size
            sigma =  n * mean_sqared_error / (n-order) # Eq. after Eq. 3.9 on pp 47 in Hastie etal.
            beta_covariance = xtx_inv * sigma # Eq. 3.10 on pp 47 in Hastie etal.  # Is it valid for ridge?? Maybe missing a correction term when lam>0
            beta_variance = np.diag(beta_covariance) # .reshape(orders)

            std_error = np.sqrt(beta_variance)
            z_score = beta / std_error
            # 1-alpha confidence interval for beta. Eq 3.14 in Hastie
            z_alpha = -ss.norm.ppf(self.alpha/2)  # inverse of the gaussian cdf function (ss.norm.cdf(-z_alpha)==alpha/2), cdf = cumulative density function
            beta_low = beta - z_alpha * std_error
            beta_up = beta + z_alpha * std_error

            self.stats = fitstats(mse=mean_sqared_error,
                                  r2=r_squared(y, yhat),
                                  beta_variance=beta_variance,
                                  zscore=z_score,
                                  beta_low=beta_low,
                                  beta_up=beta_up)
        return self
        def _fit_lin_surface(zz, pixelsize):

            from numpy.polynomial import polynomial

            xx, yy = wpu.grid_coord(zz, pixelsize)

            f = zz.flatten()
            deg = np.array([1, 1])
            vander = polynomial.polyvander2d(xx.flatten(), yy.flatten(), deg)
            vander = vander.reshape((-1, vander.shape[-1]))
            f = f.reshape((vander.shape[0],))
            c = np.linalg.lstsq(vander, f)[0]

            print(c)

            return polynomial.polyval2d(xx, yy, c.reshape(deg+1))
Esempio n. 20
0
def newtForwardTransform(orders, locations, functionVals):
    if len(locations.shape)==1:
        return np.array(poly.polyfit(locations, functionVals, orders[0]))
    else:
        if locations.shape[1]==2:
            V=poly.polyvander2d(locations[:,0], locations[:,1], orders)
        elif locations.shape[1]==3:
            V=poly.polyvander3d(locations[:,0],locations[:,1],locations[:,2], orders)
        elif locations.shape[1]==4:
            V=newtVander4d(locations,orders)
        elif locations.shape[1]==5:
            V=newtVander5d(locations,orders)
        else:
            raise NotImplementedError # there's a bad startup joke about this being good enough for the paper.
        ret, _, _, _=npl.lstsq(V, functionVals, rcond=None)
        return np.reshape(ret, (np.array(orders)+1).flatten())
Esempio n. 21
0
def polyfit2d(x, y, z, order=5):
    """Takes x and y coordinates and their resultant z value, and creates a matrix where element i,j is the coefficient
    of the desired order polynomial x ** i * y ** j

    Arguments:
        x {np.array} -- flat array of x coordinates
        y {np.array} -- flat array of y coordinates
        z {np.array} -- flat array of z value at the corresponding x and y value
        order {int} -- max order of polynomial to work out

    Returns:
        np.array -- matrix of polynomial coefficients
    """
    deg = np.array([order, order])
    vander = polynomial.polyvander2d(x, y, deg)
    # vander matrix is matrix where each row i deals with x=x[i] and y=y[i], and each item in the
    # row has value x ** m * y ** n with (m,n) = (0,0), (0,1), (0,2) ... (1,0), (1,1), (1,2) etc up to (order, order)
    coeff_mat, _, _, _ = np.linalg.lstsq(vander, z, rcond=None)
    return coeff_mat.reshape(deg + 1)
Esempio n. 22
0
File: math.py Progetto: bedlamzd/vkr
def mls3d(data: np.ndarray, p=(0, 0), support_radius=1, deg=(0, 0)):
    """
    трехмерный moving least squares

    :param data: набор (x,y,z) точек для аппроксимации
    :param p: опорная точка
    :param support_radius: радиус влияния
    :param deg: степень полинома
    :return: коэффициенты полинома
    """
    B = polyvander2d(data[:, 0], data[:, 1], deg)
    rj = np.sqrt(np.sum(np.power(data[:, :2] - p[:2], 2), axis=1)) / support_radius
    W = np.diag(np.where(rj <= 1, 1 - 6 * rj ** 2 + 8 * rj ** 3 - 3 * rj ** 4, 0))
    try:
        c = inv(B.T @ W @ B) @ B.T @ W @ data[:, 2]
    except np.linalg.LinAlgError:
        print('f**k')
        return np.zeros((deg[0] + 1) * (deg[0] + 1))
    return c
Esempio n. 23
0
def polyfit2d(x, y, z, deg):
    '''
    Least-squares fit of a 2D polynomial to data. Uses Vandermonde
    matrices. 

    Return the coefficients of a polynomial of degree deg that is the
    least squares fit to the data values z given at points (x,y). Similar
    to numpy.polynomial.polynomial.polyfit but for 2D polynomials.
   
    Parameters
    ----------
    x : array_like, shape (M,)
        x-coordinates of the M sample (data) points (x[i], y[i], z[i]).
    y : array_like, shape (M,) 
        y-coordinates of the M sample (data) points (x[i], y[i], z[i]).
    z:  array_like, shape (M,) 
        z-coordinates of the sample (data) points (x[i], y[i], z[i]). 
    deg : 1-D array_like
        Degree(s) of the fitting polynomials. 

    Returns
    ----------
    coef : ndarray, shape (deg[0] + 1, deg[1] +1) 
        Polynomial coefficients ordered from low to high. 

    '''
    #DATA
    x = np.asarray(x)
    y = np.asarray(y)
    z = np.asarray(z)

    #Degrees of the polynomial
    deg = np.asarray(deg)

    vander = poly.polyvander2d(x, y, deg)
    vander = vander.reshape((-1, vander.shape[-1]))
    z = z.reshape((vander.shape[0], ))

    c, r, rank, s = np.linalg.lstsq(vander, z, rcond=None)

    return c.reshape(deg + 1), r, rank, s
Esempio n. 24
0
File: wcs.py Progetto: eso/xtool
    def polyfit2d(x, y, f, deg):
        """
        Fits a 2D polynomial and returns the coefficients
        Parameters
        ----------
        x : numpy.ndarray
        y : numpy.ndarray
        f : numpy.ndarray
        deg : tuple

        Returns
        -------
        poly_2d_coef : numpy.ndarray

        """
        deg = np.asarray(deg)
        vander = polynomial.polyvander2d(x, y, deg)
        vander = vander.reshape((-1, vander.shape[-1]))
        f = f.reshape((vander.shape[0],))
        c = np.linalg.lstsq(vander, f)[0]
        return c.reshape(deg + 1)
Esempio n. 25
0
    def polyfit2d(x, y, f, deg):
        """
        Fits a 2D polynomial and returns the coefficients
        Parameters
        ----------
        x : numpy.ndarray
        y : numpy.ndarray
        f : numpy.ndarray
        deg : tuple

        Returns
        -------
        poly_2d_coef : numpy.ndarray

        """
        deg = np.asarray(deg)
        vander = polynomial.polyvander2d(x, y, deg)
        vander = vander.reshape((-1, vander.shape[-1]))
        f = f.reshape((vander.shape[0], ))
        c = np.linalg.lstsq(vander, f)[0]
        return c.reshape(deg + 1)
Esempio n. 26
0
def polyfit2d(x, y, z, order):
    """Takes x and y coordinates and their resultant z value, and creates a
    matrix where element i,j is the coefficient of the desired order polynomial
     x ** i * y ** j

    Arguments:
        x (np.array): flat array of x coordinates
        y (np.array): flat array of y coordinates
        z (np.array): flat array of z value at the corresponding x and y value
        order (int): max order of polynomial to work out

    Returns:
        np.array: matrix of polynomial coefficients
    """
    logger.info('Fitting 2D surface to polynomial in x and y')
    deg = np.array([int(order), int(order)])
    vander = polynomial.polyvander2d(x, y, deg)
    # vander matrix is matrix where each row i deals with x=x[i] and y=y[i],
    # and each item in the row has value x ** m * y ** n with (m,n) = (0,0),
    # (0,1), (0,2) ... (1,0), (1,1), (1,2) etc up to (order, order)
    coeff_mat, _, _, _ = np.linalg.lstsq(vander, z, rcond=None)
    return coeff_mat.reshape(deg + 1)
Esempio n. 27
0
def polyfit2d(x, y, f, deg):
    """
    Performs a simple 2D polynomial fit using numpy.polyvander2d

    Input:
        x, y    - coordinate vectors
        f       - function value at respective coordinate tuple
        deg     - degrees of polynomial to be fitted, e.g. [2,2]
    Output:
        Array of polynomial coefficients
        
    History:
       2017     - Written - Anders (AIP)
    """
    x = np.asarray(x)
    y = np.asarray(y)
    f = np.asarray(f)
    deg = np.asarray(deg)
    vander = polynomial.polyvander2d(x, y, deg)
    vander = vander.reshape((-1, vander.shape[-1]))
    f = f.reshape((vander.shape[0], ))
    c = np.linalg.lstsq(vander, f, rcond=None)[0]
    return c.reshape(deg + 1)
Esempio n. 28
0
def polyfit2d(x, y, z, deg=1, grid=True, weight=None):
    '''
    polyfit2d(x, y, z, deg=1, grid=True):

    Fit a polynomial function to 2d data (x,y) with order <deg>, z is target data.

    Input:
        <x>,<y>: are 1d arrays
        <z>: target data value, can be 1d or 2d. If 2d, we flatten it to 1d
        <deg>: int, the highest polynomial order to use, default:1
        <grid>: boolean, optional. Whether x, y, z is a grid format. Then we
            convert it to normal array format. This is useful if we fit a polynomial
            to a 2d surface. In this case, z.size = x.size * y.size
        <weight>: same size with z, weight assigned for each data point
    Output:
        <coef>: 1d array, derived coefficients. See Note note below for the order
                    of coef
        <predz>: 1d array = z.size.
        <V>: power item design matrix.
        <residual>: residual of the model fitting

    We use numpy.polynomial.polynomial.polyvander to construct the polynomial
    design matrix V. However, this function construct a full array that only
    constrains the highest power for individual item (x, or, y). This leads to
    highest power in V to 2*deg, exceeding the <deg>. For example, if the input highest <deg>=2,
    then the item with highest order will be x2*y2 = 4.
    We use the numpy.tril to select appropriate item for fitting.

    Then polyfit2d is equivalent to solve the linear regression
    weight. We use scipy.linalg.lstsq to solve the equation

    The order of coef is correspond to the order of power items in
    the column of V. Thus np.dot(V,coef) should give the <predz>

    Note that the order is flattened version of mask. For example.
    If <deg>=2, x and y power should be [0, 1, 2]. The the order (x,y) should be (0,0)
    (0,1), (0.2), ... (2,0),(2,1),(2,2). Hence, the coef[0] is the coefficient for the
    constant item in the regression.Note that this is *DIFFERENT* from the output
    of numpy.polyfit, which the coefficient order is from high to low to their
    corresponding power item.

    x,y,z can have nan or inf value. But we do not include them when computing weight
    We directly return nan values in x, y, z

    Example:
        x, y = np.arange(10), np.arange(10)
        xx,yy = np.meshgrid
        z = 2* x^2 + x + 3*y^2
        plt.subplot(121)
        plt.imshow(z)

    History:
        20180628 RZ add <weight> input
        20180616 RZ double checked the function, it works very well.
        20180510 RZ created it

    To do:
        1. implement multi linear regression

    '''

    import numpy as np
    import scipy.linalg as linalg
    import scipy.sparse as sparse
    from numpy.polynomial.polynomial import polyvander2d

    # check input
    assert isinstance(x,
                      np.ndarray) and x.ndim == 1, 'x is not 1d np.npdarray!'
    assert isinstance(y,
                      np.ndarray) and y.ndim == 1, 'y is not 1d np.npdarray!'
    assert isinstance(z, np.ndarray), 'z must be an array'
    z = z.flatten()

    if weight is None:
        weight = np.ones(m.size)

    # convert if grid=True
    if grid:
        xsize, ysize = x.size, y.size
        xx, yy = np.meshgrid(x, y)
        x, y = xx.flatten(), yy.flatten()

    # deal with nan and inf values
    valid = np.isfinite(x) & np.isfinite(y) & np.isfinite(z)

    # obtain polymial order array V
    V = polyvander2d(x, y, deg=[deg, deg])

    # we want to set the lower right triangle of V to zero since those item exceeds
    # the highest order
    ii, jj = np.meshgrid(np.arange(deg + 1), np.arange(deg + 1))
    tt = ii + jj
    mask = tt.flatten() <= deg

    # remove the item that exceeds the order
    V = V[:, mask]

    # set the weight matrix
    if weight:
        W = sparse.diags(weight[valid])
        # directly solve the equation
        coef = linalg.inv(
            V[valid, :].T @ W @ V[valid, :]) @ V[valid, :].T @ W * m[valid]
        predz = np.dot(V, coef)
        residual = (weight[valid] * (predm[valid] - m[valid])**2).sum()
    else:
        coef, residual, _, _ = linalg.lstsq(V[valid, :], m[valid])
        predz = np.dot(V, coef)

    if grid:  # if grid case, we output a multi array
        predz = predz.reshape(xsize, ysize)

    return coef, predz, V, residual
Esempio n. 29
0
 #%% Invert with polymap for plane
 #
 #
 # Create active map to go from reduce set to full
 #actvMap = Maps.ActiveCells(mesh, actv, -100)
 #
 ## Creat reduced identity map
 #idenMap = Maps.IdentityMap(nP = nC)
 #
 XYZ = mesh.gridCC
 
 order = [1,1]
 
 YZ = Utils.ndgrid(mesh.vectorCCy, mesh.vectorCCz)
 
 V = polynomial.polyvander2d(YZ[:,0], YZ[:,1], order)
 
 #f = polynomial.polyval2d(XYZ[:,1], XYZ[:,2], c.reshape((order[0]+1,order[1]+1))) - XYZ[:,0]
 
 polymap = Maps.PolyMap(mesh, order, normal='X', logSigma=False, actInd = actv)
 polymap.slope = 1.0
 #polymap.actInd = actv
 
 #m0 = np.r_[1e-2, 0., 0.0, -0.5, 0.2, 0.]
 m0 = np.r_[1e-4, 0, 1., 0., 0., 0.]
 
 
 
 #Mesh.TensorMesh.writeModelUBC(mesh,home_dir+dsep+'True_m.sus',polymap*m0)
 #Mesh.TensorMesh.writeModelUBC(mesh,home_dir+dsep+'Starting_m.sus',actvMap*polymap*m0)
 
Esempio n. 30
0
 def vandermonde(self, points):
     """"""
     vander = polyvander2d(points[:, 0], points[:, 1],
                           [self.degree, self.degree])
     ulmask = CoeffPolynomial.upper_left_triangular_mask(self.degree)
     return vander[:, ulmask.ravel()]
Esempio n. 31
0
 #%% Invert with polymap for plane
 #
 #
 # Create active map to go from reduce set to full
 #actvMap = Maps.ActiveCells(mesh, actv, -100)
 #
 ## Creat reduced identity map
 #idenMap = Maps.IdentityMap(nP = nC)
 #
 XYZ = mesh.gridCC
 
 order = [1,1]
 
 YZ = Utils.ndgrid(mesh.vectorCCy, mesh.vectorCCz)
 
 V = polynomial.polyvander2d(YZ[:,0], YZ[:,1], order)
 
 #f = polynomial.polyval2d(XYZ[:,1], XYZ[:,2], c.reshape((order[0]+1,order[1]+1))) - XYZ[:,0]
 
 polymap = Maps.PolyMap(mesh, order, normal='X', logSigma=False, actInd = actv)
 polymap.slope = 1.0
 #polymap.actInd = actv
 
 #m0 = np.r_[1e-2, 0., 0.0, -0.5, 0.2, 0.]
 m0 = np.r_[1e-4, 0, 1., 0., 0., 0.]
 
 
 
 #Mesh.TensorMesh.writeModelUBC(mesh,home_dir+dsep+'True_m.sus',polymap*m0)
 #Mesh.TensorMesh.writeModelUBC(mesh,home_dir+dsep+'Starting_m.sus',actvMap*polymap*m0)