Esempio n. 1
0
def fit_nls(
    df_data,
    md=None,
    verbose=True,
    **kwargs,
):
    r"""Fit a model with Nonlinear Least Squares (NLS)

    Estimate best-fit variable levels with nonlinear least squares (NLS), and
    return an executable model with those frozen best-fit levels.

    Note: This is a *synonym* for eval_nls(); see the documentation for
    eval_nls() for keyword argument options available beyond those listed here.

    Args:
        df_data (DataFrame): Data for estimating best-fit variable levels.
            Variables not found in df_data optimized for fitting.
        md (gr.Model): Model to analyze. All model variables
            selected for fitting must be bounded or random. Deterministic
            variables may have semi-infinite bounds.

    Returns:
        gr.Model: Model for evaluation with best-fit variables frozen to
            optimized levels.

    """
    ## Check invariants
    if md is None:
        raise ValueError("Must provide model md")

    ## Run eval_nls to fit model parameter values
    df_fit = eval_nls(md, df_data=df_data, append=True, **kwargs)
    ## Select best-fit values
    df_best = df_fit.sort_values(by="mse", axis=0).iloc[[0]]
    if verbose:
        print(df_best)

    ## Determine variables to fix
    var_fixed = list(set(md.var).intersection(set(df_best.columns)))
    var_remain = list(set(md.var).difference(set(var_fixed)))

    if len(var_remain) == 0:
        raise ValueError("Resulting model is constant!")

    ## Assemble and return fitted model
    if md.name is None:
        name = "(Fitted Model)"
    else:
        name = md.name + " (Fitted)"

    md_res = (Model(name) >> cp_function(
        lambda x: df_best[var_fixed].values,
        var=var_remain,
        out=var_fixed,
        name="Fix variable levels",
    ) >> cp_md_det(md=md))

    return md_res
Esempio n. 2
0
def make_test():
    md = Model() >> \
         cp_function(fun=fun, var=3, out=1) >> \
         cp_bounds(x0=(-1,+1), x1=(-1,+1), x2=(-1,+1)) >> \
         cp_marginals(
             x0={"dist": "uniform", "loc": -1, "scale": 2},
             x1={"dist": "uniform", "loc": -1, "scale": 2}
         ) >> \
         cp_copula_independence()

    return md
Esempio n. 3
0
def make_plate_buckle():
    r"""Initialize a buckling plate model

    Variables (deterministic):
        w (in): Plate width
        h (in): Plate height
        t (in): Plate thickness
        m (-): Wavenumber
        L (kips): Applied (compressive) load;
            uniformly applied along top and bottom edges

    Variables (random):
        E (kips/in^2): Elasticity
        mu (-): Poisson's ratio

    Outputs:
        k_cr (-): Prefactor for buckling stress
        g_buckle (kips/in^2): Buckling limit state:
            critical stress - applied stress
    """
    md = (
        Model("Plate Buckling")
        >> cp_vec_function(
            fun=lambda df: df_make(
                k_cr=(df.m*df.h/df.w + df.w/df.m/df.h)**2
            ),
            var=["w", "h", "m"],
            out=["k_cr"],
        )
        >> cp_vec_function(
            fun=lambda df: df_make(
                g_buckle=df.k_cr * pi**2/12 * df.E / (1 - df.mu**2) * (df.t/df.h)**2
                - df.L / df.t / df.w
            ),
            var=["k_cr", "t", "h", "w", "E", "mu", "L"],
            out=["g_buckle"],
            name="limit state",
        )
        >> cp_bounds(
            t=(0.5 * THICKNESS, 2 * THICKNESS),
            h=(6, 18),
            w=(6, 18),
            m=(1, 5),
            L=(LOAD / 2, LOAD * 2),
        )
        >> cp_marginals(
            E=marg_fit("norm", df_stang.E),
            mu=marg_fit("beta", df_stang.mu),
        )
        >> cp_copula_gaussian(df_data=df_stang)
    )

    return md
Esempio n. 4
0
def make_trajectory_linear():
    ## Assemble model
    md_trajectory = (
        Model("Trajectory Model")
        >> cp_vec_function(fun=fun_x, var=var_list, out=["x"], name="x_trajectory",)
        >> cp_vec_function(fun=fun_y, var=var_list, out=["y"], name="y_trajectory",)
        >> cp_bounds(
            u0=[0.1, Inf], v0=[0.1, Inf], tau=[0.05, Inf], t=[0, 600]
        )
    )

    return md_trajectory
