18 #ifndef NonlinearSystem_INC
19 #define NonlinearSystem_INC
30 #include <boost/numeric/ublas/matrix.hpp>
31 #include <boost/numeric/ublas/lu.hpp>
32 #include <boost/numeric/ublas/vector.hpp>
33 #include <boost/numeric/ublas/io.hpp>
39 using namespace boost::numeric;
57 ublas::matrix< value_type >
Nr;
58 ublas::matrix< value_type >
gamma;
67 using namespace boost::numeric::ublas;
68 typedef permutation_matrix<std::size_t> pmatrix;
72 pmatrix pm(A.size1());
75 int res = lu_factorize(A,pm);
76 if( res != 0 )
return false;
79 inverse.assign(ublas::identity_matrix<T>(A.size1()));
82 lu_substitute(A, pm, inverse);
96 slopes_.resize( size_, 0);
97 x_.resize( size_, 0 );
99 J_.resize( size_, size_, 0);
100 invJ_.resize( size_, size_, 0);
102 x2.resize( size_, 0);
103 x1.resize( size_, 0);
105 ri.nVec.resize( size_ );
106 dx_ = sqrt( numeric_limits<double>::epsilon() );
118 return system(x_, f_);
123 for(
size_t i = 0; i < size_; i++)
124 for(
size_t j = 0; j < size_; j++)
128 J_(i, j) = (compute_at(temp)[i] - compute_at(x)[i]) / dx_;
134 if( compute_inverse )
144 init.resize(size_, 0);
146 for(
size_t i = 0; i < size_; i++)
152 compute_jacobians( init );
159 ss <<
"=======================================================";
160 ss << endl << setw(25) <<
"State of system: " ;
161 ss <<
" Argument: " << x_ <<
" Value : " << f_;
162 ss << endl << setw(25) <<
"Jacobian: " << J_;
163 ss << endl << setw(25) <<
"Inverse Jacobian: " << invJ_;
170 int num_consv = ri.num_mols - ri.rank;
171 for (
size_t i = 0; i < ri.num_mols; ++i )
173 double temp = x[i] * x[i] ;
177 if ( std::isnan( temp ) or std::isinf( temp ) )
180 for(
auto v : ri.nVec ) cerr << v <<
", ";
188 vector< double > vels;
189 ri.pool->updateReacVelocities( &ri.nVec[0], vels );
191 assert( vels.size() ==
static_cast< unsigned int >( ri.num_reacs ) );
195 for (
int i = 0; i < ri.rank; ++i )
198 for (
int j = i; j < ri.num_reacs; ++j )
199 temp += ri.Nr(i, j ) * vels[j];
204 for (
int i = 0; i < num_consv; ++i )
206 double dT = - ri.T[i];
207 for (
size_t j = 0; j < ri.num_mols; ++j )
208 dT += ri.gamma(i, j) * x[j] * x[j];
210 f[ i + ri.rank] = dT ;
228 double norm2OfDiff = 1.0;
230 int status = apply();
232 while( ublas::norm_2(f_) >= tolerance )
235 compute_jacobians( x_,
true );
244 if( iter >= max_iter )
251 if( iter >= max_iter )
267 x[which_dimen] += dx_;
272 return ublas::norm_2( (x2 - x1)/dx_ );
294 double factor = 1e-2;
298 compute_jacobians( x_,
false );
301 direction = ublas::prod( J_, f_ );
302 nextState = x_ - factor * direction;
303 if( ublas::norm_2( compute_at( nextState ) ) >= ublas::norm_2(compute_at(x_)))
304 factor = factor / 2.0;
307 cerr <<
"Correction term applied ";
bool inverse(const ublas::matrix< T > &input, ublas::matrix< T > &inverse)
Id init(int argc, char **argv, bool &doUnitTests, bool &doRegressionTests, unsigned int &benchmark)
int system(const vector_type &x, vector_type &f)
vector_type compute_at(const vector_type &x)
NonlinearSystem(size_t systemSize)
ublas::vector< value_type > vector_type
int compute_jacobians(const vector_type &x, bool compute_inverse=true)
ublas::matrix< value_type > gamma
value_type slope(unsigned int which_dimen)
Compute the slope of function in given dimension.
ublas::matrix< value_type > matrix_type
ublas::matrix< value_type > Nr
double convergenceCriterion
void initialize(const T &x)
bool find_roots_gnewton(double tolerance=1e-7, size_t max_iter=50)
Find roots using Newton-Raphson method.
void correction_step()
Makes the first guess. After this call the Newton method.