23#ifndef LOSSYSTORAGE_HH
24#define LOSSYSTORAGE_HH
32#include <boost/unordered_map.hpp>
34bool abscompare(
double a,
double b ) {
return fabs( a ) < fabs( b ) ; }
40template <
class VariableSetSens,
class Gr
id,
int D=2>
50 bool uniform =
true,
unsigned int vidx=0 )
55 long int nIntervals = (
long int) ceil( range / aTol / 2.0 ) ;
56 if( nIntervals % 2 == 0 )
return nIntervals + 1 ;
62template <
class Gr
id,
class VariableSet,
class Space,
class QuantizationPolicy=UniformQuantizationPolicy<VariableSet,Gr
id> >
66 static const int dim = Grid::dimension ;
71 typedef boost::fusion::vector<Space const*>
Spaces ;
76 typedef typename Grid::template Codim<dim>::LeafIndexSet
IndexSet ;
83 QuantizationPolicy& quantizationPolicy_ = QuantizationPolicy() )
84 : gridManager(gridManager_), varSet(varSet_), coarseLevel(coarseLevel_), aTol(aTol_),
85 count(0), firstCall(true), uniform(uniform_), order(1),
quantizationPolicy(quantizationPolicy_)
93 if( mlTransfer != NULL )
delete mlTransfer ;
101 typename VariableSet::VariableSet
encode(
typename VariableSet::VariableSet
const& sol, std::string fn )
106 if( mlTransfer != NULL )
delete mlTransfer ;
110 unsigned long int ID ;
112 for(
int level = 0 ; level <= gridManager.
grid().maxLevel() ; level++ )
115 it != gridManager.
grid().levelGridView( level ).end<
dim>(); ++ it)
117 ID = gridManager.
grid().globalIdSet().id( *it ) ;
118 if( levelInfo.find(ID) != levelInfo.end() ) continue ;
119 levelInfo[ID] = level ;
123 IndexSet const& indexSet = varSet.indexSet ;
124 int maxLevel = gridManager.
grid().maxLevel() ;
127 std::ostringstream debugfn ;
128 typename VariableSet::VariableSet predictionError(varSet) ;
129 predictionError *= 0 ;
133 Space space( gridManager, gv, order ) ;
135 std::string varNames[1] = {
"pred" };
142 std::vector<std::vector<ULong> > allIndices ;
143 std::vector<ULong> indices ;
144 std::vector<double> nodalValues ;
146 it != gridManager.
grid().levelGridView( coarseLevel ).template end<dim>(); ++it )
148 nodalValues.push_back( -(*boost::fusion::at_c<0>(sol.data))[indexSet.index(*it)] ) ;
151 double ub = *std::max_element( nodalValues.begin(), nodalValues.end() ) ;
152 double lb = *std::min_element( nodalValues.begin(), nodalValues.end() ) ;
155 ub = *std::max_element( nodalValues.begin(), nodalValues.end(),
abscompare ) ;
156 if( ub < 0 ) { lb = ub ; ub = -lb ; }
160 double range = ub - lb ;
164 if( range > 0 ) maxBits = (-ld(aTol) ) ;
166 if( maxBits < 0 ) maxBits = 0 ;
167 maxIntervals = (
long int)ceil(pow( 2, maxBits ));
169 std::ofstream out( fn.c_str(), std::ios::binary ) ;
172 out.write(
reinterpret_cast<char*
>( &lb ),
sizeof(
double) ) ;
173 out.write(
reinterpret_cast<char*
>( &ub ),
sizeof(
double) ) ;
178 unsigned long vertexCount = 0 ;
181 quantize( nodalValues, indices, coarseLevel, lb, ub ) ;
186 allIndices.push_back( indices ) ;
188 reconstruct( nodalValues, indices, coarseLevel, lb, ub ) ;
194 indices.resize(nodalValues.size(), 0) ;
198 unsigned int vidx = gridManager.
grid().leafIndexSet().index(*it) ;
200 indices[vertexCount] = quantize( nodalValues[vertexCount], lb, ub, it->geometry().corner(0),vidx );
202 nodalValues[vertexCount] = reconstruct( indices[vertexCount], lb, ub, it->geometry().corner(0),vidx);
206 allIndices.push_back( indices ) ;
214 (*boost::fusion::at_c<0>(x.
data))[gv.indexSet().index(*it)] -= nodalValues[vertexCount] ;
219 typename VariableSet::VariableSet pred(varSet) ;
223 (*boost::fusion::at_c<0>(pred.data))[ indexSet.index(*it) ] = (*boost::fusion::at_c<0>(x.
data))[ gv.indexSet().index(*it) ] ;
227 for(
int l = coarseLevel ; l < maxLevel ; l++ )
229 gv = gridManager.
grid().levelView(l+1) ;
230 space.setGridView(gv);
232 *boost::fusion::at_c<0>(x.
data) = *(mlTransfer->apply(l, *boost::fusion::at_c<0>(x.
data))) ;
234 nodalValues.clear() ;
235 itEnd = gridManager.
grid().levelGridView( l+1 ).template end<dim>();
239 double val = (*boost::fusion::at_c<0>(x.
data))[gv.indexSet().index(*it)]
240 -(*boost::fusion::at_c<0>(sol.data))[indexSet.index(*it)] ;
242 nodalValues.push_back(val);
245 ub = *std::max_element( nodalValues.begin(), nodalValues.end() ) ;
246 lb = *std::min_element( nodalValues.begin(), nodalValues.end() ) ;
249 ub = *std::max_element( nodalValues.begin(), nodalValues.end(),
abscompare ) ;
250 if( ub < 0 ) { lb = ub ; ub = -lb ; }
254 out.write(
reinterpret_cast<char*
>( &lb ),
sizeof(
double) ) ;
255 out.write(
reinterpret_cast<char*
>( &ub ),
sizeof(
double) ) ;
259 quantize( nodalValues, indices, l+1, lb, ub) ;
260 allIndices.push_back( indices ) ;
261 reconstruct( nodalValues, indices, l+1, lb, ub ) ;
266 indices.clear() ; indices.resize(nodalValues.size(), 0);
271 unsigned int vidx = gridManager.
grid().leafIndexSet().index(*it) ;
273 indices[vertexCount] = quantize( nodalValues[vertexCount], lb, ub, it->geometry().corner(0), vidx );
274 nodalValues[vertexCount] = reconstruct( indices[vertexCount], lb, ub, it->geometry().corner(0), vidx );
277 allIndices.push_back( indices ) ;
282 unsigned long skipped = 0 ;
287 unsigned long ID = gridManager.
grid().globalIdSet().id( *it ) ;
288 unsigned char vertexLevel = levelInfo[ID] ;
289 if( vertexLevel < l+1 ) { vertexCount++ ; skipped++ ; continue ; }
291 (*boost::fusion::at_c<0>(x.
data))[gv.indexSet().index(*it)] -= nodalValues[vertexCount] ;
300 (*boost::fusion::at_c<0>(pred.data))[ indexSet.index(*it) ] = (*boost::fusion::at_c<0>(x.
data))[ gv.indexSet().index(*it) ] ;
328 typename VariableSet::VariableSet intervals(varSet) ; intervals *= 0 ;
329 for(
int l = maxLevel ; l >= coarseLevel ; l-- )
332 itEnd = gridManager.
grid().levelGridView( l ).template end<dim>();
336 (*boost::fusion::at_c<0>(intervals.data))[indexSet.index(*it)] = allIndices[l-coarseLevel][vertexCount] ;
344 std::vector<long int> intervalIndicesTmp( gridManager.
grid().size(
dim) ) ;
345 intervals.write( intervalIndicesTmp.begin() ) ;
349 long int minIndex = *std::min_element( intervalIndicesTmp.begin(), intervalIndicesTmp.end() ) ;
350 std::vector<ULong> intervalIndices( gridManager.
grid().size(
dim) ) ;
352 for(
int i = 0 ; i < intervalIndicesTmp.size() ; i++ )
353 intervalIndices[i] = intervalIndicesTmp[i] - minIndex ;
355 out.write(
reinterpret_cast<char*
>( &minIndex ),
sizeof(
long int) ) ;
357 long int maxIndex = *std::max_element( intervalIndices.begin(), intervalIndices.end() ) + 1 ;
359 std::vector<ULong> frequencies( maxIndex, 0 ) ;
360 for(
int i = 0 ; i < intervalIndices.size() ; i++ ) frequencies[ intervalIndices[i] ]++ ;
363 unsigned int nnz = (
unsigned int) std::count_if( frequencies.begin(), frequencies.end(), greaterZero<ULong> ) ;
365 std::vector<int> dictionary( frequencies.size(), -1 ) ;
367 for(
int i = 0 ; i < frequencies.size() ; i++ )
369 if( frequencies[i] > 0 )
371 dictionary[i] = cur_no ; cur_no++ ;
374 out.write(
reinterpret_cast<char*
>( &nnz ),
sizeof(
unsigned int) ) ;
375 for(
int i = 0 ; i < dictionary.size() ; i++ )
377 if( dictionary[i] >= 0 ) out.write(
reinterpret_cast<char*
>( &i ),
sizeof(
int) ) ;
380 frequencies.erase( std::remove(frequencies.begin(), frequencies.end(), 0), frequencies.end() ) ;
381 for(
int i = 0 ; i < frequencies.size() ; i++ )
382 out.write(
reinterpret_cast<char*
>( &frequencies[i] ),
sizeof(
ULong) ) ;
387 for(
int i = 0 ; i < intervalIndices.size(); i++ )
389 encodeSymbol( encoder, alphabet, dictionary[intervalIndices[i]] );
427 if( mlTransfer != NULL )
delete mlTransfer ;
431 unsigned long int ID ;
433 for(
int level = 0 ; level <= gridManagerState.
grid().maxLevel() ; level++ )
436 it != gridManagerState.
grid().levelGridView( level ).template end<dim>(); ++ it)
438 ID = gridManagerState.
grid().globalIdSet().id( *it ) ;
439 if( levelInfo.find(ID) != levelInfo.end() ) continue ;
440 levelInfo[ID] = level ;
445 LevelView gv = gridManagerState.
grid().levelView( coarseLevel ) ;
446 Space space( gridManagerState, gv, order ) ;
448 std::string varNames[1] = {
"pred" };
454 int maxLevel = gridManagerState.
grid().maxLevel() ;
455 IndexSet const& indexSet = gridManagerState.
grid().leafIndexSet();
457 std::vector<double> values ;
459 std::vector<double> lb(maxLevel-coarseLevel+1), ub(maxLevel-coarseLevel+1) ;
462 std::ifstream in( fn.c_str(), std::ios::binary ) ;
463 for(
int i = 0 ; i <= maxLevel-coarseLevel ; i++ )
465 in.read(
reinterpret_cast<char*
>( &lb[i] ),
sizeof(
double) ) ;
466 in.read(
reinterpret_cast<char*
>( &ub[i] ),
sizeof(
double) ) ;
470 std::vector<long int> intervalIndices( gridManagerState.
grid().size(
dim) ) ;
473 in.read(
reinterpret_cast<char*
>( &minIndex ),
sizeof(
long int) ) ;
477 in.read(
reinterpret_cast<char*
>( &nnz ),
sizeof(
unsigned int) ) ;
480 std::vector<int> dictionary( nnz ) ;
481 for(
int i = 0 ; i < nnz ; i++ )
483 in.read(
reinterpret_cast<char*
>( &dictionary[i] ),
sizeof(
int) ) ;
485 std::vector<ULong> frequencies( nnz, 0 ) ;
486 for(
int i = 0 ; i < nnz ; i++ )
487 in.read(
reinterpret_cast<char*
>( &frequencies[i] ),
sizeof(
ULong) ) ;
493 for(
int i = 0 ; i < intervalIndices.size() ; i++ )
495 ULong s = decodeSymbol(decoder,alphabet) ;
496 intervalIndices[i] = dictionary[s] + minIndex ;
499 catch( std::ios_base::failure& e ) { std::cout << e.what() <<
" Decoding error\n" ; }
525 typename VariableSet::VariableSet corr(sol) ; corr *= 0 ;
526 corr.read( intervalIndices.begin() ) ;
529 std::vector<std::vector<ULong> > allIndices( maxLevel+1-coarseLevel ) ;
530 for(
int l = coarseLevel ; l <= maxLevel ; l++ )
533 it != gridManagerState.
grid().levelGridView( l ).template end<dim>(); ++it)
535 allIndices[l-coarseLevel].push_back( (*boost::fusion::at_c<0>(corr.data))[indexSet.index(*it)] ) ;
545 reconstruct( values, allIndices[0], coarseLevel, lb[0], ub[0] );
549 values.clear() ; values.resize( allIndices[0].size() ) ;
553 unsigned int vidx = gridManagerState.
grid().leafIndexSet().index(*it) ;
555 values[vertexCount] = reconstruct( allIndices[0][vertexCount], lb[0], ub[0], it->geometry().corner(0),vidx );
564 (*boost::fusion::at_c<0>(x.
data))[gv.indexSet().index(*it)] = -values[vertexCount] ;
572 (*boost::fusion::at_c<0>(sol.data))[ indexSet.index(*it) ] = (*boost::fusion::at_c<0>(x.
data))[ gv.indexSet().index(*it) ] ;
577 for(
int l = coarseLevel ; l < maxLevel ; l++ )
579 itEnd = gridManagerState.
grid().levelGridView( l+1 ).template end<dim>();
581 gv = gridManagerState.
grid().levelView(l+1) ;
582 space.setGridView(gv);
584 *boost::fusion::at_c<0>(x.
data) = *(mlTransfer->apply(l, *boost::fusion::at_c<0>(x.
data))) ;
588 reconstruct( values, allIndices[l-coarseLevel+1], l+1, lb[l+1-coarseLevel], ub[l+1-coarseLevel] );
594 values.resize( allIndices[l-coarseLevel+1].size() ) ;
599 unsigned int vidx = gridManagerState.
grid().leafIndexSet().index(*it) ;
601 values[vertexCount] = reconstruct( allIndices[l-coarseLevel+1][vertexCount], lb[l-coarseLevel+1],
602 ub[l-coarseLevel+1], it->geometry().corner(0), vidx );
612 if( levelInfo[gridManagerState.
grid().globalIdSet().id(*it)] == l+1 )
614 (*boost::fusion::at_c<0>(x.
data))[gv.indexSet().index(*it)] -= values[vertexCount] ;
623 (*boost::fusion::at_c<0>(sol.data))[ indexSet.index(*it) ] = (*boost::fusion::at_c<0>(x.
data))[ gv.indexSet().index(*it) ] ;
644 void quantize( std::vector<double>
const& values, std::vector<ULong>& indices,
int level,
double lb,
double ub )
646 double range = ub - lb ;
651 if( nIntervals > maxIntervals ) maxIntervals = nIntervals ;
662 indices.resize( values.size(), 0 ) ;
666 for(
int i = 0 ; i < values.size() ; i++ )
668 idx = (
ULong)( (values[i] - lb) * nIntervals / range ) + 1 ;
676 bool uniform =
false,
unsigned int vidx = 0 )
678 double range = ub - lb ;
680 if( range == 0 )
return 0 ;
682 long int nIntervals =
quantizationPolicy.getIntervals( range, aTol, coor, uniform, vidx ) ;
685 if( nIntervals > maxIntervals ) maxIntervals = nIntervals ;
687 return (
ULong)( (value - lb) * nIntervals / range ) + 1 ;
692 void reconstruct( std::vector<double>& values, std::vector<ULong>
const& indices,
int level,
double lb,
double ub )
694 double range = ub - lb ;
699 if( nIntervals <= 0 ) delta = 0 ;
700 else delta = range / nIntervals ;
703 values.resize( indices.size() ) ;
704 for(
int i = 0 ; i < indices.size() ; i++ )
706 if( indices[i] == 0 ) values[i] = lb ;
707 else values[i] = lb + (2*indices[i]-1) * delta/2 ;
713 bool uniform =
false,
unsigned int vidx = 0 )
715 double range = ub - lb ;
716 long int nIntervals =
quantizationPolicy.getIntervals( range, aTol, coor, uniform, vidx ) ;
718 if( nIntervals <= 0 ) delta = 0 ;
719 else delta = range / nIntervals ;
720 if( index == 0 )
return lb ;
721 else return lb + (2*index-1) * delta/2 ;
726 double ld(
double val ) {
return log(val)/log(2.0) ; }
728 void setTolerance(
double tol ) { aTol = tol ; }
738 std::string filePrefix ;
744 long int maxIntervals ;
747 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.