Esempio n. 5
0
def make_poly():
    md = Model("Polynomials") >> \
         cp_function(fun=lambda x: x, var=1, out=1, name="linear") >> \
         cp_function(fun=lambda x: x**2, var=1, out=1, name="quadratic") >> \
         cp_function(fun=lambda x: x**3, var=1, out=1, name="cubic") >> \
         cp_marginals(
             x0={"dist": "uniform", "loc": -1, "scale": 2},
             x1={"dist": "uniform", "loc": -1, "scale": 2},
             x2={"dist": "uniform", "loc": -1, "scale": 2}
         ) >> \
         cp_copula_independence()

    return md
Esempio n. 6
0
def make_channel_nondim():
    r"""Make 1d channel model; dimensionless form

    Instantiates a model for particle and fluid temperature rise; particles are suspended in a fluid with bulk velocity along a square cross-section channel. The walls of said channel are transparent, and radiation heats the particles as they travel down the channel.

    References:
        Banko, A.J. "RADIATION ABSORPTION BY INERTIAL PARTICLES IN A TURBULENT SQUARE DUCT FLOW" (2018) PhD Thesis, Stanford University, Chapter 2

    """
    md = (
        Model("1d Particle-laden Channel with Radiation; Dimensionless Form")
        >> cp_vec_function(
            fun=lambda df: df_make(beta=120 * (1 + df.Phi_M * df.chi)),
            var=["Phi_M", "chi"],
            out=["beta"],
        ) >> cp_vec_function(
            fun=lambda df: df_make(
                T_f=(df.Phi_M * df.chi) / (1 + df.Phi_M * df.chi) *
                (df.I * df.xst - df.beta**(-1) * df.I *
                 (1 - exp(-df.beta * df.xst))),
                T_p=1 / (1 + df.Phi_M * df.chi) *
                (df.Phi_M * df.chi * df.I * df.xst + df.beta**(-1) * df.I *
                 (1 - exp(-df.beta * df.xst))),
            ),
            var=["xst", "Phi_M", "chi", "I", "beta"],
            out=["T_f", "T_p"],
        ) >> cp_bounds(
            ## Dimensionless axial location (-)
            xst=(0, 5), ) >> cp_marginals(
                ## Mass loading ratio (-)
                Phi_M={
                    "dist": "uniform",
                    "loc": 0,
                    "scale": 1
                },
                ## Particle-fluid heat capacity ratio (-)
                chi={
                    "dist": "uniform",
                    "loc": 0.1,
                    "scale": 0.9
                },
                ## Normalized radiative intensity (-)
                I={
                    "dist": "uniform",
                    "loc": 0.1,
                    "scale": 0.9
                },
            ) >> cp_copula_independence())

    return md
Esempio n. 7
0
def make_linear_normal():
    md = Model("Linear-Normal Reliability Problem") >> \
         cp_function(
             fun=limit_state,
             var=2,
             out=["g_linear"],
             name="limit state"
         ) >> \
         cp_marginals(
             x0={"dist": "norm", "loc": 0, "scale": 1, "sign":+1},
             x1={"dist": "norm", "loc": 0, "scale": 1, "sign":+1}
         ) >> \
         cp_copula_independence()

    return md
Esempio n. 8
0
def make_pareto_random(twoDim=True):
    """ Create a model of random points for a pareto frontier evaluation
    Args:
        twoDim (bool): determines whether to create a 2D or 3D model
    """
    if twoDim == True:
        # Model to make dataset
        md_true = (Model() >> cp_vec_function(
            fun=lambda df: df_make(
                y1=df.x1 * cos(df.x2),
                y2=df.x1 * sin(df.x2),
            ),
            var=["x1", "x2"],
            out=["y1", "y2"],
        ) >> cp_marginals(
            x1=dict(dist="uniform", loc=0, scale=1),
            x2=dict(dist="uniform", loc=0, scale=pi / 2),
        ) >> cp_copula_independence())

        return md_true
    else:
        # Model to make dataset
        md_true = (Model() >> cp_vec_function(
            fun=lambda df: df_make(
                y1=df.x1 * cos(df.x2),
                y2=df.x1 * sin(df.x2),
                y3=df.x1 * tan(df.x2),
            ),
            var=["x1", "x2", "x3"],
            out=["y1", "y2", "y3"],
        ) >> cp_marginals(x1=dict(dist="uniform", loc=0, scale=1),
                          x2=dict(dist="uniform", loc=0, scale=pi / 2),
                          x3=dict(dist="uniform", loc=0, scale=pi / 4)) >>
                   cp_copula_independence())

        return md_true
Esempio n. 9
0
def fit_nls(
    df_data,
    md=None,
    out=None,
    var_fix=None,
    df_init=None,
    verbose=True,
    uq_method=None,
    **kwargs,
):
    r"""Fit a model with Nonlinear Least Squares (NLS)

    Estimate best-fit variable levels with nonlinear least squares (NLS), and
    return an executable model with those frozen best-fit levels. Optionally,
    fit a distribution on the parameters to quantify parametric uncertainty.

    Note: This is a *synonym* for eval_nls(); see the documentation for
    eval_nls() for keyword argument options available beyond those listed here.

    Args:
        df_data (DataFrame): Data for estimating best-fit variable levels.
            Variables not found in df_data optimized for fitting.
        md (gr.Model): Model to analyze. All model variables
            selected for fitting must be bounded or random. Deterministic
            variables may have semi-infinite bounds.
        var_fix (list or None): Variables to fix to nominal levels. Note that
            variables with domain width zero will automatically be fixed.
        df_init (DataFrame): Initial guesses for parameters; overrides n_restart
        n_restart (int): Number of restarts to try; the first try is at
            the nominal conditions of the model. Returned model will use
            the least-error parameter set among restarts tested.
        n_maxiter (int): Optimizer maximum iterations
        verbose (bool): Print best-fit parameters to console?
        uq_method (str OR None): If string, select method to quantify parameter
            uncertainties. If None, provide best-fit values only. Methods:
            uq_method = "linpool": assume normal errors; linearly approximate
                parameter effects; equally pool variance matrices for each output

    Returns:
        gr.Model: Model for evaluation with best-fit variables frozen to
            optimized levels.

    Examples:
        >>> import grama as gr
        >>> from grama.data import df_trajectory_windowed
        >>> from grama.models import make_trajectory_linear
        >>> X = gr.Intention()
        >>>
        >>> md_trajectory = make_trajectory_linear()
        >>> md_fitted = (
        >>>     df_trajectory_windowed
        >>>     >> gr.ft_nls(
        >>>         md=md_trajectory,
        >>>         uq_method="linpool",
        >>>     )
        >>> )
    """
    ## Check `out` invariants
    if out is None:
        out = md.out
        print("... fit_nls setting out = {}".format(out))

    ## Check invariants
    if md is None:
        raise ValueError("Must provide model md")

    ## Determine variables to be fixed
    if var_fix is None:
        var_fix = set()
    else:
        var_fix = set(var_fix)
    for var in md.var_det:
        wid = md.domain.get_width(var)
        if wid == 0:
            var_fix.add(var)

    ## Run eval_nls to fit model parameter values
    df_fit = eval_nls(
        md,
        df_data=df_data,
        var_fix=var_fix,
        df_init=df_init,
        append=True,
        verbose=verbose,
        **kwargs,
    )
    ## Select best-fit values
    df_best = df_fit.sort_values(by="mse",
                                 axis=0).iloc[[0]].reset_index(drop=True)
    if verbose:
        print(df_fit.sort_values(by="mse", axis=0))

    ## Determine variables that were fitted
    var_fitted = list(set(md.var).intersection(set(df_best.columns)))
    var_remain = list(set(md.var).difference(set(var_fitted)))

    if len(var_remain) == 0:
        raise ValueError("Resulting model is constant!")

    ## Assemble and return fitted model
    if md.name is None:
        name = "(Fitted Model)"
    else:
        name = md.name + " (Fitted)"

    ## Calibrate parametric uncertainty, if requested
    if uq_method == "linpool":
        ## Precompute data
        df_nom = eval_nominal(md, df_det="nom")
        df_base = tran_outer(
            df_data, concat((df_best[var_fitted], df_nom[var_fix]), axis=1))
        df_pred = eval_df(md, df=df_base)
        df_grad = eval_grad_fd(md, df_base=df_base, var=var_fitted)

        ## Pool variance matrices
        n_obs = df_data.shape[0]
        n_fitted = len(var_fitted)
        Sigma_pooled = zeros((n_fitted, n_fitted))

        for output in out:
            ## Approximate sigma_sq
            sigma_sq = npsum(
                nppow(df_data[output].values - df_pred[output].values,
                      2)) / (n_obs - n_fitted)
            ## Approximate (pseudo)-inverse hessian
            var_grad = list(map(lambda v: "D" + output + "_D" + v, var_fitted))
            Z = df_grad[var_grad].values
            Hinv = pinv(Z.T.dot(Z), hermitian=True)

            ## Add variance matrix to pooled Sigma
            Sigma_pooled = Sigma_pooled + sigma_sq * Hinv / n_fitted

        ## Check model for identifiability
        kappa_out = cond(Sigma_pooled)
        if kappa_out > 1e10:
            warn(
                "Model is locally unidentifiable as measured by the " +
                "condition number of the pooled covariance matrix; " +
                "kappa = {}".format(kappa_out),
                RuntimeWarning,
            )

        ## Convert to std deviations and correlation
        sigma_comp = npsqrt(diag(Sigma_pooled))
        corr_mat = Sigma_pooled / (atleast_2d(sigma_comp).T.dot(
            atleast_2d(sigma_comp)))
        corr_data = []
        I, J = triu_indices(n_fitted, k=1)
        for ind in range(len(I)):
            i = I[ind]
            j = J[ind]
            corr_data.append([var_fitted[i], var_fitted[j], corr_mat[i, j]])
        df_corr = DataFrame(data=corr_data, columns=["var1", "var2", "corr"])

        ## Assemble marginals
        marginals = {}
        for ind, var_ in enumerate(var_fitted):
            marginals[var_] = {
                "dist": "norm",
                "loc": df_best[var_].values[0],
                "scale": sigma_comp[ind],
            }

        ## Construct model with Gaussian copula
        if len(var_fix) > 0:
            md_res = (Model(name) >> cp_function(
                lambda x: df_nom[var_fix].values,
                var=set(var_remain).difference(var_fix),
                out=var_fix,
                name="Fix variable levels",
            ) >> cp_md_det(md=md) >> cp_marginals(**marginals) >>
                      cp_copula_gaussian(df_corr=df_corr))
        else:
            md_res = (Model(name) >> cp_md_det(md=md) >> cp_marginals(
                **marginals) >> cp_copula_gaussian(df_corr=df_corr))

    ## Return deterministic model
    elif uq_method is None:
        md_res = (Model(name) >> cp_function(
            lambda x: df_best[var_fitted].values,
            var=var_remain,
            out=var_fitted,
            name="Fix variable levels",
        ) >> cp_md_det(md=md))

    else:
        raise ValueError(
            "uq_method option {} not recognized".format(uq_method))

    return md_res
