示例#1
0
    def test_compute_kle_gradient_from_mesh_gradient(self):
        nvars, sigma = 2, 3
        length_scale = 1
        mesh = np.linspace(0., 1., 11)[None, :]
        kle_mean = mesh[0, :] + 2

        for use_log in [False, True]:
            kle = MeshKLE(mesh, kle_mean, use_log)
            kle.compute_basis(length_scale, sigma, nvars)

            def scalar_function_of_field(field):
                return np.dot(field[:, 0], field[:, 0])

            sample = np.random.normal(0., 1., (nvars, 1))
            kle_vals = kle(sample)

            from pyapprox.optimization import approx_jacobian
            mesh_gradient = kle_vals.T * 2
            assert np.allclose(mesh_gradient,
                               approx_jacobian(scalar_function_of_field,
                                               kle_vals),
                               atol=1e-7)

            gradient = compute_kle_gradient_from_mesh_gradient(
                mesh_gradient, kle.eig_vecs, kle.mean_field, kle.use_log,
                sample[:, 0])

            def scalar_function_of_sample(sample):
                field = kle(sample)
                return scalar_function_of_field(field)

            fd_gradient = approx_jacobian(scalar_function_of_sample, sample)
            # print((fd_gradient, gradient))
            assert np.allclose(fd_gradient, gradient)
    def test_1_layer_gradient_wrt_inputs(self):
        nqoi, nvars = 2, 3
        A = np.random.normal(0, 1, (nqoi, nvars))
        b = np.random.normal(0, 1, (nqoi, 1))

        def fun(x):
            return sigmoid_function(A.dot(x) + b)

        def jac(x):
            return sigmoid_gradient(A.dot(x) + b) * A
            # return np.diag(sigmoid_gradient(A.dot(x)+b)[:, 0]).dot(A)

        x0 = np.random.normal(0, 1, (nvars, 1))
        assert np.allclose(approx_jacobian(fun, x0), jac(x0))

        def g(x):
            return sigmoid_function(x)[:, None]

        assert np.allclose(
            _approx_fprimeprime(x0[:, 0], g, 1e-4)[:, 0, :],
            approx_jacobian(sigmoid_gradient, x0[:, 0]))
        assert np.allclose(
            np.diag(approx_jacobian(sigmoid_gradient, x0[:, 0])),
            sigmoid_second_derivative(x0)[:, 0])

        def f(x):
            x = x[:, None]
            return fun(x)

        def hess(x):
            return sigmoid_second_derivative(A.dot(x) + b) * A**2

        assert np.allclose(hess(x0),
                           _approx_fprimeprime(x0[:, 0], f, 1e-4)[:, 0, :])
示例#3
0
    def test_pce_jacobian(self):
        degree = 2

        alpha_stat, beta_stat = 2, 3
        univariate_variables = [beta(alpha_stat, beta_stat, 0, 1), norm(-1, 2)]
        variable = IndependentMultivariateRandomVariable(univariate_variables)
        var_trans = AffineRandomVariableTransformation(variable)
        num_vars = len(univariate_variables)

        poly = PolynomialChaosExpansion()
        poly_opts = define_poly_options_from_variable_transformation(var_trans)
        poly.configure(poly_opts)

        indices = compute_hyperbolic_indices(num_vars, degree, 1.0)
        poly.set_indices(indices)

        sample = generate_independent_random_samples(variable, 1)

        coef = np.ones((indices.shape[1], 2))
        coef[:, 1] *= 2
        poly.set_coefficients(coef)

        jac = poly.jacobian(sample)
        from pyapprox.optimization import approx_jacobian
        fd_jac = approx_jacobian(lambda x: poly(x[:, np.newaxis])[0, :],
                                 sample[:, 0])
        assert np.allclose(jac, fd_jac)
 def test_emax_model(self):
     from pyapprox.optimization import approx_jacobian
     theta = np.ones(3)*0.5
     samples = np.random.uniform(1,2,(1,2))
     fd_jac = approx_jacobian(emax_model,theta,samples)
     jac = emax_model_grad_parameters(theta,samples)
     assert np.allclose(jac.T,fd_jac)
 def test_michaelis_menten_model(self):
     from pyapprox.optimization import approx_jacobian
     theta = np.ones(2)*0.5
     samples = np.random.uniform(1,2,(1,3))
     fd_jac = approx_jacobian(michaelis_menten_model,theta,samples)
     jac = michaelis_menten_model_grad_parameters(theta,samples)
     assert np.allclose(jac.T,fd_jac)
    def test_smooth_l1_norm_gradients(self):
        #x = np.linspace(-1,1,101)
        #t = np.ones_like(x)
        #r = 1e1
        #plt.plot(x,kouri_smooth_absolute_value(t,r,x))
        #plt.show()

        t = np.ones(5);r=1
        init_guess = np.random.normal(0,1,(t.shape[0]))
        func = partial(kouri_smooth_l1_norm,t,r)
        jac  = partial(kouri_smooth_l1_norm_gradient,t,r)
        errors = check_gradients(func,jac,init_guess,disp=False)
        assert errors.min()<3e-7

        fd_hess = approx_jacobian(jac,init_guess)
        assert np.allclose(fd_hess,kouri_smooth_l1_norm_hessian(t,r,init_guess))
