Skip to main content

Stoichiometric constraints not working on symbolic regression program

Awaiting user input

Comments

4 comments

  • Eli Towle
    Gurobi Staff Gurobi Staff

    The issue I am encountering is that even when I provide my system with the right reaction and rate constant as an initial guess, I get the same reaction (wrong) as when I don't.

    Gurobi searches for a global solution to the model. A MIP start may help Gurobi find a global solution more quickly, but it does not affect the set of global solutions.

    When I run your code, the optimal reaction vector is [1, 0, 1, 1] and the optimal objective value is ~0.017633. Is this not the optimal solution you expect? If so, what do you expect the optimal solution to be? I don't know anything about stoichiometry, but we could figure out from a mathematical modeling perspective why Gurobi isn't returning the solution you expect. If we fix the reaction to [1, 0, 0, 1], the best achievable objective value is ~0.035266.

    I'm also getting some warnings about my constraints being violated, which I don't get where they are coming from.

    By default, Gurobi versions 11.0.3 and earlier model nonlinear constraints using piecewise-linear approximations. While Gurobi's solution may satisfy all of the constraints of the approximation it builds, that solution may have errors with respect to the underlying nonlinear constraints you are actually modeling. You can read more about this in the documentation for Function Constraints.

    Parameters like FuncPieceError, FuncPieceLength, FuncPieceRatio, and FuncPieces give you control over how Gurobi builds these piecewise-linear approximations. I see you are setting FuncPieces=1, though you may need to build tighter approximations if you want smaller constraint violations. Alternatively, I recommend instead simply setting the FuncNonlinear parameter to 1 - this directs Gurobi to handle the nonlinear constraints directly rather than approximating them. Note that FuncNonlinear=1 will be the default behavior starting in Gurobi 12.0.0, scheduled for release in mid-November.

    Additionally, the log output displays the following warning:

    Warning: Model contains variables with very large bounds participating
             in nonlinear terms.
             Presolve was not able to compute smaller bounds for these variables.
             Consider bounding these variables or reformulating the model.

    It's very important to provide the tightest possible upper and lower bounds on all variables participating in nonlinear constraints and bilinear terms. This will generally help improve performance. If Gurobi is building piecewise-linear approximations of your nonlinear constraints, tighter variable bounds will limit the domain over which Gurobi has to build those approximations, which in general should lead to more accurate approximations and/or better performance. Are you able to add tight bounds to your \(\texttt{temp}\) variables?

    0
  • Manuel Palma
    First Comment
    First Question

    Hi Eli Towle,
    thank you so much for replying.
    Sorry I did not make this clearer:

    # provide init guess
    if 1==2:
        # Suggested initial guess, for example [[1, 0, 0, 0]]
        initial_guess = [[1, 0, 0, 1]]  # Adjust this for your actual size of N_r and 2*N
    
        # Set the initial guess for M
        for ri in range(N_r):
            for ci in range(2 * N):
                M[ri, ci].start = initial_guess[ri][ci]
    
        # Set the initial guess for K
        K[0].start = 0.3

    If I were to allow this part of the script to run I'd be giving the system the actual solution. The correct reaction mechanism is [1,0,0,1] and the correct rate constant is 0.3. Is the system were to predict this exact values the MSE and thus the objective should be very close to 0 (a few sig figs lower than 0.017...). I was trying to say that I do not get that answer even when I allow the system to have the right answer for the MIP start.

    Regarding FuncPieces=1, I meant to comment that out, I was changing the value to address the constraint violation issues and I forgot to remove it. When I did increase, even to 2, it'd result on the system taking VERY long and still not finding the answer.

    Regarding tighter bounds around the temp variables, I did not think of making changes there because I'm implementing constraints to define their values, I never used them as "decision variables". I made change to the script to tighten their bounds to the temp variables as well as "K", but nothing changed. I'll keep tuning that.

    Please let me know if you have any other questions or suggestions.

    0
  • Eli Towle
    Gurobi Staff Gurobi Staff

    The correct reaction mechanism is [1,0,0,1] and the correct rate constant is 0.3. Is the system were to predict this exact values the MSE and thus the objective should be very close to 0 (a few sig figs lower than 0.017...).

    There is no feasible solution to the model satisfying:

    K[0] = 0.3
    M[0,0] = 1
    M[0,1] = 0
    M[0,2] = 0
    M[0,3] = 1

    I fixed these values in the model and computed an irreducible infeasible subsystem (IIS). This is a subset of model constraints and variable bounds that together form an infeasible subsystem, but that subsystem becomes feasible if any individual constraint or bound is removed. That IIS helped explain why this solution is not feasible.

    The model includes the following five constraints:

    C_r_C_A_C_B_7: Conc_reactants_t7 = temp_C_A_7 * temp_C_B_7
    A_Conc_contrib_7: temp_Cr_A_t7 + M[0,0] * Conc_reactants_t7 = M[0,2] * Conc_reactants_t7
    Constr_A_pred_7: A_pred_rate[7] = K[0] * temp_Cr_A_t7
    ExpA_temp_C_A_7: temp_C_A_7 = EXP ( temp_A_log_7 )
    ExpA_temp_C_B_7: temp_C_B_7 = EXP ( temp_B_log_7 )

    Let's assume for contradiction there exists a feasible solution with \(\texttt{M[0,0]}=1\), \(\texttt{M[0,2]}=0\), and \(\texttt{K[0]}=0.3\). We can plug these three values into the constraints above to simplify the constraints:

    C_r_C_A_C_B_7: Conc_reactants_t7 = temp_C_A_7 * temp_C_B_7
    A_Conc_contrib_7: Conc_reactants_t7 = - temp_Cr_A_t7
    Constr_A_pred_7: A_pred_rate[7] = 0.3 * temp_Cr_A_t7
    ExpA_temp_C_A_7: temp_C_A_7 = EXP ( temp_A_log_7 )
    ExpA_temp_C_B_7: temp_C_B_7 = EXP ( temp_B_log_7 )

    Next, let's substitute the definitions of \(\texttt{temp_C_A_7}\) and \(\texttt{temp_C_B_7}\) from the last two constraints into constraint \(\texttt{C_r_C_A_C_B_7}\):

    C_r_C_A_C_B_7: Conc_reactants_t7 = EXP ( temp_A_log_7 ) * EXP ( temp_B_log_7 )
    A_Conc_contrib_7: Conc_reactants_t7 = - temp_Cr_A_t7
    Constr_A_pred_7: A_pred_rate[7] = 0.3 * temp_Cr_A_t7

    It follows from constraint \(\texttt{Constr_A_pred_7}\) that \(\texttt{temp_Cr_A_t7} = (10 / 3) \cdot \texttt{A_pred_rate[7]}\). We substitute this value into constraint \(\texttt{A_Conc_contrib_7}\) to get

    C_r_C_A_C_B_7: Conc_reactants_t7 = EXP ( temp_A_log_7 ) * EXP ( temp_B_log_7 )
    A_Conc_contrib_7: Conc_reactants_t7 = - (10 / 3) * A_pred_rate[7]

    Now, we have two different expressions, both of which are equal to variable \( \texttt{Conc_reactants_t7} \). These expressions must therefore equal each other:

    EXP ( temp_A_log_7 ) * EXP ( temp_B_log_7 ) = - (10 / 3) * A_pred_rate[7]

    The left-hand side of this constraint is strictly positive, regardless of the values of \(\texttt{temp_A_log_7}\) and \(\texttt{temp_B_log_7}\). However, \(\texttt{A_pred_rate[7]}\) is defined to be a non-negative variable, so the right-hand side of this constraint is non-positive. This is a contradiction. Thus, no solution to the model can satisfy \(\texttt{M[0,0]}=1\), \(\texttt{M[0,2]}=0\), and \(\texttt{K[0]}=0.3\).

    Did you intend for the \(\texttt{A_pred_rate}\) and \(\texttt{B_pred_rate}\) variables to be non-negative? The default lower bound on variables is 0. The fix might be as simple as adding the keyword argument \(\texttt{lb=-GRB.INFINITY}\) to the corresponding Model.addVars() calls.

    0
  • Manuel Palma
    First Comment
    First Question

    Eli Towle It was indeed that simple! Thank you so so much for your help.
    I did not know that IIS was a thing! Great to have another tool at my disposal.

    0

Please sign in to leave a comment.