Esempio n. 10
0
def fit_kmeans(df, var=None, colname="cluster_id", seed=None, **kwargs):
    r"""K-means cluster a dataset

    Create a cluster-labeling model on a dataset using the K-means algorithm.

    Args:
        df (DataFrame): Hybrid point results from gr.eval_hybrid()
        var (list or None): Variables in df on which to cluster. Use None to
            cluster on all variables.
        colname (string): Name of cluster id; will be output in cluster model.
        seed (int): Random seed for kmeans clustering

    Kwargs:
        n_clusters (int): Number of clusters to fit
        random_state (int or None):

    Returns:
        gr.Model: Model that labels input data

    Notes:
        - A wrapper for sklearn.cluster.KMeans

    References:
        Scikit-learn: Machine Learning in Python, Pedregosa et al. JMLR 12, pp. 2825-2830, 2011.

    Examples:
        >>> import grama as gr
        >>> from grama.data import df_stang
        >>> from grama.fit import ft_kmeans
        >>> X = gr.Intention()
        >>> md_cluster = (
        >>>     df_stang
        >>>     >> ft_kmeans(var=["E", "mu"], n_clusters=2)
        >>> )
        >>> (
        >>>     md_cluster
        >>>     >> gr.ev_df(df_stang)
        >>>     >> gr.tf_group_by(X.cluster_id)
        >>>     >> gr.tf_summarize(
        >>>         thick_mean=gr.mean(X.thick),
        >>>         thick_sd=gr.sd(X.thick),
        >>>         n=gr.n(X.index),
        >>>     )
        >>> )

    """
    ## Check invariants
    if var is None:
        var = list(df.columns).copy()
    else:
        var = list(var).copy()
        diff = set(var).difference(set(df.columns))
        if len(diff) > 0:
            raise ValueError("`var` must be subset of `df.columns`\n"
                             "diff = {}".format(diff))

    ## Generate clustering
    try:
        kmeans = KMeans(random_state=seed, **kwargs).fit(df[var].values)

    except NameError as e:
        error_string = str(e)
        raise NameError(error_string +
                        "\n\nThis function requires the `sklearn` package. " +
                        "Try running the following to install the package:\n"
                        "    pip install scikit-learn")

    ## Build grama model
    def fun_cluster(df):
        res = kmeans.predict(df[var].values)
        return DataFrame(data={colname: res})

    md = Model() >> cp_vec_function(fun=fun_cluster, var=var, out=[colname])

    return md
