Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pyoptinterface_based_impl.py and integrate it #104

Merged
merged 2 commits into from
Aug 21, 2024

Conversation

KeShih
Copy link
Contributor

@KeShih KeShih commented Aug 15, 2024

What?

  • Add pyoptinterface_based_impl.py, which uses the PyOptInterface package.
  • Remove the old fast and slow modes, use a unified interface instead.
  • The default solver is HiGHS, we can change the global default solver by invorking set_default_solver(solver_name) in dingo.pyoptinterface_based_impl module. Also, we can change the solver in MetabolicNetwork and MetabolicNetwork class by invoking the method set_solver(self, solver)

How to test it?

  • Test with highs.
python3 tests/fba.py
python3 tests/full_dimensional.py
python3 tests/max_ball.py
python3 tests/scaling.py
python3 tests/rounding.py
python3 tests/sampling.py
  • Test with gurobi.
python3 tests/fba.py gurobi
python3 tests/full_dimensional.py gurobi
python3 tests/max_ball.py gurobi
python3 tests/scaling.py gurobi
python3 tests/rounding.py gurobi
python3 tests/sampling.py gurobi

Documentation

See #106.

@KeShih
Copy link
Contributor Author

KeShih commented Aug 16, 2024

Speed up of fva() and remove_redundant_facets().

In these two functions, we need to solve numerous LPs with similar constraints. Modifying the model rather than constructing a new one can significantly enhance performance, and the PyOptInterface package supports such modifications.

  • fva()

    dingo/dingo/fva.py

    Lines 65 to 70 in 4a961e7

    for i in range(n):
    # Set the ith row of the A matrix as the objective function
    objective_function = A[
    i,
    ]

    Noticing that only the objective function changes after each iteration, optimization can be achieved.
  • remove_redundant_facets()
    The outer loop is a while loop, and the inner loop is a for loop. We observe that throughout the for loop, Aeq_sparse, beq, A_sparse, and [val] remain unchanged. Within each iteration of the for loop, only lb[i], ub[i], and the objective function change. Between consecutive iterations of the for loop, only lb[i] and ub[i] from the previous iteration may be modified. Therefore, we can achieve fine-tuning by adjusting a single model throughout the entire for loop.
    # Loop until nor redundant facets are found
    while removed > 0 or offset > 0:
    removed = 0
    offset = 0
    indices = indices_iter
    indices_iter = []
    Aeq_sparse = sp.csr_matrix(Aeq_res)
    beq = np.array(beq_res)
    b_res = []
    A_res = np.empty((0, n), float)
    for i in indices:
    # Set the ith row of the A matrix as the objective function
    objective_function = A[
    i,
    ]
    redundant_facet_right = True
    redundant_facet_left = True
    # for the maximum
    objective_function_max = np.asarray(
    [-x for x in objective_function]
    )
    model_iter = update_model(
    model_iter,
    n,
    Aeq_sparse,
    beq,
    lb,
    ub,
    A_sparse,
    [val],
    objective_function_max,
    )
    model_iter.optimize()

Experiment (iAF1260 model)

image

# And check whether the computed radius is negative
if r < 0:
print(
"The radius calculated has negative value. The polytope is infeasible or something went wrong with the solver"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please throw an exception here instead of printing a message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

Comment on lines 453 to 454
# Reset the inequality
# model_iter.set_variable_attribute(v[i], poi.VariableAttribute.LowerBound, lb[i])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What these lines stand for?

Copy link
Contributor Author

@KeShih KeShih Aug 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code above will be more symmetrical, but in reality, it carries no meaning. I have removed it.

@KeShih KeShih changed the title Add pyoptInterface_based_impl.py and integrate it Add pyoptinterface_based_impl.py and integrate it Aug 20, 2024
@TolisChal
Copy link
Member

Thanks @KeShih! This is a great contribution!

@TolisChal TolisChal merged commit e2a7e4c into GeomScale:develop Aug 21, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants