KASKADE 7 development version
lossystorageDUNE.hh
Go to the documentation of this file.
1#ifndef LOSSYSTORAGEDUNE_HH
2#define LOSSYSTORAGEDUNE_HH
3
4#include <map>
5#include <cassert>
6
7#include "dune/grid/common/grid.hh"
8#include "dune/grid/common/entity.hh"
9#include "dune/grid/io/file/dgfparser/dgfparser.hh"
10#include "dune/istl/matrix.hh"
11#include "dune/istl/bcrsmatrix.hh"
12#include "dune/common/fmatrix.hh"
13#include "dune/common/iteratorfacades.hh"
14#include "dune/istl/matrixindexset.hh"
15
16#include "rangecoder.hh"
17
18#include "lossy_helper.hh"
19
20// #define USEBOUNDS
21#define USEFREQ
22// #define LEVELWISE
23
24template <class Grid, class CoeffVector>
25class LossyStorage
26{
27public:
28 static const int dim = Grid::dimension ;
29 // degree of interpolation polynomials; currently only linear interpolation is supported
30 static const int order = 1 ;
31
32 // some typedefs used throughout the class
33 typedef typename Grid::template Codim<dim>::LevelIterator VertexLevelIterator ;
34 typedef typename Grid::template Codim<dim>::LeafIterator VertexLeafIterator ;
35 typedef typename Grid::LeafIndexSet IndexSet;
36 typedef typename Grid::LevelGridView::IndexSet::IndexType IndexType;
37 typedef typename Grid::LeafGridView::IndexSet::IndexType LeafIndexType;
38
39 typedef typename Grid::Traits::GlobalIdSet::IdType IdType;
40
41 typedef unsigned long int ULong;
42
43 LossyStorage( int coarseLevel_, double aTol_) : ps(NULL), coarseLevel(coarseLevel_), aTol(aTol_),
44 accumulatedEntropy(0), accumulatedOverhead(0),
45 accumulatedUncompressed(0), accumulatedCompressed(0)
46 {
47/*#ifdef USEFREQ
48 std::cout << "USES PRECOMPUTED FREQUENCIES FOR ENCODING A SINGLE FUNCTION!\nBEWARE OF THE OVERHEAD!\n";
49 std::cout << "Due to implementation, not using pre-computed frequencies fails, as the vectors used for\n"
50 << "Alphabet are too large.\n";
51#else
52 std::cout << "Uses dictionary for encoding. Beware of the overhead!\n";
53 std::cout << "Due to implementation, not using the dictionary fails, as the vectors used for\n"
54 << "Alphabet would be too large for fine quantization.\n";
55#endif*/
56 }
57
58 ~LossyStorage() { if( ps != NULL ) delete ps; }
59
60 // returns the entropy (summed since the last call to resetEntropy/resetSizes)
61 // of the data (= average symbol size in byte needed to store the file)
63 {
64 return accumulatedEntropy;
65 }
66
67
69 {
70 accumulatedEntropy = 0;
71 }
72
73
74 // reports the overhead (summed since last call to resetOverhead/resetSizes)
75 // i.e. interval bounds, frequencies, etc.
77 {
78 return accumulatedOverhead;
79 }
80
82 {
83 accumulatedOverhead = 0;
84 }
85
86 // returns the compressed size
87 // which is (in the best case) the size of the encoded, compressed file
88 // without the overhead from storing intervals etc.
90 {
91 return accumulatedCompressed;
92 }
93
95 {
96 accumulatedCompressed = 0 ;
97 }
98
99 // returns the compressed size + overhead, which is (in the best case/in the limit)
100 // the size of the compressed file (including all side information)
102 {
103 return accumulatedCompressed + accumulatedOverhead;
104 }
105
106 // reset everything
108 {
109 accumulatedEntropy = 0;
110 accumulatedOverhead = 0;
111 accumulatedCompressed = 0;
112 accumulatedUncompressed = 0;
113 }
114
115
116 // returns the size needed for uncompressed storage of the data
118 {
119 return accumulatedUncompressed;
120 }
121
123 {
124 accumulatedUncompressed = 0 ;
125 }
126
127
128 // returns the compression factor (=uncompressed size/compressed size)
129 double reportRatio()
130 {
131 if( accumulatedCompressed + accumulatedOverhead > 0 )
132 return accumulatedUncompressed / (accumulatedCompressed + accumulatedOverhead );
133
134 return -1;
135 }
136
137
138 // TODO: has to be faster for adaptive meshes!
139 void setup( Grid const& grid )
140 {
141 if( ps != NULL ) delete ps;
143
144// auto foo = Lossy_Detail::ProlongationStack<Grid>(grid); // for debugging, should use ps = new Prolongation<Grid> instead!
145
146 typename Grid::GlobalIdSet const& idSet = grid.globalIdSet();
147
148 levelInfo.clear();
149 for( int level = grid.maxLevel(); level >= 0; --level )
150 {
151 VertexLevelIterator lEnd = grid.levelGridView( level ).template end<dim>();
152 for( VertexLevelIterator it = grid.levelGridView( level ).template begin<dim>(); it != lEnd; ++it )
153 {
154 levelInfo[idSet.id( *it )] = level ;
155 }
156 }
157 }
158
159
160
165 void encode( Grid const& grid, CoeffVector const& sol, std::string fn, double aTol_ = 0, int maxLevel_ = -1 )
166 {
167 std::ofstream out( fn.c_str(), std::ios::binary ) ;
168 encode( grid, sol, out, aTol_, maxLevel_);
169 out.close();
170 }
171
172
173 void encode( Grid const& grid, CoeffVector const& sol, std::ostream& out, double aTol_ = 0, int maxLevel_ = -1 )
174 {
175 double aTolSave = aTol ;
176 if( aTol_ > 0 ) aTol = aTol_ ;
177
178 // use maxLevel_ instead of maxLevel member
179 int maxLevel = maxLevel_;
180 if( maxLevel < 0 ) maxLevel = grid.maxLevel() ;
181
182 double overhead = 0, entropy = 0, compressed = 0 ;
183 size_t nNodes = grid.size(dim);
184
185 typename Grid::GlobalIdSet const& idSet = grid.globalIdSet();
186 typename Grid::LeafGridView::IndexSet const& leafIndexSet = grid.leafIndexSet();
187
188 std::vector<long int> indices ;
189 std::vector<double> predictionError ;
190
191 std::vector<std::vector<long int> > levelIndices;
192
193 VertexLevelIterator itEnd = grid.levelGridView(coarseLevel).template end<dim>();
194 for( VertexLevelIterator it = grid.levelGridView( coarseLevel ).template begin<dim>() ; it != itEnd; ++it )
195 {
196 predictionError.push_back( -sol[leafIndexSet.index(*it)] ) ;
197 }
198
199 quantize( predictionError, indices) ;
200 reconstruct( predictionError, indices ) ;
201
202 levelIndices.push_back(indices);
203
204 CoeffVector reconstruction(grid.size(coarseLevel, dim) ) ;
205
206 // assign reconstructed coarse grid values
207 size_t nEntries = sol.size();
208 std::vector<long int> intervalIndicesTmp( nEntries );
209 long int minIndex = 0;
210
211 size_t vertexCount = 0 ;
212 for( VertexLevelIterator it = grid.levelGridView(coarseLevel).template begin<dim>(); it != itEnd; ++it)
213 {
214 reconstruction[vertexCount] = -predictionError[vertexCount] ;
215
216 long int tmpIndex = indices[vertexCount];
217 intervalIndicesTmp[leafIndexSet.index(*it)] = tmpIndex;
218 if( tmpIndex < minIndex ) minIndex = tmpIndex;
219
220 vertexCount++ ;
221 }
222
223 CoeffVector prediction;
224
225 for( int l = coarseLevel ; l < maxLevel ; l++ )
226 {
227 ps->mv(l, reconstruction, prediction) ;
228
229 std::vector<std::vector<size_t> > vertexInfo( prediction.size(), std::vector<size_t>(3) );
230
231 predictionError.clear();
232 predictionError.reserve( prediction.size() ); // avoid reallocations
233
234 vertexCount = 0 ;
235 typename Grid::LevelGridView::IndexSet const& levelIndexSet = grid.levelGridView(l+1).indexSet();
236
237 itEnd = grid.levelGridView(l+1).template end<dim>();
238 for( VertexLevelIterator it = grid.levelGridView(l+1).template begin<dim>(); it != itEnd; ++it)
239 {
240 unsigned char vertexLevel = levelInfo[idSet.id( *it )] ;
241 if( vertexLevel == l+1 )
242 {
243 predictionError.push_back(prediction[levelIndexSet.index(*it)] - sol[leafIndexSet.index(*it)] );
244 }
245 vertexInfo[vertexCount][0] = levelIndexSet.index(*it) ;
246 vertexInfo[vertexCount][1] = leafIndexSet.index(*it) ;
247 vertexInfo[vertexCount][2] = vertexLevel ;
248
249 vertexCount++;
250 }
251
252 quantize( predictionError, indices) ;
253 reconstruct( predictionError, indices) ;
254
255 levelIndices.push_back(indices);
256
257 if( (l+1) < maxLevel )
258 {
259 // prepare prediction on next level -- use reconstructed values
260 reconstruction.resize( prediction.size() );
261 vertexCount = 0 ;
262
263 for( size_t ii = 0 ; ii < vertexInfo.size(); ii++ )
264 {
265 // correction only for the nodes on level l+1
266 unsigned char vertexLevel = vertexInfo[ii][2];
267 IndexType levelIndex = vertexInfo[ii][0];
268 if( vertexLevel < l+1 )
269 {
270 reconstruction[levelIndex] = prediction[levelIndex];
271 }
272 else
273 {
274 long int tmpIndex = indices[vertexCount];
275 intervalIndicesTmp[vertexInfo[ii][1] ] = tmpIndex;
276 if( tmpIndex < minIndex ) minIndex = tmpIndex;
277 reconstruction[levelIndex] = prediction[levelIndex]-predictionError[vertexCount] ;
278
279 vertexCount++;
280 }
281 }
282 }
283 else
284 {
285 vertexCount = 0 ;
286 for( size_t ii = 0 ; ii < vertexInfo.size(); ii++ )
287 {
288 unsigned char vertexLevel = vertexInfo[ii][2];//levelInfo[idSet.id( *it )] ;
289 if( vertexLevel < l+1 ) continue;
290
291 long int tmpIndex = indices[vertexCount];
292 intervalIndicesTmp[vertexInfo[ii][1] ] = tmpIndex;
293 if( tmpIndex < minIndex ) minIndex = tmpIndex;
294 vertexCount++ ;
295 }
296 }
297 }
298
299 std::vector<ULong> intervalIndices( nEntries ) ;
300 for( size_t i = 0; i < nEntries; i++ ) intervalIndices[i] = intervalIndicesTmp[i] - minIndex ;
301
302 out.write(reinterpret_cast<char*>( &minIndex ), sizeof(long int) ) ;
303 overhead += sizeof(long int);
304
305 std::map<unsigned long, unsigned long> freqMap;
306 unsigned int nnz = 0;
307 for( size_t i = 0 ; i < nEntries ; i++ )
308 {
309 if( freqMap.find(intervalIndices[i] ) != freqMap.end() ) // already there, increment
310 {
311 freqMap[intervalIndices[i]]++ ;
312 }
313 else // new nonzero, add to map
314 {
315 nnz++;
316 freqMap[intervalIndices[i]] = 1;
317 }
318 }
319
320 out.write(reinterpret_cast<char*>( &nnz ), sizeof(unsigned int) ) ;
321 overhead += sizeof(unsigned int);
322
323
324 std::vector<unsigned long> frequenciesForRangeCoder(nnz);
325
326 std::map<unsigned long, unsigned long> dictMap;
327 unsigned long curNo = 0 ;
328
329 std::map<unsigned long,unsigned long>::iterator mapIt;
330 std::map<unsigned long,unsigned long>::iterator mapEnd = freqMap.end();
331 for( mapIt = freqMap.begin(); mapIt != mapEnd; ++mapIt )
332 {
333 unsigned long lv = mapIt->first;
334 frequenciesForRangeCoder[curNo] = mapIt->second;
335 dictMap.insert( dictMap.begin(), std::pair<unsigned long, unsigned long>(lv, curNo) ) ;
336 out.write(reinterpret_cast<char*>( &lv ), sizeof(unsigned long) ) ;
337 overhead += sizeof(unsigned long);
338 curNo++;
339 }
340
341
342 for( unsigned int i = 0 ; i < nnz ; i++ )
343 {
344#ifdef USEFREQ
345 out.write(reinterpret_cast<char*>( &frequenciesForRangeCoder[i] ), sizeof(unsigned long) ) ;
346 overhead += sizeof(unsigned long);
347#endif
348
349 double tmp = -ld(frequenciesForRangeCoder[i]/((double)nNodes)) *
350 frequenciesForRangeCoder[i]/((double)nNodes);
351 entropy += tmp;
352 compressed += tmp;
353 }
354 accumulatedCompressed += compressed/8*nNodes;
355 compressed = 0;
356
357#ifndef USEFREQ
358 frequenciesForRangeCoder.clear();
359 freqMap.clear();
360#endif
361
362 std::cout.flush();
363#ifdef USEFREQ
364 Alphabet<unsigned long> alphabet( frequenciesForRangeCoder.begin(), frequenciesForRangeCoder.end() ) ;
365 RangeEncoder<unsigned long> encoder( out ) ;
366
367 for( size_t i = 0 ; i < nEntries; i++ )
368 {
369 encodeSymbol( encoder, alphabet, dictMap.find(intervalIndices[i])->second/* dictMap[intervalIndices[i]]*/ );
370 }
371
372#else
373
374
375 size_t symbolCounter = 0 ;
376 std::vector<unsigned long> count(nnz, 1) ;
377 Alphabet<unsigned long> alphabet( count.begin(), count.end() ) ;
378
379 RangeEncoder<unsigned long> encoder(out) ;
380
381 for( size_t i = 0 ; i < nEntries; i++ )
382 {
383 encodeSymbol( encoder, alphabet, dictMap.find(intervalIndices[i])->second);
384 ++count[dictMap[intervalIndices[i]]];
385 ++symbolCounter ;
386 if (symbolCounter>0.1*nEntries)
387 {
388 alphabet.update(count.begin(),count.end());
389 symbolCounter=0;
390 }
391 }
392#endif
393
394 accumulatedEntropy += entropy/8 ;
395 accumulatedOverhead += overhead;
396 accumulatedUncompressed += 8*nNodes;
397
398 aTol = aTolSave;
399 }
400
405 void decode( Grid const& gridState, CoeffVector& sol, std::string fn, double aTol_ = 0, int maxLevel_ = -1 )
406 {
407 std::ifstream in( fn.c_str(), std::ios::binary ) ;
408 decode(gridState, sol, in, aTol_, maxLevel_);
409 in.close() ;
410 }
411
412
413 void decode( Grid const& gridState, CoeffVector& sol, std::istream& in, double aTol_ = 0, int maxLevel_ = -1 )
414 {
415 double aTolSave = aTol ;
416 if( aTol_ > 0 ) aTol = aTol_ ;
417
418 int maxLevel = maxLevel_;
419 if( maxLevel < 0 ) maxLevel = gridState.maxLevel();
420
421 // prepare prediction
422 typename Grid::GlobalIdSet const& idSet = gridState.globalIdSet();
423 IndexSet const& indexSet = gridState.leafIndexSet();
424
425 std::vector<double> values ;
426 std::vector<long int> intervalIndices( gridState.size(dim) );
427 size_t nEntries = intervalIndices.size();
428
429 VertexLevelIterator itEnd = gridState.levelGridView(coarseLevel).template end<dim>();
430
431 // read in indices from file
432 long int minIndex ;
433 in.read(reinterpret_cast<char*>( &minIndex ), sizeof(long int) ) ;
434
435 unsigned int nnz ;
436 in.read(reinterpret_cast<char*>( &nnz ), sizeof(unsigned int) ) ; // # non-empty intervals
437 std::vector<long int> dictionary( nnz ) ;
438 for( int i = 0 ; i < nnz ; i++ )
439 {
440 in.read(reinterpret_cast<char*>( &dictionary[i] ), sizeof(unsigned long) ) ; // existing intervals (dictionary)
441 }
442#ifdef USEFREQ
443 std::vector<unsigned long> frequencies( nnz, 0 ) ;
444 for( int i = 0 ; i < nnz ; i++ )
445 {
446 in.read(reinterpret_cast<char*>( &frequencies[i] ), sizeof(unsigned long) ) ; // frequencies
447 }
448
449 Alphabet<unsigned long> alphabet( frequencies.begin(), frequencies.end() ) ;
450 try
451 {
452 RangeDecoder<unsigned long> decoder( in ) ;
453 for( int i = 0 ; i < intervalIndices.size() ; i++ )
454 {
455 unsigned long s = decodeSymbol(decoder,alphabet) ;
456 intervalIndices[i] = dictionary[s] + minIndex ;
457 }
458 }
459 catch( std::ios_base::failure& e )
460 {
461 if (in.rdstate() & std::ifstream::eofbit)
462 {
463 std::cout << "EOF reached.\n";
464 }
465 else
466 {
467 std::cout << " Decoding error\n" << e.what() << "\n";
468 }
469 }
470#else
471 size_t symbolCounter = 0 ;
472
473 std::vector<unsigned long> symcount(nnz, 1) ;
474 Alphabet<unsigned long> alphabet( symcount.begin(), symcount.end() ) ;
475
476 try
477 {
478 RangeDecoder<unsigned long> decoder( in ) ;
479 for( size_t i = 0 ; i < nEntries ; i++ )
480 {
481 unsigned long s = decodeSymbol(decoder,alphabet) ;
482 intervalIndices[i] = dictionary[s] + minIndex ;
483
484 ++symcount[s];
485 ++symbolCounter ;
486
487 if (symbolCounter>0.1*nEntries)
488 {
489 alphabet.update(symcount.begin(),symcount.end());
490 symbolCounter=0;
491 }
492 }
493 }
494 catch( std::ios_base::failure& e )
495 {
496 if (in.rdstate() & std::ifstream::eofbit)
497 {
498 std::cout << "EOF reached.\n";
499 }
500 else
501 {
502 std::cout << " Decoding error\n" << e.what() << "\n";
503 }
504 }
505#endif
506
507// in.close() ;
508
509 // start reconstruction
510 int vertexCount = 0;
511
512 CoeffVector reconstruction( gridState.size(coarseLevel, dim) );
513 sol.resize( gridState.size(dim) );
514
515
516 for( VertexLevelIterator it = gridState.levelGridView( coarseLevel ).template begin<dim>(); it != itEnd; ++it)
517 {
518
519 double recVal = reconstruct( intervalIndices[indexSet.index(*it)]);
520 reconstruction[gridState.levelGridView(coarseLevel).indexSet().index(*it)] = -recVal ;
521
522 // store predicted values for the coarse grid in solution vector
523 sol[ indexSet.index(*it) ] = -recVal ;
524 vertexCount++ ;
525 }
526
527
528 CoeffVector prediction;
529 // perform prediction and correction
530 for( int l = coarseLevel ; l < maxLevel ; l++ )
531 {
532 ps->mv( l, reconstruction, prediction ) ;
533
534 reconstruction.resize( prediction.size() );
535
536 typename Grid::LevelGridView::IndexSet const& levelIndexSet = gridState.levelGridView(l+1).indexSet();
537
538 vertexCount = 0 ;
539
540 itEnd = gridState.levelGridView(l+1).template end<dim>();
541 for( VertexLevelIterator it = gridState.levelGridView(l+1).template begin<dim>(); it != itEnd ; ++it)
542 {
543 IndexType levelIndex = levelIndexSet.index(*it);
544 if(levelInfo[gridState.globalIdSet().id(*it)] == l+1) //correct only vertices on level l+1
545 {
546 reconstruction[levelIndex] = prediction[levelIndex] - reconstruct( intervalIndices[indexSet.index(*it)]);
547 }
548 else
549 {
550 reconstruction[levelIndex] = prediction[levelIndex];
551 }
552 sol[indexSet.index(*it)] = reconstruction[ levelIndex] ;
553 vertexCount++ ;
554 }
555 }
556 aTol = aTolSave ;
557 }
558
559
560
561private:
562 LossyStorage( LossyStorage const& );
563 LossyStorage& operator=( LossyStorage const& ) ;
564
565
567 void quantize( std::vector<double> const& values, std::vector<long int>& indices)
568 {
569 indices.clear() ;
570 indices.resize( values.size(), 0 ) ;
571
572 for( size_t i = 0 ; i < values.size() ; i++ )
573 {
574 indices[i] = static_cast<long int>( floor( values[i] / (2*aTol) + 0.5 ) );
575 }
576 }
577
578
580 void reconstruct( std::vector<double>& values, std::vector<long int> const& indices)
581 {
582 values.clear() ;
583 values.resize( indices.size() ) ;
584 for( size_t i = 0 ; i < indices.size() ; i++ )
585 {
586 values[i] = indices[i] * 2* aTol ;
587 }
588 }
589
590
591
593 double reconstruct( long int const& index )
594 {
595 return index*2*aTol;
596 }
597
599 double ld( double val ) { return log(val)/log(2.0) ; }
600
602 std::map<IdType, unsigned char> levelInfo ;
603 int coarseLevel ;
604 double aTol ;
605 double accumulatedEntropy, accumulatedOverhead, accumulatedUncompressed, accumulatedCompressed;
606} ;
607
608#endif
A simple alphabet of symbols with frequencies to be used with the range coder.
Definition: rangecoder.hh:342
void update(InIter first, InIter last)
Modifies the symbols' half-open ranges to represent the symbols' frequencies given in the range [firs...
Definition: rangecoder.hh:365
double reportEntropy()
static const int dim
Definition: lossystorage.hh:62
void setup(Grid const &grid)
Grid::template Codim< dim >::LevelIterator VertexLevelIterator
Grid::template Codim< dim >::LeafIterator VertexLeafIterator
double reportOverallSize()
unsigned long int ULong
void decode(Grid const &gridState, CoeffVector &sol, std::istream &in, double aTol_=0, int maxLevel_=-1)
void decode(Grid const &gridState, CoeffVector &sol, std::string fn, double aTol_=0, int maxLevel_=-1)
Grid::Traits::GlobalIdSet::IdType IdType
double reportUncompressedSize()
Grid::LeafGridView::IndexSet::IndexType LeafIndexType
void encode(Grid const &grid, CoeffVector const &sol, std::string fn, double aTol_=0, int maxLevel_=-1)
Grid::LevelGridView::IndexSet::IndexType IndexType
void decode(GridManager< Grid > &gridManagerState, typename VariableSet::VariableSet &sol, std::string fn)
LossyStorage(int coarseLevel_, double aTol_)
double reportOverhead()
void resetUncompressedSize()
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())
Definition: lossystorage.hh:76
Grid::LeafIndexSet IndexSet
double reportRatio()
double reportCompressedSize()
void resetCompressedSize()
void encode(Grid const &grid, CoeffVector const &sol, std::ostream &out, double aTol_=0, int maxLevel_=-1)
Grid::template Codim< dim >::LeafIndexSet IndexSet
Definition: lossystorage.hh:71
Entropy coding with range decoder.
Definition: rangecoder.hh:245
Entropy coding with range encoder.
Definition: rangecoder.hh:136
int count(Cell const &cell, int codim)
Computes the number of subentities of codimension c of a given entity.
Definition: fixdune.hh:716
Range coder for fast entropy coding.