Esempio n. 11
0
def fit_lm(df,
           md=None,
           var=None,
           out=None,
           domain=None,
           density=None,
           seed=None,
           suppress_warnings=True,
           **kwargs):
    r"""Fit a linear model

    Fit a linear model to given data. Specify inputs and outputs, or inherit
    from an existing model.

    Args:
        df (DataFrame): Data for function fitting
        md (gr.Model): Model from which to inherit metadata
        var (list(str) or None): List of features or None for all except outputs
        out (list(str)): List of outputs to fit
        domain (gr.Domain): Domain for new model
        density (gr.Density): Density for new model
        seed (int or None): Random seed for fitting process
        suppress_warnings (bool): Suppress warnings when fitting?

    Returns:
        gr.Model: A grama model with fitted function(s)

    Notes:
        - Wrapper for sklearn.ensemble.RandomForestRegressor

    """
    if suppress_warnings:
        filterwarnings("ignore")

    n_obs, n_in = df.shape

    ## Infer fitting metadata, if available
    if not (md is None):
        domain = md.domain
        density = md.density
        out = md.out

    ## Check invariants
    if not set(out).issubset(set(df.columns)):
        raise ValueError("out must be subset of df.columns")
    ## Default input value
    if var is None:
        var = list(set(df.columns).difference(set(out)))
    ## Check more invariants
    set_inter = set(out).intersection(set(var))
    if len(set_inter) > 0:
        raise ValueError(
            "outputs and inputs must be disjoint; intersect = {}".format(
                set_inter))
    if not set(var).issubset(set(df.columns)):
        raise ValueError("var must be subset of df.columns")

    ## Construct gaussian process for each output
    functions = []

    try:
        for output in out:
            lm = LinearRegression(**kwargs)
            lm.fit(df[var], df[output])
            name = "LM"

            fun = FunctionRegressor(lm, var, [output], name, 0)
            functions.append(fun)

    except NameError as e:
        error_string = str(e)
        raise NameError(error_string +
                        "\n\nThis function requires the `sklearn` package. " +
                        "Try running the following to install the package:\n"
                        "    pip install scikit-learn")

    ## Construct model
    return Model(functions=functions, domain=domain, density=density)
Esempio n. 12
0
def fit_gp(
    df,
    md=None,
    var=None,
    out=None,
    domain=None,
    density=None,
    kernels=None,
    seed=None,
    suppress_warnings=True,
    n_restart=5,
    alpha=1e-10,
):
    r"""Fit a gaussian process

    Fit a gaussian process to given data. Specify var and out, or inherit from
    an existing model.

    Note that the new model will have two outputs `y_mean, y_sd` for each
    original output `y`. The quantity `y_mean` is the best-fit value, while
    `y_sd` is a measure of predictive uncertainty.

    Args:
        df (DataFrame): Data for function fitting
        md (gr.Model): Model from which to inherit metadata
        var (list(str) or None): List of features or None for all except outputs
        out (list(str)): List of outputs to fit
        domain (gr.Domain): Domain for new model
        density (gr.Density): Density for new model
        seed (int or None): Random seed for fitting process
        kernels (sklearn.gaussian_process.kernels.Kernel or dict or None): Kernel for GP
        n_restart (int): Restarts for optimization
        alpha (float or iterable): Value added to diagonal of kernel matrix
        suppress_warnings (bool): Suppress warnings when fitting?

    Returns:
        gr.Model: A grama model with fitted function(s)

    Notes:
        - Wrapper for sklearn.gaussian_process.GaussianProcessRegressor

    """
    if suppress_warnings:
        filterwarnings("ignore")

    n_obs, n_in = df.shape

    ## Infer fitting metadata, if available
    if not (md is None):
        domain = md.domain
        density = md.density
        out = md.out

    ## Check invariants
    if not set(out).issubset(set(df.columns)):
        raise ValueError("out must be subset of df.columns")
    ## Default input value
    if var is None:
        var = list(set(df.columns).difference(set(out)))
    ## Check more invariants
    set_inter = set(out).intersection(set(var))
    if len(set_inter) > 0:
        raise ValueError(
            "out and var must be disjoint; intersect = {}".format(set_inter))
    if not set(var).issubset(set(df.columns)):
        raise ValueError("var must be subset of df.columns")

    ## Pre-process kernel selection
    try:
        if kernels is None:
            # Vectorize
            kernels = {o: None for o in out}
        elif isinstance(kernels, Kernel):
            kernels = {o: kernels for o in out}

    except NameError as e:
        error_string = str(e)
        raise NameError(error_string +
                        "\n\nThis function requires the `sklearn` package. " +
                        "Try running the following to install the package:\n"
                        "    pip install scikit-learn")

    ## Pre-process data
    var_min = df[var].min()
    var_max = df[var].max()
    df_sd = standardize_cols(df, var_min, var_max, var)

    ## Construct gaussian process for each output
    functions = []

    try:
        for output in out:
            # Define and fit model
            gpr = GaussianProcessRegressor(
                kernel=deepcopy(kernels[output]),
                random_state=seed,
                normalize_y=True,
                copy_X_train=True,
                n_restarts_optimizer=n_restart,
                alpha=alpha,
            )
            gpr.fit(df_sd[var], df_sd[output])
            name = "GP ({})".format(str(gpr.kernel_))

            fun = FunctionGPR(gpr, var, [output], name, 0, var_min, var_max)
            functions.append(fun)

    except NameError as e:
        error_string = str(e)
        raise NameError(error_string +
                        "\n\nThis function requires the `sklearn` package. " +
                        "Try running the following to install the package:\n"
                        "    pip install scikit-learn")

    ## Construct model
    return Model(functions=functions, domain=domain, density=density)
