def setUp(self): self.md = (gr.Model() >> gr.cp_function( fun=lambda x: x, var=1, out=1, runtime=1) >> gr.cp_marginals(x0={ "dist": "uniform", "loc": 0, "scale": 1 }) >> gr.cp_copula_independence()) self.md_2d = (gr.Model() >> gr.cp_function( fun=lambda x: x[0], var=2, out=1) >> gr.cp_marginals( x0={ "dist": "uniform", "loc": 0, "scale": 1 }, x1={ "dist": "uniform", "loc": 0, "scale": 1 }, ) >> gr.cp_copula_independence()) self.md_mixed = (gr.Model() >> gr.cp_function( fun=lambda x: x[0] + x[1], var=2, out=1) >> gr.cp_bounds(x0=(-1, +1)) >> gr.cp_marginals(x1={ "dist": "uniform", "loc": 0, "scale": 1 }, ) >> gr.cp_copula_independence())
def setUp(self): ## Smooth model self.md_smooth = (gr.Model() >> gr.cp_function( fun=lambda x: [x, x + 1], var=["x"], out=["y", "z"]) >> gr.cp_marginals(x={ "dist": "uniform", "loc": 0, "scale": 2 }) >> gr.cp_copula_independence()) self.df_smooth = self.md_smooth >> gr.ev_df( df=pd.DataFrame(dict(x=[0, 1, 2]))) ## Tree model self.md_tree = (gr.Model() >> gr.cp_function( fun=lambda x: [0, x < 5], var=["x"], out=["y", "z"]) >> gr.cp_marginals(x={ "dist": "uniform", "loc": 0, "scale": 2 }) >> gr.cp_copula_independence()) self.df_tree = self.md_tree >> gr.ev_df( df=pd.DataFrame(dict(x=np.linspace(0, 10, num=8)))) ## Cluster model self.df_cluster = pd.DataFrame( dict( x=[0.1, 0.2, 0.3, 0.4, 1.1, 1.2, 1.3, 1.4], y=[0.3, 0.2, 0.1, 0.0, 1.3, 1.2, 1.1, 1.0], c=[0, 0, 0, 0, 1, 1, 1, 1], ))
def setUp(self): # Default model self.df_wrong = pd.DataFrame(data={"z": [0.0, 1.0]}) # 2D identity model with permuted df inputs domain_2d = gr.Domain(bounds={"x0": [-1.0, +1.0], "x1": [0.0, 1.0]}) marginals = {} marginals["x0"] = gr.MarginalNamed(d_name="uniform", d_param={ "loc": -1, "scale": 2 }) marginals["x1"] = gr.MarginalNamed( sign=-1, d_name="uniform", d_param={ "loc": 0, "scale": 1 }, ) self.model_2d = gr.Model( functions=[ gr.Function(lambda x: [x[0], x[1]], ["x0", "x1"], ["y0", "y1"], "test", 0), ], domain=domain_2d, density=gr.Density(marginals=marginals), ) self.df_2d = pd.DataFrame(data={"x1": [0.0], "x0": [+1.0]}) self.res_2d = self.model_2d.evaluate_df(self.df_2d) self.df_median_in = pd.DataFrame({"x0": [0.5], "x1": [0.5]}) self.df_median_out = pd.DataFrame({"x0": [0.0], "x1": [0.5]}) self.model_3d = gr.Model( functions=[ gr.Function(lambda x: x[0] + x[1] + x[2], ["x", "y", "z"], ["f"], "test", 0) ], density=gr.Density(marginals=marginals), ) ## Timing check self.model_slow = gr.Model(functions=[ gr.Function(lambda x: x, ["x0"], ["y0"], "f0", 1), gr.Function(lambda x: x, ["x0"], ["y1"], "f1", 1), ])
def test_grad_fd(self): """Checks the FD code """ ## Accuracy df_grad = gr.eval_grad_fd( self.model_2d, df_base=self.df_2d_nominal, append=False ) self.assertTrue(np.allclose(df_grad[self.df_2d_grad.columns], self.df_2d_grad)) ## Subset df_grad_sub = gr.eval_grad_fd( self.model_2d, df_base=self.df_2d_nominal, var=["x"], append=False ) self.assertTrue(set(df_grad_sub.columns) == set(["Df_Dx", "Dg_Dx"])) ## Flags md_test = ( gr.Model() >> gr.cp_function(fun=lambda x: x[0] + x[1] ** 2, var=2, out=1) >> gr.cp_marginals(x0={"dist": "norm", "loc": 0, "scale": 1}) ) df_base = pd.DataFrame(dict(x0=[0, 1], x1=[0, 1])) ## Multiple base points df_true = pd.DataFrame(dict(Dy0_Dx0=[1, 1], Dy0_Dx1=[0, 2])) df_rand = gr.eval_grad_fd(md_test, df_base=df_base, var="rand", append=False) self.assertTrue(gr.df_equal(df_true[["Dy0_Dx0"]], df_rand, close=True)) df_det = gr.eval_grad_fd(md_test, df_base=df_base, var="det", append=False) self.assertTrue(gr.df_equal(df_true[["Dy0_Dx1"]], df_det, close=True))
def setUp(self): # 2D identity model with permuted df inputs domain_2d = gr.Domain(bounds={"x": [-1.0, +1], "y": [0.0, 1.0]}) marginals = {} marginals["x"] = gr.MarginalNamed( d_name="uniform", d_param={"loc": -1, "scale": 2} ) marginals["y"] = gr.MarginalNamed( sign=-1, d_name="uniform", d_param={"loc": 0, "scale": 1} ) self.model_2d = gr.Model( functions=[ gr.Function(lambda x: [x[0], x[1]], ["x", "y"], ["f", "g"], "test", 0) ], domain=domain_2d, density=gr.Density( marginals=marginals, copula=gr.CopulaIndependence(var_rand=["x"]) ), ) ## Correct results self.df_2d_nominal = pd.DataFrame( data={"x": [0.0], "y": [0.5], "f": [0.0], "g": [0.5]} ) self.df_2d_grad = pd.DataFrame( data={"Df_Dx": [1.0], "Dg_Dx": [0.0], "Df_Dy": [0.0], "Dg_Dy": [1.0]} ) self.df_2d_qe = pd.DataFrame( data={"x": [0.0], "y": [0.1], "f": [0.0], "g": [0.1]} )
def setUp(self): self.md = (gr.Model() >> gr.cp_function( fun=lambda x: x, var=["x"], out=["y"], ) >> gr.cp_marginals(x=dict(dist="norm", loc=0, scale=1)) >> gr.cp_copula_independence())
def test_gauss_copula(self): md = gr.Model() >> gr.cp_marginals( E=gr.marg_fit("norm", data.df_stang.E), mu=gr.marg_fit("beta", data.df_stang.mu), thick=gr.marg_fit("uniform", data.df_stang.thick), ) df_corr = gr.tran_copula_corr(data.df_stang, model=md)
def test_transforms(self): ## Setup df_corr = pd.DataFrame(dict(var1=["x"], var2=["y"], corr=[0.5])) Sigma_h = np.linalg.cholesky(np.array([[1.0, 0.5], [0.5, 1.0]])) md = ( gr.Model() >> gr.cp_marginals(x=dict(dist="norm", loc=0, scale=1), y=dict(dist="norm", loc=0, scale=1)) >> gr.cp_copula_gaussian(df_corr=df_corr)) ## Copula and marginals have same var_rand order self.assertTrue( list(md.density.marginals) == md.density.copula.var_rand) ## Transforms invariant z = np.array([0, 0]) x = md.z2x(z) zp = md.x2z(x) self.assertTrue(np.all(z == zp)) df_z = gr.df_make(x=0.0, y=0.0) df_x = md.norm2rand(df_z) df_zp = md.rand2norm(df_x) self.assertTrue(gr.df_equal(df_z, df_zp)) ## Jacobian accurate dxdz_fd = np.zeros((2, 2)) dxdz_fd[0, :] = (md.z2x(z + np.array([h, 0])) - md.z2x(z)) / h dxdz_fd[1, :] = (md.z2x(z + np.array([0, h])) - md.z2x(z)) / h dxdz_p = md.dxdz(z) self.assertTrue(np.allclose(dxdz_fd, dxdz_p))
def test_gauss_copula(self): md = gr.Model() >> gr.cp_marginals( E=gr.marg_named(data.df_stang.E, "norm"), mu=gr.marg_named(data.df_stang.mu, "beta"), thick=gr.marg_named(data.df_stang.thick, "uniform"), ) df_corr = gr.tran_copula_corr(data.df_stang, model=md)
def test_nls(self): ## Setup md_feat = ( gr.Model() >> gr.cp_function(fun=lambda x: x[0] * x[1] + x[2], var=3, out=1,) >> gr.cp_bounds(x0=[-1, +1], x2=[0, 0]) >> gr.cp_marginals(x1=dict(dist="norm", loc=0, scale=1)) ) md_const = ( gr.Model() >> gr.cp_function(fun=lambda x: x[0], var=1, out=1) >> gr.cp_bounds(x0=(-1, +1)) ) df_response = md_feat >> gr.ev_df( df=gr.df_make(x0=0.1, x1=[-1, -0.5, +0, +0.5, +1], x2=0) ) df_data = df_response[["x1", "y0"]] ## Model with features df_true = gr.df_make(x0=0.1) df_fit = md_feat >> gr.ev_nls(df_data=df_data, append=False) pd.testing.assert_frame_equal( df_fit, df_true, check_exact=False, check_dtype=False, check_column_type=False, ) ## Fitting synonym md_feat_fit = df_data >> gr.ft_nls(md=md_feat, verbose=False) self.assertTrue(set(md_feat_fit.var) == set(["x1", "x2"])) ## Constant model df_const = gr.df_make(x0=0) df_fit = md_const >> gr.ev_nls(df_data=gr.df_make(y0=[-1, 0, +1])) pd.testing.assert_frame_equal( df_fit, df_const, check_exact=False, check_dtype=False, check_column_type=False, )
def __init__(self): """Setup necessary values""" self.md = (gr.Model() >> gr.cp_function( fun=lambda x: x, var=1, out=1, runtime=1)) self.md_var_det = self.md >> gr.cp_bounds(x1=(0, 1)) self.df = pd.DataFrame(data={"x": [0.0], "y": [0.5]}) # declare tests self.type_tests = [(1, 2), 2, [1, 8]]
def test_drop_out(self): """Checks that output column names are properly dropped""" md = gr.Model() >> gr.cp_function(lambda x: x[0] + 1, var=1, out=1) df_in = gr.df_make(x0=[0, 1, 2], y0=[0, 1, 2]) df_true = gr.df_make(x0=[0, 1, 2], y0=[1, 2, 3]) df_res = md >> gr.ev_df(df=df_in) self.assertTrue(gr.df_equal(df_res, df_true, close=True))
def test_nominal(self): """Checks the implementation of nominal values""" md = gr.Model() >> gr.cp_bounds( x0=[-1, +1], x1=[0.1, np.Inf], x2=[-np.Inf, -0.1], ) df_true = gr.df_make(x0=0.0, x1=+0.1, x2=-0.1) df_res = gr.eval_nominal(md, df_det="nom", skip=True) self.assertTrue(gr.df_equal(df_res, df_true))
def setUp(self): ## Linear limit state w/ MPP off initial guess self.beta_true = 3 self.md = ( gr.Model() >> gr.cp_function( fun=lambda x: self.beta_true * 2 - x[0] - np.sqrt(3) * x[1], var=2, out=["g"], ) >> gr.cp_marginals( x0=dict(dist="norm", loc=0, scale=1, sign=1), x1=dict(dist="norm", loc=0, scale=1, sign=1), ) >> gr.cp_copula_independence() ) ## Linear limit state w/ lognormal marginals self.md_log = ( gr.Model() >> gr.cp_vec_function( fun=lambda df: gr.df_make( g=gr.exp(gr.sqrt(2) * 1) - df.x * df.y ), var=["x", "y"], out=["g"] ) >> gr.cp_marginals( x=dict(dist="lognorm", loc=0, scale=1, s=1), y=dict(dist="lognorm", loc=0, scale=1, s=1), ) >> gr.cp_copula_independence() ) self.df_mpp = gr.df_make( x=gr.exp(gr.sqrt(2)/2), y=gr.exp(gr.sqrt(2)/2), beta_g=1.0, g=0.0, ) ## Cantilever beam for flatten test self.md_beam = models.make_cantilever_beam()
def setUp(self): self.md = models.make_test() self.md_mixed = ( gr.Model() >> gr.cp_function(fun=lambda x: x[0], var=3, out=1) >> gr.cp_bounds(x2=(0, 1)) >> gr.cp_marginals( x0={"dist": "uniform", "loc": 0, "scale": 1}, x1={"dist": "uniform", "loc": 0, "scale": 1}, ) >> gr.cp_copula_independence() )
def test_opt(self): # invariant checks self.inv_test.md_arg(gr.eval_min, df_arg="df_start") self.inv_test.df_arg(gr.eval_min, df_arg="df_start", acc_none="always") md_bowl = (gr.Model("Constrained bowl") >> gr.cp_function( fun=lambda x: x[0]**2 + x[1]**2, var=["x", "y"], out=["f"], ) >> gr.cp_function( fun=lambda x: (x[0] + x[1] + 1), var=["x", "y"], out=["g1"], ) >> gr.cp_function( fun=lambda x: -(-x[0] + x[1] - np.sqrt(2 / 10)), var=["x", "y"], out=["g2"], ) >> gr.cp_bounds( x=(-1, +1), y=(-1, +1), )) df_res = md_bowl >> gr.ev_min( out_min="f", out_geq=["g1"], out_leq=["g2"], ) # Check result self.assertTrue(abs(df_res.x[0] + np.sqrt(1 / 20)) < 1e-6) self.assertTrue(abs(df_res.y[0] - np.sqrt(1 / 20)) < 1e-6) # Check errors for violated invariants with self.assertRaises(ValueError): gr.eval_min(md_bowl, out_min="FALSE") with self.assertRaises(ValueError): gr.eval_min(md_bowl, out_min="f", out_geq=["FALSE"]) with self.assertRaises(ValueError): gr.eval_min(md_bowl, out_min="f", out_eq=["FALSE"]) # Test multiple restarts df_multi = gr.eval_min( md_bowl, out_min="f", out_geq=["g1"], out_leq=["g2"], n_restart=2, ) self.assertTrue(df_multi.shape[0] == 2)
def test_comp_model(self): """Test model composition""" md_inner = ( gr.Model("inner") >> gr.cp_function(fun=lambda x: x[0] + x[1], var=2, out=1) >> gr.cp_marginals(x0=dict(dist="norm", loc=0, scale=1)) >> gr.cp_copula_independence() ) ## Deterministic composition md_det = gr.Model("outer_det") >> gr.cp_md_det(md=md_inner) self.assertTrue(set(md_det.var) == {"x0", "x1"}) self.assertTrue(md_det.out == ["y0"]) gr.eval_df(md_det, df=gr.df_make(x0=0, x1=0)) ## Deterministic composition md_sample = gr.Model("outer_det") >> gr.cp_md_sample( md=md_inner, param=dict(x0=("loc", "scale")) ) self.assertTrue(set(md_sample.var) == {"x0_loc", "x0_scale", "x1"}) self.assertTrue(set(md_sample.out) == {"y0"}) gr.eval_df(md_sample, df=gr.df_make(x0_loc=0, x0_scale=1, x1=0))
def setUp(self): ## Linear limit state w/ MPP off initial guess self.beta_true = 3 self.md = ( gr.Model() >> gr.cp_function( fun=lambda x: self.beta_true * 2 - x[0] - np.sqrt(3) * x[1], var=2, out=["g"], ) >> gr.cp_marginals( x0=dict(dist="norm", loc=0, scale=1, sign=1), x1=dict(dist="norm", loc=0, scale=1, sign=1), ) >> gr.cp_copula_independence() )
def test_var_outer(self): ## Test pass-throughs df_test = pd.DataFrame(dict(x0=[0])) md_no_rand = gr.Model() >> gr.cp_function( fun=lambda x: x, var=1, out=1) md_no_rand.var_outer(pd.DataFrame(), df_det="nom") md_no_det = md_no_rand >> gr.cp_marginals(x0={ "dist": "uniform", "loc": 0, "scale": 1 }) md_no_det.var_outer(df_test, df_det="nom") ## Test assertions with self.assertRaises(ValueError): self.model_3d.var_outer(self.df_2d, df_det=self.df_2d)
def md_arg(self, func, df_arg="df", **kwargs): """Helper function for TypeErrors and ValueErrors for invalid Model arguments (eval_* functions). Args: func (func): eval function to test df_arg (str): name of DataFrame argument **kwargs: kwargs to pass""" ## Type test for wrong in self.type_tests: self.assertRaises(TypeError, func, wrong, **{df_arg: self.df}, **kwargs) ## No model.functions self.assertRaises(ValueError, func, gr.Model(), **{df_arg: self.df}, **kwargs)
def test_dag(self): md = (gr.Model("model") >> gr.cp_function(lambda x: x, var=1, out=1) >> gr.cp_function(lambda x: x[0] + x[1], var=["x0", "y0"], out=1)) G_true = nx.DiGraph() G_true.add_edge("(var)", "f0", label="{}".format({"x0"})) G_true.add_edge("f0", "(out)", label="{}".format({"y0"})) G_true.add_edge("(var)", "f1", label="{}".format({"x0"})) G_true.add_edge("f0", "f1", label="{}".format({"y0"})) G_true.add_edge("f1", "(out)", label="{}".format({"y1"})) nx.set_node_attributes(G_true, "model", "parent") self.assertTrue( nx.is_isomorphic( md.make_dag(), G_true, node_match=lambda u, v: u == v, edge_match=lambda u, v: u == v, ))
def test_function_model(self): md_base = gr.Model() >> gr.cp_function( fun=lambda x: x, var=1, out=1, name="name", runtime=1) ## Base constructor func = gr.FunctionModel(md_base) self.assertTrue(md_base.var == func.var) self.assertTrue(md_base.out == func.out) self.assertTrue(md_base.name == func.name) self.assertTrue(md_base.runtime(1) == func.runtime) ## Test copy func_copy = func.copy() self.assertTrue(func_copy.var == func.var) self.assertTrue(func_copy.out == func.out) self.assertTrue(func_copy.name == func.name) self.assertTrue(func_copy.runtime == func.runtime)
def test_tran_reweight(self): """Test the functionality of tran_reweight() """ ## Correctness # Choose scale based on Owen (2013) Exercise 9.7 md_new = (self.md >> gr.cp_marginals( x=dict(dist="norm", loc=0, scale=sqrt(4 / 5)))) df_base = (self.md >> gr.ev_sample(n=500, df_det="nom", seed=101)) df = (df_base >> gr.tf_reweight(md_base=self.md, md_new=md_new) >> gr.tf_summarize( mu=gr.mean(DF.y * DF.weight), se=gr.sd(DF.y * DF.weight) / gr.sqrt(gr.n(DF.weight)), se_orig=gr.sd(DF.y) / gr.sqrt(gr.n(DF.weight)), )) mu = df.mu[0] se = df.se[0] se_orig = df.se_orig[0] self.assertTrue(mu - se * 2 < 0 and 0 < mu + se * 2) ## Optimized IS should be more precise than ordinary monte carlo # print("se_orig = {0:4.3f}".format(se_orig)) # print("se = {0:4.3f}".format(se)) self.assertTrue(se < se_orig) ## Invariants # Missing input in data with self.assertRaises(ValueError): gr.tran_reweight(df_base[["y"]], md_base=self.md, md_new=self.md) # Input mismatch with self.assertRaises(ValueError): gr.tran_reweight(df_base, md_base=self.md, md_new=gr.Model()) # Weights collision with self.assertRaises(ValueError): gr.tran_reweight(df_base >> gr.tf_mutate(weight=0), md_base=self.md, md_new=self.md)
def test_nls(self): ## Ground-truth model c_true = 2 a_true = 1 md_true = (gr.Model() >> gr.cp_function( fun=lambda x: a_true * np.exp(x[0] * c_true) + x[1], var=["x", "epsilon"], out=["y"], ) >> gr.cp_marginals(epsilon={ "dist": "norm", "loc": 0, "scale": 0.5 }) >> gr.cp_copula_independence()) df_data = md_true >> gr.ev_monte_carlo( n=5, seed=101, df_det=gr.df_make(x=[0, 1, 2, 3, 4])) ## Model to fit md_param = (gr.Model() >> gr.cp_function( fun=lambda x: x[2] * np.exp(x[0] * x[1]), var=["x", "c", "a"], out=["y"]) >> gr.cp_bounds(c=[0, 4], a=[0.1, 2.0])) ## Fit the model md_fit = df_data >> gr.ft_nls( md=md_param, verbose=False, uq_method="linpool", ) ## Unidentifiable model throws warning # ------------------------- md_unidet = (gr.Model() >> gr.cp_function( fun=lambda x: x[2] / x[3] * np.exp(x[0] * x[1]), var=["x", "c", "a", "z"], out=["y"], ) >> gr.cp_bounds(c=[0, 4], a=[0.1, 2.0], z=[0, 1])) with self.assertWarns(RuntimeWarning): gr.fit_nls( df_data, md=md_unidet, uq_method="linpool", ) ## True parameters in wide confidence region # ------------------------- alpha = 1e-3 self.assertTrue( (md_fit.density.marginals["c"].q(alpha / 2) <= c_true) and (c_true <= md_fit.density.marginals["c"].q(1 - alpha / 2))) self.assertTrue( (md_fit.density.marginals["a"].q(alpha / 2) <= a_true) and (a_true <= md_fit.density.marginals["a"].q(1 - alpha / 2))) ## Model with fixed parameter # ------------------------- md_fixed = (gr.Model() >> gr.cp_function( fun=lambda x: x[2] * np.exp(x[0] * x[1]), var=["x", "c", "a"], out=["y"]) >> gr.cp_bounds(c=[0, 4], a=[1, 1])) md_fit_fixed = df_data >> gr.ft_nls( md=md_fixed, verbose=False, uq_method="linpool") # Test that fixed model can evaluate successfully gr.eval_monte_carlo(md_fit_fixed, n=1, df_det="nom") ## Trajectory model # ------------------------- md_base = models.make_trajectory_linear() md_fit = data.df_trajectory_windowed >> gr.ft_nls( md=md_base, method="SLSQP", tol=1e-3) df_tmp = md_fit >> gr.ev_nominal(df_det="nom")
def test_nls(self): ## Ground-truth model c_true = 2 a_true = 1 md_true = (gr.Model() >> gr.cp_function( fun=lambda x: a_true * np.exp(x[0] * c_true) + x[1], var=["x", "epsilon"], out=["y"], ) >> gr.cp_marginals(epsilon={ "dist": "norm", "loc": 0, "scale": 0.5 }) >> gr.cp_copula_independence()) df_data = md_true >> gr.ev_sample( n=5, seed=101, df_det=gr.df_make(x=[0, 1, 2, 3, 4])) ## Model to fit md_param = (gr.Model() >> gr.cp_function( fun=lambda x: x[2] * np.exp(x[0] * x[1]), var=["x", "c", "a"], out=["y"]) >> gr.cp_bounds(c=[0, 4], a=[0.1, 2.0])) ## Fit the model md_fit = df_data >> gr.ft_nls( md=md_param, verbose=False, uq_method="linpool", ) ## Unidentifiable model throws warning # ------------------------- md_unidet = (gr.Model() >> gr.cp_function( fun=lambda x: x[2] / x[3] * np.exp(x[0] * x[1]), var=["x", "c", "a", "z"], out=["y"], ) >> gr.cp_bounds(c=[0, 4], a=[0.1, 2.0], z=[0, 1])) with self.assertWarns(RuntimeWarning): gr.fit_nls( df_data, md=md_unidet, uq_method="linpool", ) ## True parameters in wide confidence region # ------------------------- alpha = 1e-3 self.assertTrue( (md_fit.density.marginals["c"].q(alpha / 2) <= c_true) and (c_true <= md_fit.density.marginals["c"].q(1 - alpha / 2))) self.assertTrue( (md_fit.density.marginals["a"].q(alpha / 2) <= a_true) and (a_true <= md_fit.density.marginals["a"].q(1 - alpha / 2))) ## Model with fixed parameter # ------------------------- md_fixed = (gr.Model() >> gr.cp_function( fun=lambda x: x[2] * np.exp(x[0] * x[1]), var=["x", "c", "a"], out=["y"]) >> gr.cp_bounds(c=[0, 4], a=[1, 1])) md_fit_fixed = df_data >> gr.ft_nls( md=md_fixed, verbose=False, uq_method="linpool") # Test that fixed model can evaluate successfully gr.eval_sample(md_fit_fixed, n=1, df_det="nom") ## Trajectory model # ------------------------- md_base = models.make_trajectory_linear() md_fit = data.df_trajectory_windowed >> gr.ft_nls( md=md_base, method="SLSQP", tol=1e-3) df_tmp = md_fit >> gr.ev_nominal(df_det="nom") ## Select output for fitting # ------------------------- # Split model has inconsistent "true" parameter value md_split = (gr.Model("Split") >> gr.cp_vec_function( fun=lambda df: gr.df_make( f=1 * df.c * df.x, g=2 * df.c * df.x, ), var=["c", "x"], out=["f", "g"], ) >> gr.cp_bounds( x=(-1, +1), c=(-1, +1), )) df_split = (gr.df_make(x=gr.linspace(-1, +1, 100)) >> gr.tf_mutate( f=X.x, g=X.x)) # Fitting both outputs: cannot achieve mse ~= 0 df_both = (df_split >> gr.ft_nls(md_split, out=["f", "g"]) >> gr.ev_df(df_split >> gr.tf_rename(f_t=X.f, g_t=X.g)) >> gr.tf_summarize( mse_f=gr.mse(X.f, X.f_t), mse_g=gr.mse(X.g, X.g_t), )) self.assertTrue(df_both.mse_f[0] > 0) self.assertTrue(df_both.mse_g[0] > 0) # Fitting "f" only df_f = (df_split >> gr.ft_nls(md_split, out=["f"]) >> gr.ev_df(df_split >> gr.tf_rename(f_t=X.f, g_t=X.g)) >> gr.tf_summarize( mse_f=gr.mse(X.f, X.f_t), mse_g=gr.mse(X.g, X.g_t), )) self.assertTrue(df_f.mse_f[0] < 1e-16) self.assertTrue(df_f.mse_g[0] > 0) # Fitting "g" only df_g = (df_split >> gr.ft_nls(md_split, out=["g"]) >> gr.ev_df(df_split >> gr.tf_rename(f_t=X.f, g_t=X.g)) >> gr.tf_summarize( mse_f=gr.mse(X.f, X.f_t), mse_g=gr.mse(X.g, X.g_t), )) self.assertTrue(df_g.mse_f[0] > 0) self.assertTrue(df_g.mse_g[0] < 1e-16)
def setUp(self): self.md = gr.Model()
def test_copula_warning(self): md = gr.Model() with self.assertRaises(ValueError): md.density.sample()
def test_contour(self): md1 = (gr.Model() >> gr.cp_vec_function( fun=lambda df: gr.df_make( f=df.x**2 + df.y**2, g=df.x + df.y, ), var=["x", "y"], out=["f", "g"], ) >> gr.cp_bounds( x=(-1, +1), y=(-1, +1), )) md2 = (gr.Model() >> gr.cp_vec_function( fun=lambda df: gr.df_make(f=(df.c) * df.x + (1 - df.c) * df.y, ), var=["x", "y", "c"], out=["f"], ) >> gr.cp_bounds( x=(-1, +1), y=(-1, +1), c=(+0, +1), )) ## Basic functionality df_res1 = ( md1 >> gr.ev_contour( var=["x", "y"], out=["f", "g"], n_side=10, # Coarse, for speed )) # Contains correct columns self.assertTrue("x" in df_res1.columns) self.assertTrue("y" in df_res1.columns) df_res2 = ( md2 >> gr.ev_contour( var=["x", "y"], out=["f"], df=gr.df_make(c=[0, 1]), n_side=10, # Coarse, for speed )) # Contains auxiliary variable self.assertTrue("c" in df_res2.columns) df_res3 = ( md1 >> gr.ev_contour( var=["x", "y"], out=["g"], levels=dict(g=[-1, 0, +1]), n_side=10, # Coarse, for speed )) # Correct manual levels self.assertTrue(set(df_res3.level) == {-1, 0, +1}) # Correct manual levels with self.assertWarns(Warning): df_res4 = ( md1 >> gr.ev_contour( var=["x", "y"], out=["g"], levels=dict(g=[-1, 0, +1, +1e3]), n_side=10, # Coarse, for speed )) # Correct manual levels self.assertTrue(set(df_res4.level) == {-1, 0, +1}) ## Check assertions # No var with self.assertRaises(ValueError): res = (md1 >> gr.ev_contour(out=["f"])) # Incorrect number of inputs with self.assertRaises(ValueError): res = (md1 >> gr.ev_contour(var=["x", "y", "z"])) # Unavailable inputs with self.assertRaises(ValueError): res = (md1 >> gr.ev_contour(var=["foo", "bar"])) # Unsupported input with self.assertRaises(ValueError): res = (md2 >> gr.ev_contour( var=["x", "y"], out=["f"], )) with self.assertRaises(ValueError): res = (md2 >> gr.ev_contour( var=["x", "y"], out=["f"], df=gr.df_make(foo=1))) # Zero bound width with self.assertRaises(ValueError): res = ( gr.Model() >> gr.cp_vec_function( fun=lambda df: gr.df_make( f=df.x**2 + df.y**2, g=df.x + df.y, ), var=["x", "y"], out=["f", "g"], ) >> gr.cp_bounds( x=(0, 0), y=(-1, +1), ) >> gr.ev_contour( var=["x", "y"], out=["f", "g"], n_side=10, # Coarse, for speed )) # No out with self.assertRaises(ValueError): res = (md1 >> gr.ev_contour(var=["x", "y"])) # Output unavailable with self.assertRaises(ValueError): res = (md1 >> gr.ev_contour(var=["x", "y"], out=["foo"]))
def test_empty_functions(self): md = gr.Model() >> gr.cp_bounds(x=[-1, +1]) with self.assertRaises(ValueError): gr.eval_nominal(md)
def test_nls(self): ## Setup md_feat = (gr.Model() >> gr.cp_function( fun=lambda x: x[0] * x[1] + x[2], var=3, out=1, ) >> gr.cp_bounds(x0=[-1, +1], x2=[0, 0]) >> gr.cp_marginals(x1=dict(dist="norm", loc=0, scale=1))) md_const = (gr.Model() >> gr.cp_function( fun=lambda x: x[0], var=1, out=1) >> gr.cp_bounds(x0=(-1, +1))) df_response = md_feat >> gr.ev_df( df=gr.df_make(x0=0.1, x1=[-1, -0.5, +0, +0.5, +1], x2=0)) df_data = df_response[["x1", "y0"]] ## Model with features df_true = gr.df_make(x0=0.1) df_fit = md_feat >> gr.ev_nls(df_data=df_data, append=False) pd.testing.assert_frame_equal( df_fit, df_true, check_exact=False, check_dtype=False, check_column_type=False, ) ## Fitting synonym md_feat_fit = df_data >> gr.ft_nls(md=md_feat, verbose=False) self.assertTrue(set(md_feat_fit.var) == set(["x1", "x2"])) ## Constant model df_const = gr.df_make(x0=0) df_fit = md_const >> gr.ev_nls(df_data=gr.df_make(y0=[-1, 0, +1])) pd.testing.assert_frame_equal( df_fit, df_const, check_exact=False, check_dtype=False, check_column_type=False, ) ## Multiple restarts works df_multi = gr.eval_nls(md_feat, df_data=df_data, n_restart=2) self.assertTrue(df_multi.shape[0] == 2) ## Specified initial guess df_spec = gr.eval_nls(md_feat, df_data=df_data, df_init=gr.df_make(x0=0.5), append=False) pd.testing.assert_frame_equal( df_spec, df_true, check_exact=False, check_dtype=False, check_column_type=False, ) # Raises if incorrect guess data with self.assertRaises(ValueError): gr.eval_nls(md_feat, df_data=df_data, df_init=gr.df_make(foo=0.5))