Commit d5238a96 authored by Kirill Terekhov's avatar Kirill Terekhov

Functions to detect infs and nans in matrices and variables; correct a bug...

Functions to detect infs and nans in matrices and variables; correct a bug that tags in Autodiff::SynchronizeData were sorted based on memory location instead of name, leading to different order on different processors (and incorrect synchronization)
parent 51cea7c7
......@@ -502,17 +502,26 @@ namespace INMOST
{
//synchronize indices
{
std::map<Mesh *,std::set<Tag> > exch_tags;
std::map<Mesh *,std::map<std::string,Tag> > exch_tags;
ElementType exch_mask = NONE;
for (unsigned it = 0; it < reg_blocks.size(); ++it) if( act_blocks[it] )
{
exch_mask |= reg_blocks[it]->GetElementType();
for(unsigned jt = 0; jt < reg_blocks[it]->Size(); ++jt)
exch_tags[reg_blocks[it]->GetValueTag(jt).GetMeshLink()].insert(reg_blocks[it]->GetValueTag(jt));
exch_tags[reg_blocks[it]->GetValueTag(jt).GetMeshLink()][reg_blocks[it]->GetValueTag(jt).GetTagName()] = reg_blocks[it]->GetValueTag(jt);
}
for(std::map<Mesh *,std::set<Tag> >::iterator it = exch_tags.begin(); it != exch_tags.end(); ++it)
for(std::map<Mesh *,std::map<std::string,Tag> >::iterator it = exch_tags.begin(); it != exch_tags.end(); ++it)
{
it->first->ExchangeData(std::vector<Tag>(it->second.begin(),it->second.end()), exch_mask,0);
std::vector<Tag> sync;
//std::cout << "Synchronize tags: ";
for(std::map<std::string,Tag>::iterator jt = it->second.begin(); jt != it->second.end(); ++jt)
{
sync.push_back(jt->second);
//std::cout << jt->first << " ";
}
//std::cout << std::endl;
it->first->ExchangeData(sync, exch_mask,0);
}
}
}
......
......@@ -171,13 +171,27 @@ namespace INMOST
virtual void Resize(enumerator rows, enumerator cols) = 0;
/// Check all matrix entries for nans.
/// Also checks derivatives for matrices of variables.
bool CheckNans()
bool CheckNans() const
{
for(enumerator i = 0; i < Rows(); ++i)
for(enumerator j = 0; j < Cols(); ++j)
if( check_nans((*this)(i,j)) ) return true;
return false;
}
bool CheckInfs() const
{
for(enumerator i = 0; i < Rows(); ++i)
for(enumerator j = 0; j < Cols(); ++j)
if( check_infs((*this)(i,j)) ) return true;
return false;
}
bool CheckNansInfs() const
{
for(enumerator i = 0; i < Rows(); ++i)
for(enumerator j = 0; j < Cols(); ++j)
if( check_nans_infs((*this)(i,j)) ) return true;
return false;
}
/// Singular value decomposition.
/// Reconstruct matrix: A = U*Sigma*V.Transpose().
/// Source http://www.public.iastate.edu/~dicook/JSS/paper/code/svd.c
......@@ -2426,5 +2440,11 @@ INMOST::Matrix<typename INMOST::Promote<INMOST::hessian_variable,typeB>::type> o
{return other*coef;}
#endif
template<typename T>
__INLINE bool check_nans(const INMOST::AbstractMatrix<T> & A) {return A.CheckNans();}
template<typename T>
__INLINE bool check_infs(const INMOST::AbstractMatrix<T> & A) {return A.CheckInfs();}
template<typename T>
__INLINE bool check_nans_infs(const INMOST::AbstractMatrix<T> & A) {return A.CheckNansInfs();}
#endif //INMOST_DENSE_INCLUDED
......@@ -115,6 +115,10 @@ namespace INMOST
{
return value != value;
}
bool check_infs() const
{
return std::isinf(value);
}
};
#if defined(PACK_ARRAY)
......@@ -282,6 +286,13 @@ namespace INMOST
if( it->second != it->second ) return true;
return false;
}
bool check_infs() const
{
if( std::isinf(value) ) return true;
for(Sparse::Row::const_iterator it = entries.Begin(); it != entries.End(); ++it)
if( std::isinf(it->second) ) return true;
return false;
}
/// Write variable into array of entries.
/// Size of array can be determined via RecordSize.
/// Used internally by Mesh::GetData.
......@@ -550,6 +561,15 @@ namespace INMOST
if( it->second != it->second ) return true;
return false;
}
bool check_infs() const
{
if( std::isinf(value)) return true;
for(Sparse::Row::const_iterator it = entries.Begin(); it != entries.End(); ++it)
if( std::isinf(it->second) ) return true;
for(Sparse::HessianRow::const_iterator it = hessian_entries.Begin(); it != hessian_entries.End(); ++it)
if( std::isinf(it->second) ) return true;
return false;
}
friend class hessian_multivar_expression_reference;
};
#if defined(PACK_ARRAY)
......@@ -722,6 +742,13 @@ namespace INMOST
if( it->second != it->second ) return true;
return false;
}
bool check_infs() const
{
if( std::isinf(value) ) return true;
for(Sparse::Row::iterator it = entries->Begin(); it != entries->End(); ++it)
if( std::isinf(it->second) ) return true;
return false;
}
};
......@@ -928,6 +955,15 @@ namespace INMOST
if( it->second != it->second ) return true;
return false;
}
bool check_infs() const
{
if( std::isinf(value) ) return true;
for(Sparse::Row::iterator it = entries->Begin(); it != entries->End(); ++it)
if( std::isinf(it->second) ) return true;
for(Sparse::HessianRow::iterator it = hentries->Begin(); it != hentries->End(); ++it)
if( std::isinf(it->second) ) return true;
return false;
}
};
......@@ -2015,6 +2051,14 @@ __INLINE bool check_nans(INMOST_DATA_REAL_TYPE val) {return val != val;}
__INLINE bool check_nans(INMOST::var_expression const & e) {return e.check_nans();}
__INLINE bool check_nans(INMOST::multivar_expression const & e) {return e.check_nans();}
__INLINE bool check_nans(INMOST::multivar_expression_reference const & e) {return e.check_nans();}
__INLINE bool check_infs(INMOST_DATA_REAL_TYPE val) {return std::isinf(val);}
__INLINE bool check_infs(INMOST::var_expression const & e) {return e.check_infs();}
__INLINE bool check_infs(INMOST::multivar_expression const & e) {return e.check_infs();}
__INLINE bool check_infs(INMOST::multivar_expression_reference const & e) {return e.check_infs();}
__INLINE bool check_nans_infs(INMOST_DATA_REAL_TYPE val) {return check_nans(val) || check_infs(val);}
__INLINE bool check_nans_infs(INMOST::var_expression const & e) {return e.check_nans() || e.check_infs();}
__INLINE bool check_nans_infs(INMOST::multivar_expression const & e) {return e.check_nans() || e.check_infs();}
__INLINE bool check_nans_infs(INMOST::multivar_expression_reference const & e) {return e.check_nans() || e.check_infs();}
template<class A, class B, class C> __INLINE INMOST::condition_expression<A,B,C> condition(INMOST::shell_expression<A> const & control, INMOST::shell_expression<B> const & if_ge_zero, INMOST::shell_expression<C> const & if_lt_zero) { return INMOST::condition_expression<A,B,C>(control,if_ge_zero,if_lt_zero); }
__INLINE INMOST_DATA_REAL_TYPE condition(INMOST_DATA_REAL_TYPE control, INMOST_DATA_REAL_TYPE if_ge_zero, INMOST_DATA_REAL_TYPE if_lt_zero) {return control >= 0.0 ? if_ge_zero : if_lt_zero;}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment