Example #1
0
    def train(self, X, f, weights=None):
        """Train the least-squares-fit polynomial approximation.

        Parameters
        ----------
        X : ndarray
            an ndarray of training points for the polynomial approximation. The 
            shape is M-by-m, where m is the number of dimensions.
        f : ndarray
            an ndarray of function values used to train the polynomial 
            approximation. The shape of `f` is M-by-1.
        weights : ndarray, optional 
            an ndarray of weights for the least-squares. (default is None, which
            means uniform weights)

        Notes
        -----
        This method sets all the attributes of the class for use in the 
        `predict` method.
        """
        X, f, M, m = process_inputs_outputs(X, f)

        # check that there are enough points to train the polynomial
        if M < comb(self.N + m, m):
            raise Exception(
                'Not enough points to fit response surface of order {:d}'.
                format(self.N))

        B, indices = polynomial_bases(X, self.N)
        p = B.shape[1]
        if weights is not None:
            B, f = weights * B, weights * f

        poly_weights = np.linalg.lstsq(B, f)[0]
        Rsqr = 1.0 - (np.linalg.norm(np.dot(B, poly_weights) - f)**2 /
                      (M * np.var(f)))

        # store data
        self.X, self.f = X, f
        self.poly_weights = poly_weights.reshape((p, 1))
        self.Rsqr = Rsqr

        # organize linear and quadratic coefficients
        self.g = poly_weights[1:m + 1].copy().reshape((m, 1))
        if self.N > 1:
            H = np.zeros((m, m))
            for i in range(m + 1, int(m + 1 + comb(m + 1, 2))):
                ind = indices[i, :]
                loc = np.nonzero(ind != 0)[0]
                if loc.size == 1:
                    H[loc, loc] = 2.0 * poly_weights[i]
                elif loc.size == 2:
                    H[loc[0], loc[1]] = poly_weights[i]
                    H[loc[1], loc[0]] = poly_weights[i]
                else:
                    raise Exception('Error creating quadratic coefficients.')
            self.H = H
    def train(self, X, f, weights=None):
        """Train the least-squares-fit polynomial approximation.

        Parameters
        ----------
        X : ndarray
            an ndarray of training points for the polynomial approximation. The 
            shape is M-by-m, where m is the number of dimensions.
        f : ndarray
            an ndarray of function values used to train the polynomial 
            approximation. The shape of `f` is M-by-1.
        weights : ndarray, optional 
            an ndarray of weights for the least-squares. (default is None, which
            means uniform weights)

        Notes
        -----
        This method sets all the attributes of the class for use in the 
        `predict` method.
        """
        X, f, M, m = process_inputs_outputs(X, f)

        # check that there are enough points to train the polynomial
        if M < comb(self.N + m, m):
            raise Exception('Not enough points to fit response surface of order {:d}'.format(self.N))

        B, indices = polynomial_bases(X,  self.N)
        p = B.shape[1]
        if weights is not None:
            B, f = weights*B, weights*f

        poly_weights = np.linalg.lstsq(B, f)[0]
        Rsqr = 1.0 - ( np.linalg.norm(np.dot(B, poly_weights) - f)**2 / (M*np.var(f)) )

        # store data
        self.X, self.f = X, f
        self.poly_weights = poly_weights.reshape((p,1))
        self.Rsqr = Rsqr

        # organize linear and quadratic coefficients
        self.g = poly_weights[1:m+1].copy().reshape((m,1))
        if self.N > 1:
            H = np.zeros((m, m))
            for i in range(m+1, int(m+1+comb(m+1,2))):
                ind = indices[i,:]
                loc = np.nonzero(ind!=0)[0]
                if loc.size==1:
                    H[loc,loc] = 2.0*poly_weights[i]
                elif loc.size==2:
                    H[loc[0],loc[1]] = poly_weights[i]
                    H[loc[1],loc[0]] = poly_weights[i]
                else:
                    raise Exception('Error creating quadratic coefficients.')
            self.H = H
    def train(self, X, f, weights=None):
        """
        Train the least-squares-fit polynomial approximation.

        :param ndarray X: An ndarray of training points for the polynomial
            approximation. The shape is M-by-m, where m is the number of
            dimensions.
        :param ndarray f: An ndarray of function values used to train the
            polynomial approximation. The shape of `f` is M-by-1.
        :param ndarray f: An ndarray of weights for the least-squares.

        **Notes**

        This method sets all the attributes of the class for use in the
        `predict` method.
        """
        X, f, M, m = process_inputs_outputs(X, f)

        # check that there are enough points to train the polynomial
        if M < comb(self.N + m, m):
            raise Exception('Not enough points to fit response surface of order {:d}'.format(self.N))

        logging.getLogger(__name__).debug('Training a degree {:d} polynomial in {:d} dims with {:d} points.'.format(self.N, m, M))

        B, indices = polynomial_bases(X,  self.N)
        p = B.shape[1]
        if weights is not None:
            B, f = weights*B, weights*f

        Q, R = np.linalg.qr(B)
        Qf = np.dot(Q.T, f)
        poly_weights = np.linalg.solve(R, Qf)
        Rsqr = 1.0 - ( np.linalg.norm(np.dot(R, poly_weights) - Qf)**2 / np.var(f) )

        # store data
        self.X, self.f = X, f
        self.poly_weights = poly_weights.reshape((p,1))
        self.Rsqr = Rsqr

        # organize linear and quadratic coefficients
        self.g = poly_weights[1:m+1].copy().reshape((m,1))
        if self.N > 1:
            H = np.zeros((m, m))
            for i in range(m+1, indices.shape[0]):
                ind = indices[i,:]
                loc = np.nonzero(ind!=0)[0]
                if loc.size==1:
                    H[loc,loc] = 2.0*poly_weights[i]
                elif loc.size==2:
                    H[loc[0],loc[1]] = poly_weights[i]
                    H[loc[1],loc[0]] = poly_weights[i]
                else:
                    raise Exception('Error creating quadratic coefficients.')
            self.H = H
    def train(self, X, f, v=None, e=None):
        """
        Train the radial basis approximation.

        :param ndarray X: An ndarray of training points for the polynomial
            approximation. The shape is M-by-m, where m is the number of
            dimensions.
        :parma ndarray f: An ndarray of function values used to train the
            polynomial approximation. The shape of `f` is M-by-1.
        :param ndarray v: Contains the regularization parameters that model
            error in the function values.
        :param ndarray e: An ndarray containing the eigenvalues from the active
            subspace analysis. If present, the radial basis uses it to
            determine the appropriate anisotropy in the length scales.

        **Notes**

        The approximation uses an multivariate, squared exponential radial
        basis. If `e` is not None, then the radial basis is anisotropic with
        length scales determined by `e`. Otherwise, the basis is isotropic.
        The length scale parameters (i.e., the rbf shape parameters) are
        determined with a maximum likelihood heuristic inspired by
        techniques for fitting a Gaussian process model.

        The approximation also includes a monomial basis with monomials of
        total degree up to order `N`. These are fit with weighted least-squares,
        where the weight matrix is the inverse of the matrix of radial basis
        functions evaluated at the training points.

        This method sets all the attributes of the class for use in the
        `predict` method.
        """
        X, f, M, m = process_inputs_outputs(X, f)

        # check that there are enough points to train the polynomial
        if M < comb(self.N + m, m):
            raise Exception('Not enough points to fit response surface of order {:d}'.format(self.N))

        logging.getLogger(__name__).debug('Training an RBF surface with degree {:d} polynomial in {:d} dims with {:d} points.'.format(self.N, m, M))

        # use maximum likelihood to tune parameters
        log10g = fminbound(rbf_objective, -10.0, 1.0, args=(X, f, v, self.N, e, ))
        g = 10**(log10g)

        if e is None:
            ell = g*np.ones((m,1))
            if v is None:
                v = 1e-6*np.ones(f.shape)
        else:
            ell = g*np.sum(e)/e[:m]
            if v is None:
                v = g*np.sum(e[m:])*np.ones(f.shape)

        # covariance matrix of observations
        K = exponential_squared(X, X, 1.0, ell)
        K += np.diag(v.reshape((M,)))
        B = polynomial_bases(X, self.N)[0]
        p = B.shape[1]

        C = np.hstack(( np.vstack(( K, B.T )), np.vstack(( B, np.zeros((p, p)) )) ))
        weights = np.linalg.solve(C, np.vstack(( f, np.zeros((p, 1)) )) )

        radial_weights, poly_weights = weights[:M], weights[M:]

        res = f - np.dot(B, poly_weights)
        Rsqr = 1.0 - (np.dot( res.T, np.linalg.solve(K, res)) / np.dot( f.T, np.linalg.solve(K, f) ))

        # store parameters
        self.X, self.f = X, f
        self.ell, self.K = ell, K
        self.Rsqr = Rsqr[0,0]
        self.radial_weights, self.poly_weights = radial_weights, poly_weights