示例#7
0
    def test_nonlinear_basis_pursuit(self):
        np.random.seed(1)
        nsamples, degree, sparsity = 7, 7, 2
        samples = np.random.uniform(0, 1, (1, nsamples))
        basis_matrix = samples.T**np.arange(degree + 1)[np.newaxis, :]

        def model(x):
            val = basis_matrix.dot(x[:-1]) * np.exp(samples[0, :] * x[-1])
            grad = np.hstack([
                basis_matrix * np.exp(samples[0, :] * x[-1])[:, np.newaxis],
                (samples[0, :] * val)[:, np.newaxis]
            ])
            return val, grad

        true_coef = np.zeros(basis_matrix.shape[1] + 1)
        true_coef[np.random.permutation(true_coef.shape[0] - 1)[:sparsity -
                                                                1]] = 1.
        true_coef[-1] = 1
        vals = model(true_coef)[0]

        def func(x):
            model_vals, grad = model(x)
            return model_vals - vals, grad

        jac = True
        hess = None

        init_guess = true_coef + np.random.normal(0, 1, true_coef.shape[0])
        fd_jac = approx_jacobian(lambda x: model(x)[0],
                                 init_guess,
                                 epsilon=1e-7)
        analytical_jac = model(init_guess)[1]
        #print(analytical_jac-fd_jac)
        assert np.allclose(analytical_jac, fd_jac, atol=1e-8)

        tol = 1e-12
        options = {
            'ftol': tol,
            'verbose': 2,
            'disp': True,
            'xtol': tol,
            'maxiter': 1000
        }
        init_guess = true_coef + np.random.normal(0, 1, true_coef.shape[0])
        l1_coef = nonlinear_basis_pursuit(func, jac, hess, init_guess, options)
        print(np.linalg.norm(true_coef - l1_coef))
        assert np.allclose(l1_coef, true_coef, atol=2e-6)
示例#8
0
 def test_conditional_value_at_risk_gradient(self):
     N = 6
     p = np.ones(N) / N
     X = np.random.normal(0, 1, N)
     #X = np.arange(1,N+1)
     X = np.sort(X)
     beta = 7 / 12
     beta = 2 / 3
     i_beta_exact = 3
     VaR_exact = X[i_beta_exact]
     cvar_exact = 1 / 5 * VaR_exact + 2 / 5 * (np.sort(X)[i_beta_exact +
                                                          1:]).sum()
     cvar_grad = conditional_value_at_risk_gradient(X, beta)
     from pyapprox.optimization import approx_jacobian
     func = partial(conditional_value_at_risk, alpha=beta)
     cvar_grad_fd = approx_jacobian(func, X)
     assert np.allclose(cvar_grad, cvar_grad_fd, atol=1e-7)
示例#9
0
    def test_smooth_l1_norm_gradients(self):
        #x = np.linspace(-1,1,101)
        #t = np.ones_like(x)
        #r = 1e1
        #plt.plot(x,kouri_smooth_absolute_value(t,r,x))
        #plt.show()
        from pyapprox.optimization import \
            ScipyMinimizeObjectiveAsPyapproxFunction,\
            ScipyMinimizeObjectiveJacAsPyapproxJac

        t = np.ones(5)
        r = 1
        init_guess = np.random.normal(0, 1, (t.shape[0], 1))
        func = ScipyMinimizeObjectiveAsPyapproxFunction(
            partial(kouri_smooth_l1_norm, t, r))
        jac = partial(kouri_smooth_l1_norm_gradient, t, r)
        pya_jac = ScipyMinimizeObjectiveJacAsPyapproxJac(jac)
        errors = check_gradients(func, pya_jac, init_guess, disp=False)
        assert errors.min() < 3e-7

        fd_hess = approx_jacobian(jac, init_guess[:, 0])
        assert np.allclose(fd_hess,
                           kouri_smooth_l1_norm_hessian(t, r, init_guess))
