22#ifndef LOSSYSTORAGE_HH
23#define LOSSYSTORAGE_HH
32#include <boost/unordered_map.hpp>
36bool abscompare(
double a,
double b ) {
return fabs( a ) < fabs( b ) ; }
41template <
class VariableSet,
class Gr
id,
int D=2>
50 long int nIntervals = (
long int) ceil( range / aTol / 2.0 ) ;
51 if( nIntervals % 2 == 0 )
return nIntervals + 1 ;
58template <
class Gr
id,
class VariableSet,
class Space,
class QuantizationPolicy=UniformQuantizationPolicy<VariableSet,Gr
id,Gr
id::dimension> >
62 static const int dim = Grid::dimension ;
66 typedef boost::fusion::vector<Space const*>
Spaces ;
71 typedef typename Grid::template Codim<dim>::LeafIndexSet
IndexSet ;
77 QuantizationPolicy& quantizationPolicy_ = QuantizationPolicy() )
78 : gridManager(gridManager_), varSet(varSet_), coarseLevel(coarseLevel_), aTol(aTol_),
79 count(0), firstCall(true), uniform(uniform_), order(1),
quantizationPolicy(quantizationPolicy_)
83 previousIndices =
new typename VariableSet::VariableSet(varSet) ;
86 unsigned long int ID ;
87 for(
int level = 0 ; level <= gridManager.
grid().maxLevel() ; level++ )
90 it != gridManager.
grid().levelGridView( level ).end<
dim>(); ++ it)
92 ID = gridManager.
grid().globalIdSet().id( *it ) ;
93 if( levelInfo.find(ID) != levelInfo.end() ) continue ;
94 levelInfo[ID] = level ;
103 delete previousIndices ;
111 typename VariableSet::VariableSet
encode(
typename VariableSet::VariableSet
const& sol, std::string fn )
115 std::ostringstream debugfn ;
117 IndexSet const& indexSet = varSet.indexSet ;
118 typename VariableSet::VariableSet predictionError(varSet) ;
119 predictionError *= 0 ;
123 Space space( gridManager, gv, order ) ;
125 std::string varNames[1] = {
"pred" };
131 std::vector<std::vector<ULong> > allIndices ;
132 std::vector<ULong> indices ;
133 std::vector<double> nodalValues ;
139 nodalValues.push_back( -(*boost::fusion::at_c<0>(sol.data))[indexSet.index(*it)] ) ;
142 double ub = *std::max_element( nodalValues.begin(), nodalValues.end() ) ;
143 double lb = *std::min_element( nodalValues.begin(), nodalValues.end() ) ;
146 ub = *std::max_element( nodalValues.begin(), nodalValues.end(),
abscompare ) ;
147 if( ub < 0 ) { lb = ub ; ub = -lb ; }
151 double range = ub - lb ;
154 if( range > 0 ) maxBits = -ld(aTol) ;
156 if( maxBits < 0 ) maxBits = 0 ;
157 maxIntervals = (
long int)ceil(pow( 2, maxBits ));
159 std::ofstream out( fn.c_str(), std::ios::binary ) ;
160 out.write(
reinterpret_cast<char*
>( &lb ),
sizeof(
double) ) ;
161 out.write(
reinterpret_cast<char*
>( &ub ),
sizeof(
double) ) ;
163 int vertexCount = 0 ;
166 quantize( nodalValues, indices, coarseLevel, lb, ub ) ;
170 allIndices.push_back( indices ) ;
171 reconstruct( nodalValues, indices, coarseLevel, lb, ub ) ;
175 indices.clear() ; indices.resize(nodalValues.size(), 0);
178 it != gridManager.
grid().levelGridView( coarseLevel ).template end<dim>(); ++it )
180 indices[vertexCount] = quantize( nodalValues[vertexCount], lb, ub, it->geometry().corner(0) );
181 nodalValues[vertexCount] = reconstruct( indices[vertexCount], lb, ub, it->geometry().corner(0) );
184 allIndices.push_back( indices ) ;
194 (*boost::fusion::at_c<0>(x.
data))[gv.indexSet().index(*it)] -= nodalValues[vertexCount] ;
198 int maxLevel = gridManager.
grid().maxLevel() ;
200 for(
int l = coarseLevel ; l < maxLevel ; l++ )
202 itEnd = gridManager.
grid().levelGridView( l+1 ).template end<dim>();
204 gv = gridManager.
grid().levelView(l+1) ;
205 space.setGridView(gv);
207 *boost::fusion::at_c<0>(x.
data) = *(mlTransfer->apply(l, *boost::fusion::at_c<0>(x.
data))) ;
209 nodalValues.clear() ;
213 double val = (*boost::fusion::at_c<0>(x.
data))[gv.indexSet().index(*it)]
214 -(*boost::fusion::at_c<0>(sol.data))[gridManager.
grid().leafIndexSet().index(*it)] ;
216 unsigned ID = gridManager.
grid().globalIdSet().id( *it ) ;
217 unsigned char vertexLevel = levelInfo[ID] ;
218 if( vertexLevel == l+1 ) nodalValues.push_back(val);
221 ub = *std::max_element( nodalValues.begin(), nodalValues.end() ) ;
222 lb = *std::min_element( nodalValues.begin(), nodalValues.end() ) ;
225 ub = *std::max_element( nodalValues.begin(), nodalValues.end(),
abscompare ) ;
226 if( ub < 0 ) { lb = ub ; ub = -lb ; }
229 out.write(
reinterpret_cast<char*
>( &lb ),
sizeof(
double) ) ;
230 out.write(
reinterpret_cast<char*
>( &ub ),
sizeof(
double) ) ;
234 quantize( nodalValues, indices, l+1, lb, ub) ;
235 allIndices.push_back( indices ) ;
236 reconstruct( nodalValues, indices, l+1, lb, ub ) ;
241 indices.clear() ; indices.resize(nodalValues.size(), 0);
247 indices[vertexCount] = quantize( nodalValues[vertexCount], lb, ub, it->geometry().corner(0) );
248 nodalValues[vertexCount] = reconstruct( indices[vertexCount], lb, ub, it->geometry().corner(0) );
251 allIndices.push_back( indices ) ;
260 unsigned ID = gridManager.
grid().globalIdSet().id( *it ) ;
261 unsigned char vertexLevel = levelInfo[ID] ;
262 if( vertexLevel < l+1 ) { continue ; }
264 int idx = gv.indexSet().index(*it) ;
265 (*boost::fusion::at_c<0>(x.
data))[idx] -= nodalValues[vertexCount] ;
271 typename VariableSet::VariableSet pred(varSet) ;
273 it != gridManager.
grid().levelGridView(maxLevel).template end<dim>(); ++it)
275 (*boost::fusion::at_c<0>(pred.data))[ gridManager.
grid().leafIndexSet().index(*it) ] =
276 (*boost::fusion::at_c<0>(x.
data))[ gv.indexSet().index(*it) ] ;
299 typename VariableSet::VariableSet intervals(varSet) ;
300 for(
int l = maxLevel ; l >= coarseLevel ; l-- )
302 itEnd = gridManager.
grid().levelGridView( l ).template end<dim>();
307 unsigned ID = gridManager.
grid().globalIdSet().id(*it);
308 unsigned char vertexLevel = levelInfo[ID] ;
309 if( vertexLevel != l ) continue ;
311 (*boost::fusion::at_c<0>(intervals.data))[indexSet.index(*it)] = allIndices[l-coarseLevel][vertexCount] ;
321 *previousIndices *= 0 ; *previousIndices += intervals ;
327 out.open( prevFilename.c_str(), std::ios::binary | std::ios::app ) ;
329 double byteswritten = 0 ;
332 typename VariableSet::VariableSet difference(varSet) ;
334 difference += intervals ; difference -= *previousIndices ;
337 *previousIndices *= 0 ; *previousIndices += intervals ; prevFilename = fn ;
340 std::vector<long int> intervalIndicesTmp( gridManager.
grid().size(
dim) ) ;
341 difference.write( intervalIndicesTmp.begin() ) ;
343 long int minIndex = *std::min_element( intervalIndicesTmp.begin(), intervalIndicesTmp.end() ) ;
344 std::vector<ULong> intervalIndices( gridManager.
grid().size(
dim) ) ;
345 for(
int i = 0 ; i < intervalIndicesTmp.size() ; i++ ) intervalIndices[i] = intervalIndicesTmp[i] - minIndex ;
346 out.write(
reinterpret_cast<char*
>( &minIndex ),
sizeof(
long int) ) ;
347 byteswritten +=
sizeof(
long int) ;
349 long int maxIndex = *std::max_element( intervalIndices.begin(), intervalIndices.end() ) + 1 ;
351 std::vector<ULong> frequencies( maxIndex, 0 ) ;
352 for(
int i = 0 ; i < intervalIndices.size() ; i++ ) frequencies[ intervalIndices[i] ]++ ;
354 unsigned int nnz = (
unsigned int) std::count_if( frequencies.begin(), frequencies.end(), greaterZero<ULong> ) ;
355 std::vector<int> dictionary( frequencies.size(), -1 ) ;
357 for(
int i = 0 ; i < frequencies.size() ; i++ )
359 if( frequencies[i] > 0 )
361 dictionary[i] = cur_no ; cur_no++ ;
364 out.write(
reinterpret_cast<char*
>( &nnz ),
sizeof(
unsigned int) ) ;
365 byteswritten +=
sizeof(
unsigned int) ;
367 for(
int i = 0 ; i < dictionary.size() ; i++ )
369 if( dictionary[i] >= 0 ) { byteswritten +=
sizeof(int) ; out.write(
reinterpret_cast<char*
>( &i ),
sizeof(int) ) ; }
371 frequencies.erase( std::remove( frequencies.begin(), frequencies.end(), 0 ), frequencies.end() ) ;
372 for(
int i = 0 ; i < frequencies.size() ; i++ )
374 out.write(
reinterpret_cast<char*
>( &frequencies[i] ),
sizeof(
ULong) ) ;
375 byteswritten +=
sizeof(
ULong) ;
378 byteswritten += maxLevel *
sizeof(double) * 2 ;
384 for(
int i = 0 ; i < intervalIndices.size(); i++ )
386 encodeSymbol( encoder, alphabet, dictionary[intervalIndices[i]] );
412 std::ofstream out( prevFilename.c_str(), std::ios::binary | std::ios::app ) ;
414 double byteswritten = 0 ;
416 std::vector<long int> intervalIndicesTmp( gridManager.
grid().size(
dim) ) ;
417 previousIndices->write( intervalIndicesTmp.begin() ) ;
419 long int minIndex = *std::min_element( intervalIndicesTmp.begin(), intervalIndicesTmp.end() ) ;
420 std::vector<ULong> intervalIndices( gridManager.
grid().size(
dim) ) ;
421 for(
int i = 0 ; i < intervalIndicesTmp.size() ; i++ ) intervalIndices[i] = intervalIndicesTmp[i] - minIndex ;
422 out.write(
reinterpret_cast<char*
>( &minIndex ),
sizeof(
long int) ) ;
424 long int maxIndex = *std::max_element( intervalIndices.begin(), intervalIndices.end() ) + 1 ;
426 std::vector<ULong> frequencies( maxIndex, 0 ) ;
427 for(
int i = 0 ; i < intervalIndices.size() ; i++ ) frequencies[ intervalIndices[i] ]++ ;
429 unsigned int nnz = (
unsigned int) std::count_if( frequencies.begin(), frequencies.end(), greaterZero<ULong> ) ;
430 std::vector<int> dictionary( frequencies.size(), -1 ) ;
432 for(
int i = 0 ; i < frequencies.size() ; i++ )
434 if( frequencies[i] > 0 )
436 dictionary[i] = cur_no ; cur_no++ ;
439 out.write(
reinterpret_cast<char*
>( &nnz ),
sizeof(
unsigned int) ) ;
440 byteswritten +=
sizeof(
unsigned int);
442 for(
int i = 0 ; i < dictionary.size() ; i++ )
444 if( dictionary[i] >= 0 )
446 out.write(
reinterpret_cast<char*
>( &i ),
sizeof(int) ) ;
447 byteswritten +=
sizeof(int) ;
451 frequencies.erase( std::remove(frequencies.begin(), frequencies.end(), 0), frequencies.end() ) ;
452 for(
int i = 0 ; i < frequencies.size() ; i++ )
454 out.write(
reinterpret_cast<char*
>( &frequencies[i] ),
sizeof(
ULong) ) ;
455 byteswritten +=
sizeof(
ULong);
458 byteswritten += gridManager.
grid().maxLevel() * 2 *
sizeof(double) ;
464 for(
int i = 0 ; i < intervalIndices.size(); i++ )
466 encodeSymbol( encoder, alphabet, dictionary[intervalIndices[i]] );
501 Space space( gridManager, gv, order ) ;
503 std::string varNames[1] = {
"pred" };
509 int maxLevel = gridManager.
grid().maxLevel() ;
510 IndexSet const& indexSet = varSet.indexSet ;
512 std::vector<double> values ;
514 std::vector<double> lb(maxLevel-coarseLevel+1), ub(maxLevel-coarseLevel+1) ;
516 std::ifstream in( fn.c_str(), std::ios::binary ) ;
517 for(
int i = 0 ; i <= maxLevel-coarseLevel ; i++ )
519 in.read(
reinterpret_cast<char*
>( &lb[i] ),
sizeof(
double) ) ;
520 in.read(
reinterpret_cast<char*
>( &ub[i] ),
sizeof(
double) ) ;
524 typename VariableSet::VariableSet corr(varSet) ;
525 typename VariableSet::VariableSet difference(varSet) ;
527 std::vector<long int> intervalIndices( gridManager.
grid().size(
dim) ) ;
530 in.read(
reinterpret_cast<char*
>( &minIndex ),
sizeof(
long int) ) ;
533 in.read(
reinterpret_cast<char*
>( &nnz ),
sizeof(
unsigned int) ) ;
534 std::vector<int> dictionary( nnz ) ;
535 for(
int i = 0 ; i < nnz ; i++ )
537 in.read(
reinterpret_cast<char*
>( &dictionary[i] ),
sizeof(
int) ) ;
539 std::vector<ULong> frequencies( nnz, 0 ) ;
540 for(
int i = 0 ; i < nnz ; i++ )
541 in.read(
reinterpret_cast<char*
>( &frequencies[i] ),
sizeof(
ULong) ) ;
548 for(
int i = 0 ; i < intervalIndices.size() ; i++ )
550 ULong s = decodeSymbol(decoder,alphabet) ;
551 intervalIndices[i] = dictionary[s] + minIndex ;
554 catch( std::ios_base::failure& e ) { std::cout << e.what() <<
" Decoding error\n" ; }
579 difference.read( intervalIndices.begin() ) ;
585 *previousIndices *= 0 ;
586 *previousIndices += difference ;
597 corr += *previousIndices ; corr -= difference ;
599 *previousIndices *= 0 ; *previousIndices += corr ;
604 std::vector<std::vector<ULong> > allIndices( maxLevel+1-coarseLevel ) ;
605 for(
int l = coarseLevel ; l <= maxLevel ; l++ )
611 unsigned int ID = gridManager.
grid().globalIdSet().id(*it);
612 unsigned char vertexLevel = levelInfo[ID];
613 if( vertexLevel == l )
614 allIndices[l-coarseLevel].push_back( (*boost::fusion::at_c<0>(corr.data))[indexSet.index(*it)] ) ;
624 reconstruct( values, allIndices[0], coarseLevel, lb[0], ub[0] );
628 values.clear() ; values.resize( allIndices[0].size() ) ;
632 values[vertexCount] = reconstruct( allIndices[0][vertexCount], lb[0], ub[0], it->geometry().corner(0) );
641 (*boost::fusion::at_c<0>(x.
data))[gv.indexSet().index(*it)] = -values[vertexCount] ;
646 for(
int l = coarseLevel ; l < maxLevel ; l++ )
648 itEnd = gridManager.
grid().levelGridView( l+1 ).template end<dim>();
650 gv = gridManager.
grid().levelView(l+1) ;
651 space.setGridView(gv);
653 *boost::fusion::at_c<0>(x.
data) = *(mlTransfer->apply(l, *boost::fusion::at_c<0>(x.
data))) ;
657 reconstruct( values, allIndices[l-coarseLevel+1], l+1, lb[l+1-coarseLevel], ub[l+1-coarseLevel] );
662 values.clear() ; values.resize( allIndices[l-coarseLevel+1].size() ) ;
666 values[vertexCount] = reconstruct( allIndices[l-coarseLevel+1][vertexCount], lb[l-coarseLevel+1],
667 ub[l-coarseLevel+1], it->geometry().corner(0));
677 if( levelInfo[gridManager.
grid().globalIdSet().id(*it)] == l+1 )
679 (*boost::fusion::at_c<0>(x.
data))[gv.indexSet().index(*it)] -= values[vertexCount] ;
685 itEnd = gridManager.
grid().levelGridView(maxLevel).template end<dim>();
689 (*boost::fusion::at_c<0>(sol.data))[ gridManager.
grid().leafIndexSet().index(*it) ] =
690 (*boost::fusion::at_c<0>(x.
data))[ gv.indexSet().index(*it) ] ;
693 std::ostringstream debugfn ;
704 void quantize( std::vector<double>
const& values, std::vector<ULong>& indices,
int level,
double lb,
double ub )
706 double range = ub - lb ;
710 if( nIntervals > maxIntervals ) maxIntervals = nIntervals ;
720 indices.resize( values.size(), 0 ) ;
724 for(
int i = 0 ; i < values.size() ; i++ )
726 idx = (
ULong)( (values[i] - lb) * nIntervals / range ) + 1 ;
735 double range = ub - lb ;
737 if( range == 0 )
return 0 ;
740 return (
ULong)( (value - lb) * nIntervals / range ) + 1 ;
745 void reconstruct( std::vector<double>& values, std::vector<ULong>
const& indices,
int level,
double lb,
double ub )
747 double range = ub - lb ;
752 if( nIntervals <= 0 ) delta = 0 ;
753 else delta = range / nIntervals ;
756 values.resize( indices.size() ) ;
757 for(
int i = 0 ; i < indices.size() ; i++ )
759 if( indices[i] == 0 ) values[i] = lb ;
760 else values[i] = lb + (2*indices[i]-1) * delta/2 ;
767 double range = ub - lb ;
770 if( nIntervals <= 0 ) delta = 0 ;
771 else delta = range / nIntervals ;
772 if( index == 0 )
return lb ;
773 else return lb + (2*index-1) * delta/2 ;
778 double ld(
double val ) {
return log(val)/log(2.0) ; }
787 std::string filePrefix ;
792 typename VariableSet::VariableSet* previousIndices ;
794 std::string prevFilename ;
795 long int maxIntervals ;
797 boost::unordered_map<unsigned long int, unsigned char> levelInfo ;
A simple alphabet of symbols with frequencies to be used with the range coder.
Grid const & grid() const
Returns a const reference on the owned grid.
A class that stores information about a set of variables.
A class for storing a heterogeneous collection of FunctionSpaceElement s.
Grid::template Codim< dim >::LevelIterator VertexLevelIterator
Grid::LevelGridView LevelView
boost::fusion::vector< Space const * > Spaces
Grid::template Codim< dim >::LeafIterator VertexLeafIterator
void decode(GridManager< Grid > &gridManagerState, typename VariableSet::VariableSet &sol, std::string fn)
boost::fusion::vector< VariableDescription< 0, 1, 0 > > VariableDescriptions
Dune::FieldVector< double, 1 > StorageValueType
VariableSet::VariableSet encode(typename VariableSet::VariableSet const &sol, std::string fn)
LossyStorage(GridManager< Grid > &gridManager_, VariableSet const &varSet_, int coarseLevel_, double aTol_, bool uniform_=false, QuantizationPolicy &quantizationPolicy_=QuantizationPolicy())
VariableSetDescription< Spaces, VariableDescriptions > PredVariableSet
QuantizationPolicy quantizationPolicy
Grid::template Codim< dim >::LeafIndexSet IndexSet
Entropy coding with range decoder.
Entropy coding with range encoder.
bool abscompare(double a, double b)
Range coder for fast entropy coding.
options for VTK/AMIRA output
Output of mesh and solution for visualization software.