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

adjoints + steadystate #1099

Merged
merged 82 commits into from
Jun 19, 2020
Merged

adjoints + steadystate #1099

merged 82 commits into from
Jun 19, 2020

Conversation

paulstapor
Copy link
Contributor

Just want to see whether checks pass.
PR for this one will be done by @paszkow from his fork, after confirming his scripts still run and results are correct.

Łukasz Paszkowski and others added 30 commits January 19, 2020 14:12
Let both methods have all parameters required by model specified
implementation similarily as it is done for fJ and fJSparse methods.
The NewtonSolver contains a prepareLinearSystemB method that
retrieves and passes the Jacobian JB. This allows solving linear
systems JB*x = rhs.
When a linear system is prepared construct a Jacobian and use it
directly in matrix-vector multiplication instead of mutliple calls
to Model::fJv.
Avoid backwards integration to compute sensitivities when handled
with a steady-state solution. It is enough to solve a linear system.
@paulstapor paulstapor marked this pull request as ready for review June 18, 2020 12:05
@paulstapor
Copy link
Contributor Author

So, from my side, this should be mergable now.
Doing some last checks on this with @paszkow , but beyond that, the code should be fine...

@paulstapor paulstapor requested a review from FFroehlich June 18, 2020 12:46
@@ -225,24 +225,27 @@ class ReturnData {
/** employed order forward problem (dimension: nt) */
std::vector<int> order;

/** computation time of forward solve [s] */
/** computation time of forward solve [ms] */
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We used to have time reporting not uniformly. At least for one of them, the unit was incorrect. Now, everything should actually be in milliseconds.
No preference, whether seconds or milliseconds are better. We just need to have it the same way for all cpu times...

Copy link
Member

Choose a reason for hiding this comment

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

preferring seconds. but either is fine, if coherently used. good to include it already in the variable/function name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@paszkow proposed to use the chorno library (https://en.cppreference.com/w/cpp/chrono), which looks nicer and may be more precise than what we currently have...
Maybe something for the future?

Copy link
Member

@FFroehlich FFroehlich left a comment

Choose a reason for hiding this comment

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

Looks good 👍

assert rdatas[sensi_meth]['status'] == amici.AMICI_SUCCESS
settings = []
for equil_meth in [amici.SteadyStateSensitivityMode.newtonOnly,]:
# amici.SteadyStateSensitivityMode.simulationFSA,]:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
# amici.SteadyStateSensitivityMode.simulationFSA,]:
amici.SteadyStateSensitivityMode.simulationFSA,]:

settings = []
for equil_meth in [amici.SteadyStateSensitivityMode.newtonOnly,]:
# amici.SteadyStateSensitivityMode.simulationFSA,]:
for sensi_meth in [amici.SensitivityMethod.forward,
Copy link
Member

Choose a reason for hiding this comment

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

use itertools.product to reduce nesting?

for (int jt = model->nt() - 1; jt >= 0; jt--)
if (std::isinf(model->getTimepoint(it)))
--it;
if (it < model->nt() - 1){
Copy link
Member

Choose a reason for hiding this comment

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

cant we just initialize xQB to zeros for it < model->nt() - 1 and pass it to initializeB? I think that would be better readable. Also shouldn't if/else cases be switched here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem ist that, if we have postequilibration (which is the case for it < model->nt() - 1), xQB already contains the quadratures from backward postequilibration. Hence, in that case, we don't want to overwrite them, but still want to reinitialize xB and dxB.
I have another idea, which should simplify this. Will commit.

/* reinit states */
solver->reInitB(which, t, xB, dxB);
solver->quadReInitB(which, xQB);
/* we still need to integrate from first datapoint to tstart */
Copy link
Member

Choose a reason for hiding this comment

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

I believe this code should be outside the loop, we only want to run this once.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True. Done.

// Get the diagonal and ensure negativity of entries is ns_J. Note that diag(JB) = -diag(J).
model->fJDiag(*t, ns_Jdiag, 0.0, *x, dx);

ns_p.set(1.0);
Copy link
Member

Choose a reason for hiding this comment

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

duplicate code, move to seperate function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yikes. This code will be removed soon anyway, current issue, see #1073.
This is really an old handcrafted reimplementation of BICGSTAB. Prefer not to do changes now, but to fully remove and correctly reimplement the remaining linear solvers (i.e., all except DENSE and KLU).

@@ -271,7 +325,7 @@ void NewtonSolverIterative::linsolveSPBCG(int ntry, int nnewt,
double alpha = 1.0;

// can be set to 0 at the moment
Copy link
Member

Choose a reason for hiding this comment

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

I believe this comment is deprecated

CMakeLists.txt Outdated
@@ -1,7 +1,7 @@
#
# Build AMICI library
#
cmake_minimum_required(VERSION 3.3)
cmake_minimum_required(VERSION 3.12)
Copy link
Member

Choose a reason for hiding this comment

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

What was that for if there is no other change in CMake files?

Copy link
Contributor Author

@paulstapor paulstapor Jun 18, 2020

Choose a reason for hiding this comment

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

@paszkow pointed out that using the option --parallel requires at least 3.12., this is why I just put it...
Can also remove for the moment, if this comes with issues...

Copy link
Member

Choose a reason for hiding this comment

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

Hmm... that would have to be checked in the build script. Here it is too late.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

okay, I see. ... yes, okay. I'll remove for the moment. Let's do that later and not mix up too many things.

solver->setupB(&which, model->getTimepoint(it), model, xB, dxB, xQB);
/* If we have posteq, infty timepoints were already treated */
for (int jt = model->nt() - 1; jt >= 0; jt--)
if (std::isinf(model->getTimepoint(it)))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (std::isinf(model->getTimepoint(it)))
if (std::isinf(model->getTimepoint(jt)))

?

Otherwise this loop does not make much sense, does it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

arg, true...!


--it;
if ((it >= 0 || discs.size() > 0) && model->getTimepoint(it) > model->t0())
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if ((it >= 0 || discs.size() > 0) && model->getTimepoint(it) > model->t0())
if ((it >= 0 || !discs.empty()) && model->getTimepoint(it) > model->t0())

@@ -12,11 +12,13 @@
#include <cstring>
#include <ctime>
#include <cmath>
#include <iostream>
Copy link
Member

Choose a reason for hiding this comment

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

Unused?! Leftover from debugging?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, aye... Looks old...

@FFroehlich
Copy link
Member

are JB and JSparseB generated in both MATLAB and Python interfaces?

@paulstapor
Copy link
Contributor Author

are JB and JSparseB generated in both MATLAB and Python interfaces?

Yes, also Matlab generates JB and JSparseB

@paulstapor
Copy link
Contributor Author

If tests pass now, would be strongly in favor of merging now...
If anyone present, for any reason knows why these changes should not be merged, let him speak now or forever hold his peace.

@sonarqubecloud
Copy link

SonarCloud Quality Gate failed.

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities (and Security Hotspot 0 Security Hotspots to review)
Code Smell A 3 Code Smells

27.3% 27.3% Coverage
4.7% 4.7% Duplication

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.

4 participants