示例#10
0
    def test_advection_diffusion_base_class_adjoint(self):
        nvars, corr_len = 2, 0.1
        benchmark = setup_advection_diffusion_benchmark(nvars=nvars,
                                                        corr_len=corr_len,
                                                        max_eval_concurrency=1)
        model = benchmark.fun
        #random_samples = np.zeros((nvars,1))
        random_samples = -np.sqrt(3) * np.ones((nvars, 1))
        config_samples = 3 * np.ones((3, 1))
        samples = np.vstack([random_samples, config_samples])
        bmodel = model.base_model
        qoi = bmodel(samples)
        assert np.all(np.isfinite(qoi))
        sol = bmodel.solve(samples)

        grad = qoi_functional_grad_misc(sol, bmodel)

        kappa = bmodel.kappa
        J = dl_qoi_functional_misc(sol)
        control = dla.Control(kappa)
        Jhat = dla.ReducedFunctional(J, control)
        h = dla.Function(kappa.function_space())
        h.vector()[:] = np.random.normal(0, 1, kappa.function_space().dim())
        conv_rate = dla.taylor_test(Jhat, kappa, h)
        assert np.allclose(conv_rate, 2.0, atol=1e-3)

        # Check that gradient with respect to kappa is calculated correctly
        # this requires passing in entire kappa vector and not just variables
        # used to compute the KLE.
        from pyapprox.optimization import check_gradients
        from pyapprox.models.wrappers import SingleFidelityWrapper
        from functools import partial

        init_condition, boundary_conditions, function_space, beta, \
            forcing, kappa = bmodel.initialize_random_expressions(
                random_samples[:, 0])

        def fun(np_kappa):
            dt = 0.1
            fn_kappa = dla.Function(function_space)
            fn_kappa.vector()[:] = np_kappa[:, 0]
            bmodel.kappa = fn_kappa
            sol = run_model(
                function_space,
                fn_kappa,
                forcing,
                init_condition,
                dt,
                bmodel.final_time,
                boundary_conditions,
                velocity=beta,
                second_order_timestepping=bmodel.second_order_timestepping,
                intermediate_times=bmodel.options.get('intermediate_times',
                                                      None))
            vals = np.atleast_1d(bmodel.qoi_functional(sol))
            if vals.ndim == 1:
                vals = vals[:, np.newaxis]
            grad = bmodel.qoi_functional_grad(sol, bmodel)
            return vals, grad

        kappa = bmodel.get_diffusivity(random_samples[:, 0])
        x0 = dla.project(kappa, function_space).vector()[:].copy()[:, None]
        check_gradients(fun, True, x0)

        # Test that gradient with respect to kle coefficients is correct

        from pyapprox.karhunen_loeve_expansion import \
            compute_kle_gradient_from_mesh_gradient
        vals, jac = bmodel(samples, jac=True)

        # Extract mean field and KLE basis from expression
        # TODO add ability to compute gradient of kle to
        # nobile_diffusivity_fenics_class
        kle = bmodel.get_diffusivity(np.zeros(random_samples.shape[0]))
        mean_field_fn = dla.Function(function_space)
        mean_field_fn = dla.interpolate(kle, function_space)
        mean_field = mean_field_fn.vector()[:].copy() - np.exp(1)

        mesh_coords = function_space.tabulate_dof_coordinates()[:, 0]
        I = np.argsort(mesh_coords)
        basis_matrix = np.empty((mean_field.shape[0], random_samples.shape[0]))
        exact_basis_matrix = np.array([
            mesh_coords * 0 + 1,
            np.sin((2) / 2 * np.pi * mesh_coords / bmodel.options['corr_len'])
        ]).T
        for ii in range(random_samples.shape[0]):
            zz = np.zeros(random_samples.shape[0])
            zz[ii] = 1.0
            kle = bmodel.get_diffusivity(zz)
            field_fn = dla.Function(function_space)
            field_fn = dla.interpolate(kle, function_space)
            # 1e-15 used to avoid taking log of zero
            basis_matrix[:, ii] = np.log(field_fn.vector()[:].copy() -
                                         mean_field + 1e-15) - 1

        assert np.allclose(
            mean_field + np.exp(1 + basis_matrix.dot(random_samples[:, 0])),
            x0[:, 0])

        # nobile diffusivity uses different definitions of KLE
        # k = np.exp(1+basis_matrix.dot(coef))+mean_field
        # than that assumed in compute_kle_gradient_from_mesh_gradient
        # k = np.exp(basis_matrix.dot(coef)+mean_field)
        # So to
        # keep current interface set mean field to zero and then correct
        # returned gradient
        grad = compute_kle_gradient_from_mesh_gradient(jac, basis_matrix,
                                                       mean_field * 0, True,
                                                       random_samples[:, 0])
        grad *= np.exp(1)

        from pyapprox.optimization import approx_jacobian
        fun = SingleFidelityWrapper(bmodel, config_samples[:, 0])
        fd_grad = approx_jacobian(fun, random_samples)

        # print(grad, fd_grad)
        assert np.allclose(grad, fd_grad)
示例#11
0
    def help_test_stochastic_dominance_gradients(self, sd_opt_problem):

        np.random.seed(1)
        xx = sd_opt_problem.init_guess
        if hasattr(sd_opt_problem, "eps"):
            # smoothers often only have nonzero derivative is a region or
            # diameter epsilon
            xx[0] -= sd_opt_problem.eps / 3

        from pyapprox.optimization import approx_jacobian
        fd_jacobian = approx_jacobian(sd_opt_problem.objective,
                                      xx,
                                      epsilon=1e-8)
        jacobian = sd_opt_problem.objective_jacobian(xx)
        #check_gradients(
        #    sd_opt_problem.objective,sd_opt_problem.objective_jacobian,xx,False)
        #print('jac ex',fd_jacobian)
        #print('jac fd',jacobian)
        assert np.allclose(fd_jacobian, jacobian, atol=1e-7)

        fd_jacobian = approx_jacobian(sd_opt_problem.nonlinear_constraints, xx)
        jacobian = sd_opt_problem.nonlinear_constraints_jacobian(xx)
        if hasattr(jacobian, 'todense'):
            jacobian = jacobian.todense()
        #print('jac ex',fd_jacobian)
        #print('jac fd',jacobian)
        msg = 'change x, current value is not an effective test'
        #check_gradients(
        #    sd_opt_problem.nonlinear_constraints,
        #    sd_opt_problem.nonlinear_constraints_jacobian,xx,False)
        assert not np.all(np.absolute(jacobian) < 1e-15), msg
        assert np.allclose(fd_jacobian, jacobian, atol=1e-7)

        if hasattr(sd_opt_problem, 'objective_hessian'):
            hessian = sd_opt_problem.objective_hessian(xx)
            fd_hessian = approx_jacobian(sd_opt_problem.objective_jacobian, xx)
            if hasattr(hessian, 'todense'):
                hessian = hessian.todense()
            assert np.allclose(hessian, fd_hessian)

        if hasattr(sd_opt_problem, 'define_nonlinear_constraint_hessian'):
            at_least_one_hessian_nonzero = False
            for ii in range(sd_opt_problem.nnl_constraints):

                def grad(xx):
                    row = sd_opt_problem.nonlinear_constraints_jacobian(xx)[
                        ii, :]
                    if hasattr(row, 'todense'):
                        row = np.asarray(row.todense())[0, :]
                    return row

                fd_hessian = approx_jacobian(grad, xx)
                hessian = sd_opt_problem.define_nonlinear_constraint_hessian(
                    xx, ii)
                #np.set_printoptions(linewidth=1000)
                #print('h',hessian)
                #print('h_fd',fd_hessian)
                if hessian is None:
                    assert np.allclose(fd_hessian,
                                       np.zeros_like(fd_hessian),
                                       atol=1e-7)
                else:
                    if hasattr(hessian, 'todense'):
                        hessian = hessian.todense()
                    assert np.allclose(hessian,
                                       fd_hessian,
                                       atol=1e-7,
                                       rtol=1e-1)
                    if not at_least_one_hessian_nonzero:
                        at_least_one_hessian_nonzero = np.any(
                            np.absolute(hessian) < 1e-15)
                    at_least_one_hessian_nonzero = True

            if not at_least_one_hessian_nonzero:
                msg = 'change x, current value is not an effective test'
                assert False, msg

        return sd_opt_problem