Esempio n. 13
0
def fit_lolo(df,
             md=None,
             var=None,
             out=None,
             domain=None,
             density=None,
             seed=None,
             return_std=True,
             suppress_warnings=True,
             **kwargs):
    r"""Fit a random forest

    Fit a random forest to given data. Specify inputs and outputs, or inherit
    from an existing model.

    Args:
        df (DataFrame): Data for function fitting
        md (gr.Model): Model from which to inherit metadata
        var (list(str) or None): List of features or None for all except outputs
        out (list(str)): List of outputs to fit
        domain (gr.Domain): Domain for new model
        density (gr.Density): Density for new model
        seed (int or None): Random seed for fitting process
        return_std (bool): Return predictive standard deviations?
        suppress_warnings (bool): Suppress warnings when fitting?

    Keyword Arguments:

        num_trees (int):
        use_jackknife (bool):
        bias_learner ():
        leaf_learner ():
        subset_strategy (str):
        min_leaf_instances (int):
        max_depth (int):
        uncertainty_calibration (bool):
        randomize_pivot_location (bool):
        randomly_rotate_features (bool):

    Returns:
        gr.Model: A grama model with fitted function(s)

    Notes:
        - Wrapper for lolopy.learners.RandomForestRegressor

    """
    if suppress_warnings:
        filterwarnings("ignore")

    n_obs, n_in = df.shape

    ## Check minimum rows
    if n_obs < 8:
        raise ValueError("The lolo random forest requires at least 8 rows")

    ## Infer fitting metadata, if available
    if not (md is None):
        domain = md.domain
        density = md.density
        out = md.out

    ## Check invariants
    if not set(out).issubset(set(df.columns)):
        raise ValueError("out must be subset of df.columns")
    ## Default input value
    if var is None:
        var = list(set(df.columns).difference(set(out)))
    ## Check more invariants
    set_inter = set(out).intersection(set(var))
    if len(set_inter) > 0:
        raise ValueError(
            "outputs and inputs must be disjoint; intersect = {}".format(
                set_inter))
    if not set(var).issubset(set(df.columns)):
        raise ValueError("var must be subset of df.columns")

    ## Construct gaussian process for each output
    functions = []

    try:
        for output in out:
            rf = RandomForestRegressor(**kwargs)
            set_seed(seed)
            rf.fit(df[var].values, df[output].values)
            name = "RF"

            fun = FunctionRFR(rf, var, [output], name, 0, return_std)
            functions.append(fun)

    except NameError as e:
        error_string = str(e)
        raise NameError(error_string +
                        "\n\nThis function requires the `lolopy` package. " +
                        "Try running the following to install the package:\n"
                        "    pip install lolopy")

    ## Construct model
    return Model(functions=functions, domain=domain, density=density)