Example #5
0
    def train(self, X, f, v=None, e=None):
        """Train the radial basis approximation.

        Parameters
        ----------
        X : ndarray
            an ndarray of training points for the polynomial approximation. The 
            shape is M-by-m, where m is the number of dimensions.
        f : ndarray
            an ndarray of function values used to train the polynomial 
            approximation. The shape of `f` is M-by-1.
        v : ndarray, optional
            contains the regularization parameters that model error in the 
            function values (default None)
        e : ndarray, optional
            an ndarray containing the eigenvalues from the active subspace 
            analysis. If present, the radial basis uses it to determine the 
            appropriate anisotropy in the length scales. (default None)

        Notes
        -----
        The approximation uses an multivariate, squared exponential radial
        basis. If `e` is not None, then the radial basis is anisotropic with
        length scales determined by `e`. Otherwise, the basis is isotropic.
        The length scale parameters (i.e., the rbf shape parameters) are
        determined with a maximum likelihood heuristic inspired by
        techniques for fitting a Gaussian process model.

        The approximation also includes a monomial basis with monomials of
        total degree up to order `N`. These are fit with weighted least-squares,
        where the weight matrix is the inverse of the matrix of radial basis
        functions evaluated at the training points.

        This method sets all the attributes of the class for use in the
        `predict` method.
        """
        X, f, M, m = process_inputs_outputs(X, f)

        # check that there are enough points to train the polynomial
        if M < comb(self.N + m, m):
            raise Exception(
                'Not enough points to fit response surface of order {:d}'.
                format(self.N))

        # use maximum likelihood to tune parameters
        log10g = fminbound(_rbf_objective,
                           -10.0,
                           1.0,
                           args=(
                               X,
                               f,
                               v,
                               self.N,
                               e,
                           ))
        g = 10**(log10g)

        if e is None:
            ell = g * np.ones((m, 1))
            if v is None:
                v = 1e-6 * np.ones(f.shape)
        else:
            ell = g * np.sum(e) / e[:m]
            if v is None:
                v = g * np.sum(e[m:]) * np.ones(f.shape)

        # ensure conditioning
        v = np.amax([v.reshape(f.shape), 1e-6 * np.ones(f.shape)], axis=0)

        # covariance matrix of observations
        K = exponential_squared(X, X, 1.0, ell)
        K += np.diag(v.reshape((M, )))
        B = polynomial_bases(X, self.N)[0]
        p = B.shape[1]

        C = np.hstack((np.vstack((K, B.T)), np.vstack((B, np.zeros((p, p))))))
        weights = np.linalg.solve(C, np.vstack((f, np.zeros((p, 1)))))

        radial_weights, poly_weights = weights[:M], weights[M:]

        res = f - np.dot(B, poly_weights)
        Rsqr = 1.0 - (np.dot(res.T, np.linalg.solve(K, res)) /
                      np.dot(f.T, np.linalg.solve(K, f)))

        # store parameters
        self.X, self.f = X, f
        self.ell, self.K = ell, K
        self.Rsqr = Rsqr[0, 0]
        self.radial_weights, self.poly_weights = radial_weights, poly_weights