Commit cc1f5639 authored by Kirill Terekhov's avatar Kirill Terekhov
Browse files

remove memory pool and pool_array container, as it seems to fail with some compilers

parent 1d18064d
......@@ -18,19 +18,19 @@ namespace INMOST
template<> Demote<variable>::type AbstractEntry::Access<variable> (const Storage& e, INMOST_DATA_ENUM_TYPE pos) const {return Unknown(e,pos);}
template<> Demote<hessian_variable>::type AbstractEntry::Access<hessian_variable> (const Storage& e, INMOST_DATA_ENUM_TYPE pos) const {return Unknown(e,pos);}
template<>
Matrix<Demote<INMOST_DATA_REAL_TYPE>::type, pool_array_t<Demote<INMOST_DATA_REAL_TYPE>::type> >
Matrix<Demote<INMOST_DATA_REAL_TYPE>::type>
AbstractEntry::Access<INMOST_DATA_REAL_TYPE> (const Storage& e) const {return Value(e);}
template<>
Matrix<Demote<INMOST_DATA_INTEGER_TYPE>::type, pool_array_t<Demote<INMOST_DATA_INTEGER_TYPE>::type> >
Matrix<Demote<INMOST_DATA_INTEGER_TYPE>::type>
AbstractEntry::Access<INMOST_DATA_INTEGER_TYPE>(const Storage& e) const {return Index(e);}
template<>
Matrix<Demote<unknown>::type, pool_array_t<Demote<unknown>::type> >
Matrix<Demote<unknown>::type>
AbstractEntry::Access<unknown>(const Storage& e) const {return Unknown(e);}
template<>
Matrix<Demote<variable>::type, pool_array_t<Demote<variable>::type> >
Matrix<Demote<variable>::type>
AbstractEntry::Access<variable>(const Storage& e) const {return Unknown(e);}
template<>
Matrix<Demote<hessian_variable>::type,pool_array_t<Demote<hessian_variable>::type> >
Matrix<Demote<hessian_variable>::type >
AbstractEntry::Access<hessian_variable>(const Storage& e) const {return Unknown(e);}
......@@ -423,9 +423,9 @@ namespace INMOST
throw Impossible;
}
rpMatrix MultiEntry::Value(const Storage & e) const
rMatrix MultiEntry::Value(const Storage & e) const
{
rpMatrix ret(MatrixSize(e),1);
rMatrix ret(MatrixSize(e),1);
unsigned l = 0, r, t;
for(unsigned k = 0; k < entries.size(); ++k) if( entries[k]->isValid(e) )
{
......@@ -436,9 +436,9 @@ namespace INMOST
return ret;
}
ipMatrix MultiEntry::Index(const Storage & e) const
iMatrix MultiEntry::Index(const Storage & e) const
{
ipMatrix ret(MatrixSize(e),1);
iMatrix ret(MatrixSize(e),1);
unsigned l = 0, r, t;
for(unsigned k = 0; k < entries.size(); ++k) if( entries[k]->isValid(e) )
{
......@@ -449,9 +449,9 @@ namespace INMOST
return ret;
}
upMatrix MultiEntry::operator [](const Storage & e) const
uMatrix MultiEntry::operator [](const Storage & e) const
{
upMatrix ret(MatrixSize(e),1);
uMatrix ret(MatrixSize(e),1);
unsigned l = 0, r, t;
for(unsigned k = 0; k < entries.size(); ++k) if( entries[k]->isValid(e) )
{
......
......@@ -329,7 +329,7 @@ namespace INMOST
Element e;
for(Mesh::iteratorElement jt = m->BeginElement(etype); jt != m->EndElement(); ++jt) if( jt->GetStatus() != Element::Ghost )
{
rpMatrix err = R.Value(it->second->Index(jt->self()));
rMatrix err = R.Value(it->second->Index(jt->self()));
double block_err = err.FrobeniusNorm();
if( block_err > max_err )
{
......
......@@ -110,9 +110,9 @@ namespace INMOST
return ret;
}
rpMatrix Residual::Value(const AbstractMatrix<INMOST_DATA_INTEGER_TYPE> & rows) const
rMatrix Residual::Value(const AbstractMatrix<INMOST_DATA_INTEGER_TYPE> & rows) const
{
rpMatrix ret(rows.Rows(),rows.Cols());
rMatrix ret(rows.Rows(),rows.Cols());
for(INMOST_DATA_ENUM_TYPE i = 0; i < rows.Rows(); ++i)
for(INMOST_DATA_ENUM_TYPE j = 0; j < rows.Cols(); ++j)
ret(i,j) = residual[rows(i,j)];
......
......@@ -1596,396 +1596,6 @@ namespace INMOST
const T * operator ->() const {return &item;}
};
#endif //_OPENMP
class memory_pool
{
static const unsigned pool_size_bits = 16;
//typedef char pool_type[pool_size];
typedef std::map<void *,unsigned> page_fault_type;
std::vector< char * > pool; ///< Data storage
std::vector<bool> inuse; ///< marks block as in use, for unordered deallocation
std::vector<unsigned> last_alloc; ///< Last allocated block position, used to track allocation
page_fault_type page_fault;
public:
unsigned last_byte() const {return last_alloc.back();}
unsigned allocations() const {return (unsigned)(inuse.size()-1); }
memory_pool()
{
//void * tmp = malloc(sizeof(char)*(1 << pool_size_bits));
char * tmp = new char[1 << pool_size_bits];
#if defined(DEBUGMEM)
if( tmp == NULL ) {std::cout << __FILE__ << ":" << __LINE__ << "allocation returns NULL\n";}
#endif
pool.push_back((char*)tmp);
last_alloc.push_back(0);
inuse.push_back(true); //never delete
//std::cout << "mempool " << (void *)this << " constructor, addr " << (void *)pool.back() << std::endl;
}
//memory_pool(const memory_pool & b) : pool(b.pool), last_alloc(b.last_alloc) {}
//memory_pool & operator = (memory_pool const & b) {pool = b.pool; last_alloc = b.last_alloc; return *this;}
template<typename T>
void * allocate(unsigned n, const T & c = T())
{
if( sizeof(T)*n < (1 << pool_size_bits) )
{
unsigned oldpos = last_alloc.size() > 0 ? last_alloc.back() : 0;
unsigned newpos = oldpos + sizeof(T)*n;
unsigned pageold = oldpos >> pool_size_bits;
unsigned pagepos = newpos >> pool_size_bits;
unsigned datapos;
if( pagepos == pool.size() )
{
//std::cout << "position from " << oldpos << " to " << newpos << " need new page " << pagepos << std::endl;
//void * tmp = malloc(sizeof(char)*(1 << pool_size_bits));
char * tmp = new char[1 << pool_size_bits];
#if defined(DEBUGMEM)
if( tmp == NULL ) {std::cout << __FILE__ << ":" << __LINE__ << "allocation returns NULL\n";}
#endif
pool.push_back((char*)tmp);
}
if( pagepos != pageold || last_alloc.empty() )
{
//std::cout << "add page " << pagepos << " start marker" << std::endl;
last_alloc.push_back(pagepos << pool_size_bits);
inuse.push_back(false);
oldpos = last_alloc.back();
newpos = oldpos + sizeof(T)*n;
}
datapos = oldpos%(1<<pool_size_bits);
void * data = (void *)&pool[pagepos][datapos];
for(unsigned i = 0; i < n; ++i) new (&static_cast<T *>(data)[i]) T(c);
last_alloc.push_back(newpos);
inuse.push_back(true);
//std::cout << "allocated " << sizeof(T)*n << " bytes from " << oldpos << " to " << newpos << " at page " << pagepos << " at " << data << std::endl;
//std::cout << this << " last_alloc[" << last_alloc.size() << "]:";
//for(unsigned i = 0; i < last_alloc.size(); ++i) std::cout << " " << last_alloc[i] << "(" << (inuse[i] ? '+' : '-') << ")";
//std::cout << std::endl;
return data;
}
else
{
T * data = new T[n];
//for(unsigned i = 0; i < n; ++i) data[i] = c;
//void * data = malloc(sizeof(T)*n);
#if defined(DEBUGMEM)
if( data == NULL ) {std::cout << __FILE__ << ":" << __LINE__ << "allocation returns NULL\n";}
#endif
//for(unsigned i = 0; i < n; ++i) new (&static_cast<T *>(data)[i]) T(c);
std::fill(data,data+n,c);
page_fault[(void *)data] = n;
//std::cout << "page fault for " << sizeof(T)*n << " bytes allocated at " << data << std::endl;
//std::cout << this << " last_alloc[" << last_alloc.size() << "]:";
//for(unsigned i = 0; i < last_alloc.size(); ++i) std::cout << " " << last_alloc[i] << "(" << (inuse[i] ? '+' : '-') << ")";
//std::cout << std::endl;
return (void *)data;
}
}
template<typename T>
void deallocate(T * mem)
{
bool find = false;
unsigned checkpos = (unsigned)last_alloc.size(), oldpos, newpos, pagepos, datapos;
if( checkpos > 1 )
{
while( !find && checkpos > 1 )
{
oldpos = last_alloc[checkpos-2];
newpos = last_alloc[checkpos-1];
pagepos = newpos >> pool_size_bits;
datapos = oldpos % (1 << pool_size_bits);
if( (((T*)&pool[pagepos][datapos]) == mem) )
{
unsigned n = (newpos - oldpos)/sizeof(T);
for(unsigned i = 0; i < n; ++i) mem[i].~T();
inuse[checkpos-1] = false;
find = true;
}
checkpos--;
}
}
//if( find )
// std::cout << "deallocate " << mem << " from " << oldpos << " to " << newpos << " page " << pagepos << std::endl;
//else
// std::cout << "deallocate " << mem << " position not found " << std::endl;
//std::cout << this << " last_alloc[" << last_alloc.size() << "]:";
//for(unsigned i = 0; i < last_alloc.size(); ++i) std::cout << " " << last_alloc[i] << "(" << (inuse[i] ? '+' : '-') << ")";
//std::cout << std::endl;
if( !find )
{
page_fault_type::iterator it = page_fault.find((void *)mem);
assert(it != page_fault.end() && "deallocated block does not match neither last allocated block nor page fault");
if(it == page_fault.end() )
{
// std::cout << "deallocated block does not match neither last allocated block nor page fault";
// throw -1;
}
else
{
//unsigned n = it->second;
//std::cout << "deallocate page fault of " << sizeof(T)*n << " bytes at " << mem << std::endl;
delete [] mem;
//for(unsigned i = 0; i < n; ++i) mem[i].~T();
//free(mem);
page_fault.erase(it);
}
}
while( !inuse.empty() && inuse.back() == false )
{
//std::cout << "pop " << last_alloc.back() << "(" << (inuse.back() ? '+' : '-') << ") sizes " << last_alloc.size() << " " << inuse.size() << std::endl;
inuse.pop_back();
last_alloc.pop_back();
//std::cout << "deallocate from " << oldpos << " to " << newpos << std::endl;
//if( last_alloc.back() != 0 && last_alloc.back()%(1<<pool_size_bits) == 0 )
//{
// std::cout << "next should remove page " << (last_alloc.back() >> pool_size_bits) << " start marker " << std::endl;
//last_alloc.pop_back();
//}
}
}
~memory_pool()
{
//std::cout << "mempool destructor " << (void *)this << " in pool: ";
//if( last_alloc.back() != 0 ) std::cout << "warning: memory pool not empty on deallocation!!!" << std::endl;
for(unsigned k = 0; k < pool.size(); ++k)
{
//std::cout << (void *)pool[k] << " ";
//free(pool[k]);
delete [] pool[k];
}
//std::cout << std::endl;
pool.clear();
if( !page_fault.empty() )
{
std::cout << "warning: memory pool's page fault not empty on deallocation!!!" << std::endl;
//for(page_fault_type::iterator it = page_fault.begin(); it != page_fault.end(); ++it)
//free(it->first);
//delete [] static_cast<T *>(it->first);
}
}
};
//static thread_private<memory_pool> _pool;
memory_pool & get_pool();
template<typename element>//, typename enumerator = unsigned int>
class pool_array
{
public:
typedef unsigned size_type;
typedef make_unsigned<size_type>::type uenum;
template<typename etype>
class _iterator
{
private:
etype * e;
public:
typedef etype * pointer;
typedef etype & reference;
typedef etype value_type;
typedef ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
_iterator():e(NULL){}
_iterator(etype * i):e(i){}
_iterator(const _iterator & other){e = other.e;}
~_iterator() {};
_iterator operator -(size_t n) const { return _iterator(e-n); }
_iterator & operator -=(size_t n) { e-=n; return *this; }
_iterator operator +(size_t n) const { return _iterator(e+n); }
_iterator & operator +=(size_t n) { e+=n; return *this; }
_iterator & operator ++(){ ++e; return *this;}
_iterator operator ++(int){ return _iterator(e++); }
_iterator & operator --(){ --e; return *this; }
_iterator operator --(int){ return _iterator(e--); }
ptrdiff_t operator -(const _iterator & other) const {return e-other.e;}
etype & operator *() const { return *e; }
etype * operator ->() const { return e; }
_iterator & operator =(_iterator const & other) { e = other.e; return *this; }
bool operator ==(const _iterator & other) const { return e == other.e;}
bool operator !=(const _iterator & other) const { return e != other.e;}
bool operator <(const _iterator & other) const { return e < other.e;}
bool operator >(const _iterator & other) const { return e > other.e;}
bool operator <=(const _iterator & other) const { return e <= other.e;}
bool operator >=(const _iterator & other) const { return e >= other.e;}
operator void *() {return static_cast<void *> (e);}
operator const void *() const {return const_cast<const void *> (e);}
};
typedef _iterator<element> iterator;
typedef _iterator<const element> const_iterator;
template<typename etype>
class _reverse_iterator
{
private:
etype * e;
public:
typedef etype * pointer;
typedef etype & reference;
typedef etype value_type;
typedef ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
_reverse_iterator():e(NULL){}
_reverse_iterator(etype * i):e(i){}
_reverse_iterator(const _reverse_iterator & other){e = other.e;}
~_reverse_iterator() {};
_reverse_iterator operator -(size_t n) const { return _reverse_iterator(e+n); }
_reverse_iterator & operator -=(size_t n) { e+=n; return *this; }
_reverse_iterator operator +(size_t n) const {return _reverse_iterator(e-n); }
_reverse_iterator & operator +=(size_t n) { e-=n; return *this; }
_reverse_iterator & operator ++(){ --e; return *this;}
_reverse_iterator operator ++(int){ return _reverse_iterator(e--); }
_reverse_iterator & operator --(){ ++e; return *this; }
_reverse_iterator operator --(int){ return _reverse_iterator(e++); }
ptrdiff_t operator -(const _reverse_iterator & other) const {return other.e-e;}
etype & operator *() const { return *e; }
etype * operator ->() const { return e; }
_reverse_iterator & operator =(_reverse_iterator const & other) { e = other.e; return *this;}
bool operator ==(const _reverse_iterator & other) const { return e == other.e;}
bool operator !=(const _reverse_iterator & other) const { return e != other.e;}
bool operator <(const _reverse_iterator & other) const { return e < other.e;}
bool operator >(const _reverse_iterator & other) const { return e > other.e;}
bool operator <=(const _reverse_iterator & other) const { return e <= other.e;}
bool operator >=(const _reverse_iterator & other) const { return e >= other.e;}
operator void *() {return static_cast<void *> (e);}
operator const void *() const {return static_cast<const void *> (e);}
};
typedef _reverse_iterator<element> reverse_iterator;
typedef _reverse_iterator<const element> const_reverse_iterator;
private:
element * m_arr;
size_type m_size;
public:
__INLINE element * data() {return m_arr;}
__INLINE const element * data() const {return m_arr;}
pool_array()
{
m_size = 0;
m_arr = NULL;
}
pool_array(size_type n,element c = element())
{
m_size = n;
m_arr = (element *)get_pool().allocate(n,c);
assert(m_arr != NULL);
}
template<class InputIterator>
pool_array(InputIterator first, InputIterator last)
{
//isInputForwardIterators<element,InputIterator>();
m_size = static_cast<size_type>(std::distance(first,last));
m_arr = (element *)get_pool().allocate(m_size,element());
assert(m_arr != NULL);
{
size_type i = 0;
InputIterator it = first;
while(it != last) new (m_arr+i++) element(*it++);
}
}
pool_array(const pool_array & other)
{
m_size = other.m_size;
if( m_size )
{
m_arr = (element *)get_pool().allocate(m_size,element());
assert(m_arr != NULL);
}
else m_arr = NULL;
for(size_type i = 0; i < m_size; i++) new (m_arr+i) element(other.m_arr[i]);
}
~pool_array()
{
get_pool().deallocate(m_arr);
m_arr = NULL;
m_size = 0;
}
__INLINE const element & operator [] (size_type n) const
{
assert(n < m_size);
return m_arr[n];
}
__INLINE element & operator [] (size_type n)
{
assert(n < m_size);
return m_arr[n];
}
__INLINE const element & at (size_type n) const
{
assert(n < m_size);
return m_arr[n];
}
__INLINE element & at (size_type n)
{
assert(n < m_size);
return m_arr[n];
}
void resize(size_type n, element c = element())
{
if( m_size == 0 && m_arr == NULL )
{
m_arr = (element *)get_pool().allocate(n,c);
assert(m_arr != NULL);
m_size = n;
}
else if( n != m_size )
{
assert(false && "resize of non-empty pool_array");
}
}
__INLINE element & back()
{
assert(m_arr != NULL);
assert(m_size > 0);
return m_arr[m_size-1];
}
__INLINE const element & back() const
{
assert(m_arr != NULL);
assert(m_size > 0);
return m_arr[m_size-1];
}
__INLINE element & front()
{
assert(m_arr != NULL);
assert(m_size > 0);
return m_arr[0];
}
__INLINE const element & front() const
{
assert(m_arr != NULL);
assert(m_size > 0);
return m_arr[0];
}
__INLINE size_type capacity() { return m_size; }
__INLINE bool empty() const { if( m_size ) return false; return true; }
__INLINE size_type size() const {return m_size;}
__INLINE size_type capacity() const {return m_size;}
void clear()
{
get_pool().deallocate(m_arr);
m_arr = NULL;
m_size = 0;
}
void swap(pool_array<element> & other)
{
element * t_m_arr = m_arr;
size_type t_m_size = m_size;
m_arr = other.m_arr;
m_size = other.m_size;
other.m_arr = t_m_arr;
other.m_size = t_m_size;
}
__INLINE iterator begin() { return m_arr; }
__INLINE iterator end() { return m_arr+m_size; }
__INLINE const_iterator begin() const { return m_arr; }
__INLINE const_iterator end() const { return m_arr+m_size; }
__INLINE reverse_iterator rbegin() { return reverse_iterator(m_arr+m_size-1); }
__INLINE reverse_iterator rend() { return reverse_iterator(m_arr-1); }
__INLINE const_reverse_iterator rbegin() const { return const_reverse_iterator(m_arr+m_size-1); }
__INLINE const_reverse_iterator rend() const { return const_reverse_iterator(m_arr-1); }
};
}
#endif
......@@ -66,15 +66,15 @@ namespace INMOST
/// @param pos Position for which to extract the unknown, should be no larger then MatrixSize.
virtual unknown Unknown(const Storage & e, INMOST_DATA_ENUM_TYPE pos) const = 0;
/// Return vector filled with values of unknowns of the block.
virtual rpMatrix Value(const Storage & e) const = 0;
virtual rMatrix Value(const Storage & e) const = 0;
/// Return vector filled with indices of unknowns of the block.
virtual ipMatrix Index(const Storage & e) const = 0;
virtual iMatrix Index(const Storage & e) const = 0;
/// Return vector filled with unknowns of the block with their derivatives.
virtual upMatrix Unknown(const Storage & e) const = 0;
virtual uMatrix Unknown(const Storage & e) const = 0;
/// Return vector filled with either values or indices or unknowns of the block,
/// depending on the template parameter.
template<typename T>
Matrix<typename Demote<T>::type, pool_array_t<typename Demote<T>::type> >
Matrix<typename Demote<T>::type>
Access(const Storage &e) const;
/// Return either value or index or unknown at specified position of the block,
/// depending on the template parameter.
......@@ -83,7 +83,7 @@ namespace INMOST
typename Demote<T>::type
Access(const Storage &e, INMOST_DATA_ENUM_TYPE pos) const;
/// Return vector filled with unknowns of the block with their derivatives.
virtual upMatrix operator [](const Storage & e) const = 0;
virtual uMatrix operator [](const Storage & e) const = 0;
/// The intended size of the matrix for this entry.
virtual INMOST_DATA_ENUM_TYPE MatrixSize(const Storage & e) const = 0;
/// Number of tags in block.
......@@ -138,13 +138,13 @@ namespace INMOST
/// Return unknown in vector of variables of the block at certain position.
unknown Unknown(const Storage & e, INMOST_DATA_ENUM_TYPE pos) const {return unknown(Value(e,pos),Index(e,pos));}
/// Return vector filled with values of unknowns of the block.
rpMatrix Value(const Storage & e) const {rpMatrix ret(MatrixSize(e),1); for(unsigned k = 0; k < Size(); ++k) ret(k,0) = Value(e,k); return ret; }
rMatrix Value(const Storage & e) const {rMatrix ret(MatrixSize(e),1); for(unsigned k = 0; k < Size(); ++k) ret(k,0) = Value(e,k); return ret; }
/// Return vector filled with indices of unknowns of the block.
ipMatrix Index(const Storage & e) const {ipMatrix ret(MatrixSize(e),1); for(unsigned k = 0; k < Size(); ++k) ret(k,0) = Index(e,k); return ret; }
iMatrix Index(const Storage & e) const {iMatrix ret(MatrixSize(e),1); for(unsigned k = 0; k < Size(); ++k) ret(k,0) = Index(e,k); return ret; }
/// Return vector filled with unknowns of the block with their derivatives.
upMatrix Unknown(const Storage & e) const {return BlockEntry::operator [](e);}
uMatrix Unknown(const Storage & e) const {return BlockEntry::operator [](e);}
/// Return vector filled with unknowns of the block with their derivatives.
upMatrix operator [](const Storage & e) const {upMatrix ret(MatrixSize(e),1); for(unsigned k = 0; k < Size(); ++k) ret(k,0) = Unknown(e,k); return ret; }
uMatrix operator [](const Storage & e) const {uMatrix ret(MatrixSize(e),1); for(unsigned k = 0; k < Size(); ++k) ret(k,0) = Unknown(e,k); return ret; }
/// The intended size of the matrix for this entry.
INMOST_DATA_ENUM_TYPE MatrixSize(const Storage & e) const {(void)e; return Size();}
/// Number of tags in block.
......@@ -187,13 +187,13 @@ namespace INMOST
/// Return unknown in vector of variables of the block at certain position.
unknown Unknown(const Storage & e, INMOST_DATA_ENUM_TYPE pos) const {assert(pos==0); return unknown(Value(e,pos),Index(e,pos));}
/// Return vector filled with values of unknowns of the block.
rpMatrix Value(const Storage & e) const { rpMatrix ret(1,1); ret(0,0) = Value(e,0); return ret; }
rMatrix Value(const Storage & e) const { rMatrix ret(1,1); ret(0,0) = Value(e,0); return ret; }
/// Return vector filled with indices of unknowns of the block.
ipMatrix Index(const Storage & e) const { ipMatrix ret(1,1); ret(0,0) = Index(e,0); return ret; }
iMatrix Index(const Storage & e) const { iMatrix ret(1,1); ret(0,0) = Index(e,0); return ret; }
/// Return vector filled with unknowns of the block with their derivatives.
upMatrix Unknown(const Storage & e) const {return SingleEntry::operator [](e);}
uMatrix Unknown(const Storage & e) const {return SingleEntry::operator [](e);}
/// Return vector filled with unknowns of the block with their derivatives.
upMatrix operator [](const Storage & e) const { upMatrix ret(1,1); ret(0,0) = Unknown(e,0); return ret; }
uMatrix operator [](const Storage & e) const { uMatrix ret(1,1); ret(0,0) = Unknown(e,0); return ret; }
/// The intended size of the matrix for this entry.
INMOST_DATA_ENUM_TYPE MatrixSize(const Storage & e) const {(void)e; return 1;}
/// Number of tags in block.
......@@ -229,13 +229,13 @@ namespace INMOST
/// Return unknown in vector of variables of the block at certain position.
unknown Unknown(const Storage & e, INMOST_DATA_ENUM_TYPE pos) const {assert(pos<unknown_tag[e].size()); return unknown(Value(e,pos),Index(e,pos));}
/// Return vector filled with values of unknowns of the block.
rpMatrix Value(const Storage & e) const { rpMatrix ret(MatrixSize(e),1); for(int k = 0; k < (int)unknown_tag[e].size(); ++k) ret(k,0) = Value(e,k); return ret; }
rMatrix Value(const Storage & e) const { rMatrix ret(MatrixSize(e),1); for(int k = 0; k < (int)unknown_tag[e].size(); ++k) ret(k,0) = Value(e,k); return ret; }
/// Return vector filled with indices of unknowns of the block.
ipMatrix Index(const Storage & e) const { ipMatrix ret(MatrixSize(e),1); for(int k = 0; k < (int)unknown_tag[e].size(); ++k) ret(k,0) = Index(e,k); return ret; }
iMatrix Index(const Storage & e) const { iMatrix ret(MatrixSize(e),1); for(int k = 0; k < (int)unknown_tag[e].size(); ++k) ret(k,0) = Index(e,k); return ret; }
/// Return vector filled with unknowns of the block with their derivatives.
upMatrix Unknown(const Storage & e) const {return VectorEntry::operator [](e);}
uMatrix Unknown(const Storage & e) const {return VectorEntry::operator [](e);}
/// Return vector filled with unknowns of the block with their derivatives.
upMatrix operator [](const Storage & e) const { upMatrix ret(MatrixSize(e),1); for(int k = 0; k < (int)unknown_tag[e].size(); ++k) ret(k,0) = Unknown(e,k); return ret; }
uMatrix operator [](const Storage & e) const { uMatrix ret(MatrixSize(e),1); for(int k = 0; k < (int)unknown_tag[e].size(); ++k) ret(k,0) = Unknown(e,k); return ret; }
/// The intended size of the matrix for this entry.
INMOST_DATA_ENUM_TYPE MatrixSize(const Storage & e) const {return (INMOST_DATA_ENUM_TYPE)unknown_tag[e].size();}
/// Number of tags in block.
......@@ -285,13 +285,13 @@ namespace INMOST
/// Return unknown in vector of variables of the block at certain position.
unknown Unknown(const Storage & e, INMOST_DATA_ENUM_TYPE pos) const {return unknown(Value(e,pos),Index(e,pos));}
/// Return vector filled with values of unknowns of the block.
rpMatrix Value(const Storage & e) const {rpMatrix ret(MatrixSize(e),1); for(INMOST_DATA_ENUM_TYPE k = 0; k < Size(); ++k) ret(k,0) = Value(e,k); return ret; }
rMatrix Value(const Storage & e) const {rMatrix ret(MatrixSize(e),1); for(INMOST_DATA_ENUM_TYPE k = 0; k < Size(); ++k) ret(k,0) = Value(e,k); return ret; }
/// Return vector filled with indices of unknowns of the block.
ipMatrix Index(const Storage & e) const {ipMatrix ret(MatrixSize(e),1); for(INMOST_DATA_ENUM_TYPE k = 0; k < Size(); ++k) ret(k,0) = Index(e,k); return ret; }<