Esempio n. 14
0
def make_cantilever_beam():
    """Cantilever beam

    A standard reliability test-case, often used for benchmarking reliability
    analysis and design algorithms.

    Generally used in the following optimization problem:

        min_{w,t} c_area

        s.t.      P[g_stress <= 0] <= 1.35e-3

                  P[g_disp <= 0] <= 1.35e-3

                  1 <= w, t <= 4

    Deterministic Variables:
        w: Beam width
        t: Beam thickness
    Random Variables:
        H: Horizontal applied force
        V: Vertical applied force
        E: Elastic modulus
        Y: Yield stress
    Outputs:
        c_area: Cost; beam cross-sectional area
        g_stress: Limit state; stress
        g_disp: Limit state; tip displacement

    References:
        Wu, Y.-T., Shin, Y., Sues, R., and Cesare, M., "Safety-factor based approach for probability-based design optimization," American Institute of Aeronautics and Astronautics, Seattle, Washington, April 2001.
        Sues, R., Aminpour, M., and Shin, Y., "Reliability-based Multi-Disciplinary Optimiation for Aerospace Systems," American Institute of Aeronautics and Astronautics, Seattle, Washington, April 2001.

    """

    md = Model(name = "Cantilever Beam") >> \
         cp_vec_function(
             fun=function_area,
             var=["w", "t"],
             out=["c_area"],
             name="cross-sectional area",
             runtime=1.717e-7
         ) >> \
         cp_vec_function(
             fun=function_stress,
             var=["w", "t", "H", "V", "E", "Y"],
             out=["g_stress"],
             name="limit state: stress",
             runtime=8.88e-7
         ) >> \
         cp_vec_function(
             fun=function_displacement,
             var=["w", "t", "H", "V", "E", "Y"],
             out=["g_disp"],
             name="limit state: displacement",
             runtime=3.97e-6
         ) >> \
         cp_bounds(
             w=(2, 4),
             t=(2, 4)
         ) >> \
         cp_marginals(
             H={"dist": "norm", "loc": MU_H, "scale": TAU_H, "sign": +1},
             V={"dist": "norm", "loc": MU_V, "scale": TAU_V, "sign": +1},
             E={"dist": "norm", "loc": MU_E, "scale": TAU_E, "sign":  0},
             Y={"dist": "norm", "loc": MU_Y, "scale": TAU_Y, "sign": -1}
         ) >> \
         cp_copula_independence()

    return md
Esempio n. 15
0
def make_channel():
    r"""Make 1d channel model; dimensional form

    Instantiates a model for particle and fluid temperature rise; particles are suspended in a fluid with bulk velocity along a square cross-section channel. The walls of said channel are transparent, and radiation heats the particles as they travel down the channel.

    Note that this takes the same inputs as the builtin dataset `df_channel`.

    References:
        Banko, A.J. "RADIATION ABSORPTION BY INERTIAL PARTICLES IN A TURBULENT SQUARE DUCT FLOW" (2018) PhD Thesis, Stanford University, Chapter 2

    Examples:

    >>> import grama as gr
    >>> from grama.data import df_channel
    >>> from grama.models import make_channel
    >>> md_channel = make_channel()

    >>> (
    >>>     df_channel
    >>>     >> gr.tf_md(md_channel)

    >>>     >> gr.ggplot(gr.aes("T_f", "T_norm"))
    >>>     + gr.geom_abline(slope=1, intercept=0, linetype="dashed")
    >>>     + gr.geom_point()
    >>>     + gr.labs(x="1D Model", y="3D DNS")
    >>> )

    """
    md = (
        Model("1d Particle-laden Channel with Radiation; Dimensional Form") >>
        cp_vec_function(
            fun=lambda df: df_make(
                Re=df.U * df.H / df.nu_f,
                chi=df.cp_p / df.cp_f,
                Pr=df.nu_f / df.alpha_f,
                Phi_M=df.rho_p * 0.524 * df.d_p**3 * df.n / df.rho_f,
                tau_flow=df.L / df.U,
                tau_pt=(df.rho_p * df.cp_p * 0.318 * df.d_p) / df.h_p,
                tau_rad=(df.rho_p * df.cp_p * 0.667 * df.d_p * df.T_0) /
                (df.Q_abs * 0.78 * df.I_0),
            ),
            var=[
                "U",  # Fluid bulk velocity
                "H",  # Channel width
                "nu_f",  # Fluid kinematic viscosity
                "cp_p",  # Particle isobaric heat capacity
                "cp_f",  # Fluid isobaric heat capacity
                "alpha_f",  # Fluid thermal diffusivity
                "rho_p",  # Particle density
                "rho_f",  # Fluid density
                "d_p",  # Particle diameter
                "n",  # Particle number density
                "h_p",  # Particle-to-gas convection coefficient
                "T_0",  # Initial temperature
                "Q_abs",  # Particle radiation absorption coefficient
                "I_0",  # Incident radiation
            ],
            out=[
                "Re",  # Reynolds number
                "Pr",  # Prandtl number
                "chi",  # Particle-fluid heat capacity ratio
                "Phi_M",  # Mass Loading Ratio
                "tau_flow",  # Fluid residence time
                "tau_pt",  # Particle thermal time constant
                "tau_rad",  # Particle temperature doubling time (approximate)
            ],
            name="Dimensionless Numbers",
        ) >> cp_vec_function(
            fun=lambda df: df_make(
                ## Let xi = x / L
                xst=(df.xi * df.L) / df.H / df.Re / df.Pr,
                ## Assume an optically-thin scenario; I/I_0 = 1
                Is=df.Re * df.Pr * (df.H / df.L) *
                (df.tau_flow / df.tau_rad) * 1,
                beta=df.Re * df.Pr * (df.H / df.L) *
                (df.tau_flow / df.tau_pt) * (1 + df.Phi_M * df.chi),
            ),
            var=[
                "xi", "chi", "H", "L", "Phi_M", "tau_flow", "tau_rad", "tau_pt"
            ],
            out=[
                "xst",  # Flow-normalized channel axial location
                "Is",  # Normalized heat flux
                "beta",  # Spatial development coefficient
            ],
            name="Intermediate Dimensionless Numbers",
        ) >> cp_vec_function(
            fun=lambda df: df_make(
                T_f=(df.Phi_M * df.chi) / (1 + df.Phi_M * df.chi) *
                (df.Is * df.xst - df.Is / df.beta *
                 (1 - exp(-df.beta * df.xst))),
                T_p=1 / (1 + df.Phi_M * df.chi) *
                (df.Phi_M * df.chi * df.Is * df.xst + df.Is / df.beta *
                 (1 - exp(-df.beta * df.xst))),
            ),
            var=["xst", "Phi_M", "chi", "Is", "beta"],
            out=["T_f", "T_p"],
        ) >> cp_bounds(
            ## Normalized axial location; xi = x/L (-)
            xi=(0, 1), ) >> cp_marginals(
                ## Channel width (m)
                H={
                    "dist": "uniform",
                    "loc": 0.038,
                    "scale": 0.004
                },
                ## Channel length (m)
                L={
                    "dist": "uniform",
                    "loc": 0.152,
                    "scale": 0.016
                },
                ## Fluid bulk velocity (m/s)
                U={
                    "dist": "uniform",
                    "loc": 1,
                    "scale": 2.5
                },
                ## Fluid kinematic viscosity (m^2/s)
                nu_f={
                    "dist": "uniform",
                    "loc": 1.4e-5,
                    "scale": 0.1e-5
                },
                ## Particle isobaric heat capacity (J/(kg K))
                cp_p={
                    "dist": "uniform",
                    "loc": 100,
                    "scale": 900
                },
                ## Fluid isobaric heat capacity (J/(kg K))
                cp_f={
                    "dist": "uniform",
                    "loc": 1000,
                    "scale": 1000
                },
                ## Fluid thermal diffusivity (m^2/s)
                alpha_f={
                    "dist": "uniform",
                    "loc": 50e-6,
                    "scale": 50e-6
                },
                ## Particle density (kg / m^3)
                rho_p={
                    "dist": "uniform",
                    "loc": 1e3,
                    "scale": 9e3
                },
                ## Fluid density (kg / m^3)
                rho_f={
                    "dist": "uniform",
                    "loc": 0.5,
                    "scale": 1.0
                },
                ## Particle diameter (m)
                d_p={
                    "dist": "uniform",
                    "loc": 1e-6,
                    "scale": 9e-6
                },
                ## Particle number density (1 / m^3)
                n={
                    "dist": "uniform",
                    "loc": 9.5e9,
                    "scale": 1.0e9
                },
                ## Particle-to-gas convection coefficient (W / (m^2 K))
                h_p={
                    "dist": "uniform",
                    "loc": 1e3,
                    "scale": 9e3
                },
                ## Initial temperature (K)
                T_0={
                    "dist": "uniform",
                    "loc": 285,
                    "scale": 30
                },
                ## Particle radiation absorption coefficient (-)
                Q_abs={
                    "dist": "uniform",
                    "loc": 0.25,
                    "scale": 0.50
                },
                ## Incident radiation (W/m^2)
                I_0={
                    "dist": "uniform",
                    "loc": 9.5e6,
                    "scale": 1.0e6
                },
            ) >> cp_copula_independence())

    return md