KASKADE 7 development version
lossystorage.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2002-2011 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
22#ifndef LOSSYSTORAGE_HH
23#define LOSSYSTORAGE_HH
24
25
26#include <limits>
27
28#include "io/vtk.hh"
29#include "io/rangecoder.hh"
30#include "fem/mgtools.hh"
31
32#include <boost/unordered_map.hpp>
33
34typedef unsigned long ULong ;
35
36bool abscompare( double a, double b ) { return fabs( a ) < fabs( b ) ; }
37template<class T> bool greaterZero(T t) {return t > 0 ;}
38
39
40// Use policies for determining the quantization intervals
41template <class VariableSet, class Grid, int D=2>
43{
45
46 long int getIntervals(double range, double aTol, Coor const& coor = Coor(0), bool uniform = true )
47 {
48// return (long int) ceil( range / aTol / 2.0 ) ;
49 // symmetric mid-tread quantization : need odd number of intervals
50 long int nIntervals = (long int) ceil( range / aTol / 2.0 ) ;
51 if( nIntervals % 2 == 0 ) return nIntervals + 1 ;
52 return nIntervals ;
53 }
54} ;
55
56
57
58template <class Grid, class VariableSet, class Space, class QuantizationPolicy=UniformQuantizationPolicy<VariableSet,Grid,Grid::dimension> >
60{
61 public:
62 static const int dim = Grid::dimension ;
63
64 // some typedefs used throughout the class
66 typedef boost::fusion::vector<Space const*> Spaces ;
67 typedef boost::fusion::vector<VariableDescription<0,1,0> > VariableDescriptions;
69 typedef typename Grid::template Codim<dim>::LevelIterator VertexLevelIterator ;
70 typedef typename Grid::template Codim<dim>::LeafIterator VertexLeafIterator ;
71 typedef typename Grid::template Codim<dim>::LeafIndexSet IndexSet ;
72 typedef typename Grid::LevelGridView LevelView ;
73
74 public:
75
76 LossyStorage( GridManager<Grid>& gridManager_, VariableSet const& varSet_, int coarseLevel_, double aTol_ , bool uniform_ = false,
77 QuantizationPolicy& quantizationPolicy_ = QuantizationPolicy() )
78 : gridManager(gridManager_), varSet(varSet_), coarseLevel(coarseLevel_), aTol(aTol_),
79 count(0), firstCall(true), uniform(uniform_), order(1), quantizationPolicy(quantizationPolicy_)
80 {
81 mlTransfer = new MultilevelTransfer<Space,Grid>( gridManager, order, coarseLevel ) ;
82 ioOptions.outputType = IoOptions::ascii ;
83 previousIndices = new typename VariableSet::VariableSet(varSet) ;
84
85 // build map: vertex id - level the vertex is created
86 unsigned long int ID ;
87 for( int level = 0 ; level <= gridManager.grid().maxLevel() ; level++ )
88 {
89 for ( VertexLevelIterator it = gridManager.grid().levelGridView( level ).begin<dim>();
90 it != gridManager.grid().levelGridView( level ).end<dim>(); ++ it)
91 {
92 ID = gridManager.grid().globalIdSet().id( *it ) ;
93 if( levelInfo.find(ID) != levelInfo.end() ) continue ;
94 levelInfo[ID] = level ;
95 }
96 }
97 }
98
99
101 {
102 delete mlTransfer ;
103 delete previousIndices ;
104 }
105
111 typename VariableSet::VariableSet encode( typename VariableSet::VariableSet const& sol, std::string fn )
112 {
113 fn += ".dat" ;
114
115 std::ostringstream debugfn ;
116
117 IndexSet const& indexSet = varSet.indexSet ;
118 typename VariableSet::VariableSet predictionError(varSet) ;
119 predictionError *= 0 ;
120
121 // create variable set over coarse grid function space
122 LevelView gv = gridManager.grid().levelView( coarseLevel ) ;
123 Space space( gridManager, gv, order ) ;
124 Spaces spaces( &space ) ;
125 std::string varNames[1] = { "pred" };
126 PredVariableSet predVarSet( spaces, varNames ) ;
127 typename PredVariableSet::VariableSet x( predVarSet ) ;
128 x *= 0 ;
129
130 // calculate quantization (for coarseLevel)
131 std::vector<std::vector<ULong> > allIndices ;
132 std::vector<ULong> indices ;
133 std::vector<double> nodalValues ;
134
135 VertexLevelIterator itEnd = gridManager.grid().levelGridView( coarseLevel ).template end<dim>();
136 for ( VertexLevelIterator it = gridManager.grid().levelGridView( coarseLevel ).template begin<dim>() ;
137 it != itEnd; ++it )
138 {
139 nodalValues.push_back( -(*boost::fusion::at_c<0>(sol.data))[indexSet.index(*it)] ) ;
140 }
141
142 double ub = *std::max_element( nodalValues.begin(), nodalValues.end() ) ;
143 double lb = *std::min_element( nodalValues.begin(), nodalValues.end() ) ;
144
145 // symmetric quantization
146 ub = *std::max_element( nodalValues.begin(), nodalValues.end(), abscompare ) ;
147 if( ub < 0 ) { lb = ub ; ub = -lb ; }
148 else { lb = -ub ; }
149 // --
150
151 double range = ub - lb ;
152
153 double maxBits ;
154 if( range > 0 ) maxBits = -ld(aTol) ;
155 else maxBits = 0 ;
156 if( maxBits < 0 ) maxBits = 0 ;
157 maxIntervals = (long int)ceil(pow( 2, maxBits ));
158
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) ) ;
162
163 int vertexCount = 0 ;
164 if( uniform )
165 {
166 quantize( nodalValues, indices, coarseLevel, lb, ub ) ;
167 // collect indices on each level in a common vector, and after finishing the
168 // multilevel prediction, calculate occuring frequencies of interval numbers, and encode
169 // using range coder
170 allIndices.push_back( indices ) ;
171 reconstruct( nodalValues, indices, coarseLevel, lb, ub ) ;
172 }
173 else
174 {
175 indices.clear() ; indices.resize(nodalValues.size(), 0);
176
177 for ( VertexLevelIterator it = gridManager.grid().levelGridView( coarseLevel ).template begin<dim>() ;
178 it != gridManager.grid().levelGridView( coarseLevel ).template end<dim>(); ++it )
179 {
180 indices[vertexCount] = quantize( nodalValues[vertexCount], lb, ub, it->geometry().corner(0) );
181 nodalValues[vertexCount] = reconstruct( indices[vertexCount], lb, ub, it->geometry().corner(0) );
182 vertexCount++ ;
183 }
184 allIndices.push_back( indices ) ;
185 }
186
187
188 // assign reconstructed coarse grid values of solution to hierarchic variable
189 // to avoid error accumulation
190 vertexCount = 0 ;
191 for ( VertexLevelIterator it = gridManager.grid().levelGridView( coarseLevel ).template begin<dim>();
192 it != itEnd; ++it)
193 {
194 (*boost::fusion::at_c<0>(x.data))[gv.indexSet().index(*it)] -= nodalValues[vertexCount] ;
195 vertexCount++ ;
196 }
197
198 int maxLevel = gridManager.grid().maxLevel() ;
199
200 for( int l = coarseLevel ; l < maxLevel ; l++ )
201 {
202 itEnd = gridManager.grid().levelGridView( l+1 ).template end<dim>();
203
204 gv = gridManager.grid().levelView(l+1) ;
205 space.setGridView(gv);
206
207 *boost::fusion::at_c<0>(x.data) = *(mlTransfer->apply(l, *boost::fusion::at_c<0>(x.data))) ;
208
209 nodalValues.clear() ;
210 for ( VertexLevelIterator it = gridManager.grid().levelGridView( l+1 ).template begin<dim>();
211 it != itEnd; ++it)
212 {
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)] ;
215
216 unsigned ID = gridManager.grid().globalIdSet().id( *it ) ;
217 unsigned char vertexLevel = levelInfo[ID] ;
218 if( vertexLevel == l+1 ) nodalValues.push_back(val);
219 }
220
221 ub = *std::max_element( nodalValues.begin(), nodalValues.end() ) ;
222 lb = *std::min_element( nodalValues.begin(), nodalValues.end() ) ;
223
224 // for symmetric quantization (mid tread)
225 ub = *std::max_element( nodalValues.begin(), nodalValues.end(), abscompare ) ;
226 if( ub < 0 ) { lb = ub ; ub = -lb ; }
227 else { lb = -ub ; }
228
229 out.write(reinterpret_cast<char*>( &lb ), sizeof(double) ) ;
230 out.write(reinterpret_cast<char*>( &ub ), sizeof(double) ) ;
231
232 if( uniform )
233 {
234 quantize( nodalValues, indices, l+1, lb, ub) ;
235 allIndices.push_back( indices ) ;
236 reconstruct( nodalValues, indices, l+1, lb, ub ) ;
237 }
238 else
239 {
240 vertexCount = 0 ;
241 indices.clear() ; indices.resize(nodalValues.size(), 0);
242
243 for ( VertexLevelIterator it = gridManager.grid().levelGridView( l+1 ).template begin<dim>() ;
244 it != itEnd; ++it )
245 {
246
247 indices[vertexCount] = quantize( nodalValues[vertexCount], lb, ub, it->geometry().corner(0) );
248 nodalValues[vertexCount] = reconstruct( indices[vertexCount], lb, ub, it->geometry().corner(0) );
249 vertexCount++ ;
250 }
251 allIndices.push_back( indices ) ;
252 }
253
254 // prepare prediction on next level -- use reconstructed values
255 vertexCount = 0 ;
256 for ( VertexLevelIterator it = gridManager.grid().levelGridView( l+1 ).template begin<dim>();
257 it != itEnd; ++it)
258 {
259 // correction only for the nodes on level l+1
260 unsigned ID = gridManager.grid().globalIdSet().id( *it ) ;
261 unsigned char vertexLevel = levelInfo[ID] ;
262 if( vertexLevel < l+1 ) { continue ; }
263
264 int idx = gv.indexSet().index(*it) ;
265 (*boost::fusion::at_c<0>(x.data))[idx] -= nodalValues[vertexCount] ;
266 vertexCount++ ;
267 }
268 }
269
270 // for debugging
271 typename VariableSet::VariableSet pred(varSet) ;
272 for ( VertexLevelIterator it = gridManager.grid().levelGridView(maxLevel).template begin<dim>();
273 it != gridManager.grid().levelGridView(maxLevel).template end<dim>(); ++it)
274 {
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) ] ;
277 }
278
279 pred -= sol ;
280// std::vector<double> foo( gridManager.grid().size(dim) ) ;
281// pred.write( foo.begin() ) ;
282// double absQuantErr = fabs(*std::max_element(foo.begin(),foo.end(),abscompare)) ;
283// sol.write( foo.begin() ) ;
284// double relQuantErr = absQuantErr / fabs(*std::max_element(foo.begin(),foo.end(),abscompare)) ;
285// std::cout << "Linf quant err: abs = " << absQuantErr << "\trel = " << relQuantErr << "\n" ;
286//
287// L2Norm l2 ;
288// double l2q2 = l2.square( boost::fusion::at_c<0>(pred.vars) ) ;
289// double l2y2 = l2.square( boost::fusion::at_c<0>(sol.vars) ) ;
290// relQuantErr = sqrt(l2q2) / sqrt(l2y2) ;
291// absQuantErr = sqrt(l2q2) ;
292// std::cout << " L2 quant err: abs = " << absQuantErr << "\trel = " << relQuantErr << "\n" ;
293
294 count++ ;
295
296 // Now allIndices contains the collected interval numbers of all levels.
297 // In order to maximize efficiency of the range coder, precalculate the
298 // frequency of each interval, befor encoding.
299 typename VariableSet::VariableSet intervals(varSet) ;
300 for( int l = maxLevel ; l >= coarseLevel ; l-- )
301 {
302 itEnd = gridManager.grid().levelGridView( l ).template end<dim>();
303 vertexCount = 0 ;
304 for ( VertexLevelIterator it = gridManager.grid().levelGridView( l ).template begin<dim>();
305 it != itEnd; ++it)
306 {
307 unsigned ID = gridManager.grid().globalIdSet().id(*it);
308 unsigned char vertexLevel = levelInfo[ID] ;
309 if( vertexLevel != l ) continue ;
310
311 (*boost::fusion::at_c<0>(intervals.data))[indexSet.index(*it)] = allIndices[l-coarseLevel][vertexCount] ;
312 vertexCount++ ;
313 }
314 }
315
316 out.close() ; // until now, only the interval bounds were written to "out"
317
318 if( firstCall ) // first call of the method, must wait for next call to build difference
319 {
320 prevFilename = fn ;
321 *previousIndices *= 0 ; *previousIndices += intervals ;
322 firstCall = false ;
323 return pred ;
324 }
325
326 // write difference to previous file
327 out.open( prevFilename.c_str(), std::ios::binary | std::ios::app ) ;
328
329 double byteswritten = 0 ; // count overhead bytes
330
331 // generate difference between previous indices and current indices
332 typename VariableSet::VariableSet difference(varSet) ;
333 difference *= 0 ;
334 difference += intervals ; difference -= *previousIndices ;
335
336 // prepare next write
337 *previousIndices *= 0 ; *previousIndices += intervals ; prevFilename = fn ;
338
339 // and output the differences
340 std::vector<long int> intervalIndicesTmp( gridManager.grid().size(dim) ) ;
341 difference.write( intervalIndicesTmp.begin() ) ;
342
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) ;
348
349 long int maxIndex = *std::max_element( intervalIndices.begin(), intervalIndices.end() ) + 1 ;
350
351 std::vector<ULong> frequencies( maxIndex, 0 ) ;
352 for( int i = 0 ; i < intervalIndices.size() ; i++ ) frequencies[ intervalIndices[i] ]++ ;
353
354 unsigned int nnz = (unsigned int) std::count_if( frequencies.begin(), frequencies.end(), greaterZero<ULong> ) ;
355 std::vector<int> dictionary( frequencies.size(), -1 ) ;
356 int cur_no = 0 ;
357 for( int i = 0 ; i < frequencies.size() ; i++ )
358 {
359 if( frequencies[i] > 0 )
360 {
361 dictionary[i] = cur_no ; cur_no++ ;
362 }
363 }
364 out.write(reinterpret_cast<char*>( &nnz ), sizeof(unsigned int) ) ;
365 byteswritten += sizeof(unsigned int) ;
366
367 for( int i = 0 ; i < dictionary.size() ; i++ )
368 {
369 if( dictionary[i] >= 0 ) { byteswritten += sizeof(int) ; out.write(reinterpret_cast<char*>( &i ), sizeof(int) ) ; }
370 }
371 frequencies.erase( std::remove( frequencies.begin(), frequencies.end(), 0 ), frequencies.end() ) ;
372 for( int i = 0 ; i < frequencies.size() ; i++ )
373 {
374 out.write(reinterpret_cast<char*>( &frequencies[i] ), sizeof(ULong) ) ;
375 byteswritten += sizeof(ULong) ;
376 }
377
378 byteswritten += maxLevel * sizeof(double) * 2 ;
379
380// std::cout << "Overhead written: " << byteswritten << " byte.\n" ;
381
382 Alphabet<ULong> alphabet( frequencies.begin(), frequencies.end() ) ;
383 RangeEncoder<ULong> encoder( out ) ;
384 for( int i = 0 ; i < intervalIndices.size(); i++ )
385 {
386 encodeSymbol( encoder, alphabet, dictionary[intervalIndices[i]] );
387 }
388
389 // don't use precomputed frequencies for range encoding
390// int symbolCounter = 0 ;
391// std::vector<ULong> count(maxIntervals, 1) ;
392// Alphabet<ULong> alphabet( count.begin(), count.end() ) ;
393// RangeEncoder<ULong> encoder( out ) ;
394// for( int i = 0 ; i < intervalIndices.size(); i++ )
395// {
396// encodeSymbol( encoder, alphabet, intervalIndices[i] );
397// ++count[intervalIndices[i]];
398// ++symbolCounter ;
399// if (symbolCounter>2*alphabet.size())
400// {
401// alphabet.update(count.begin(),count.end());
402// symbolCounter=0;
403// }
404// }
405
406 return pred ; // return quantization error
407 }
408
410 void flush()
411 {
412 std::ofstream out( prevFilename.c_str(), std::ios::binary | std::ios::app ) ;
413
414 double byteswritten = 0 ;
415
416 std::vector<long int> intervalIndicesTmp( gridManager.grid().size(dim) ) ;
417 previousIndices->write( intervalIndicesTmp.begin() ) ;
418
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) ) ;
423
424 long int maxIndex = *std::max_element( intervalIndices.begin(), intervalIndices.end() ) + 1 ;
425
426 std::vector<ULong> frequencies( maxIndex, 0 ) ;
427 for( int i = 0 ; i < intervalIndices.size() ; i++ ) frequencies[ intervalIndices[i] ]++ ;
428
429 unsigned int nnz = (unsigned int) std::count_if( frequencies.begin(), frequencies.end(), greaterZero<ULong> ) ;
430 std::vector<int> dictionary( frequencies.size(), -1 ) ;
431 int cur_no = 0 ;
432 for( int i = 0 ; i < frequencies.size() ; i++ )
433 {
434 if( frequencies[i] > 0 )
435 {
436 dictionary[i] = cur_no ; cur_no++ ;
437 }
438 }
439 out.write(reinterpret_cast<char*>( &nnz ), sizeof(unsigned int) ) ;
440 byteswritten += sizeof(unsigned int);
441
442 for( int i = 0 ; i < dictionary.size() ; i++ )
443 {
444 if( dictionary[i] >= 0 )
445 {
446 out.write(reinterpret_cast<char*>( &i ), sizeof(int) ) ;
447 byteswritten += sizeof(int) ;
448 }
449 }
450
451 frequencies.erase( std::remove(frequencies.begin(), frequencies.end(), 0), frequencies.end() ) ;
452 for( int i = 0 ; i < frequencies.size() ; i++ )
453 {
454 out.write(reinterpret_cast<char*>( &frequencies[i] ), sizeof(ULong) ) ;
455 byteswritten += sizeof(ULong);
456 }
457
458 byteswritten += gridManager.grid().maxLevel() * 2 * sizeof(double) ;
459
460// std::cout << "Overhead written: " << byteswritten << " byte.\n" ;
461
462 Alphabet<ULong> alphabet( frequencies.begin(), frequencies.end() ) ;
463 RangeEncoder<ULong> encoder( out ) ;
464 for( int i = 0 ; i < intervalIndices.size(); i++ )
465 {
466 encodeSymbol( encoder, alphabet, dictionary[intervalIndices[i]] );
467 }
468
469 // don't use precomputed frequencies for range encoding
470// int symbolCounter = 0 ;
471// std::vector<ULong> count(maxIntervals, 1) ;
472// Alphabet<ULong> alphabet( count.begin(), count.end() ) ;
473//
474// RangeEncoder<ULong> encoder( out ) ;
475// for( int i = 0 ; i < intervalIndices.size(); i++ )
476// {
477// encodeSymbol( encoder, alphabet, intervalIndices[i] );
478// ++count[intervalIndices[i]];
479// ++symbolCounter ;
480// if (symbolCounter>2*alphabet.size())
481// {
482// alphabet.update(count.begin(),count.end());
483// symbolCounter=0;
484// }
485// }
486 }
487
488 void finish() { firstCall = true ; } ;
489
495 void decode( GridManager<Grid>& gridManagerState, typename VariableSet::VariableSet& sol, std::string fn )
496 {
497 fn += ".dat" ;
498
499 // build hierarchic variable set -- could probably be moved to constructor
500 LevelView gv = gridManager.grid().levelView( coarseLevel ) ;
501 Space space( gridManager, gv, order ) ;
502 Spaces spaces( &space ) ;
503 std::string varNames[1] = { "pred" };
504 PredVariableSet predVarSet( spaces, varNames ) ;
505 typename PredVariableSet::VariableSet x( predVarSet ) ;
506 x *= 0 ;
507
508 // prepare prediction
509 int maxLevel = gridManager.grid().maxLevel() ;
510 IndexSet const& indexSet = varSet.indexSet ;
511
512 std::vector<double> values ;
513
514 std::vector<double> lb(maxLevel-coarseLevel+1), ub(maxLevel-coarseLevel+1) ;
515 // read lb, ub from file
516 std::ifstream in( fn.c_str(), std::ios::binary ) ;
517 for( int i = 0 ; i <= maxLevel-coarseLevel ; i++ )
518 {
519 in.read( reinterpret_cast<char*>( &lb[i] ), sizeof(double) ) ;
520 in.read( reinterpret_cast<char*>( &ub[i] ), sizeof(double) ) ;
521 }
522
523 // read in indices from file
524 typename VariableSet::VariableSet corr(varSet) ;
525 typename VariableSet::VariableSet difference(varSet) ;
526
527 std::vector<long int> intervalIndices( gridManager.grid().size(dim) ) ;
528
529 long int minIndex ;
530 in.read(reinterpret_cast<char*>( &minIndex ), sizeof(long int) ) ;
531
532 unsigned int nnz ;
533 in.read(reinterpret_cast<char*>( &nnz ), sizeof(unsigned int) ) ; // # non-empty intervals
534 std::vector<int> dictionary( nnz ) ;
535 for( int i = 0 ; i < nnz ; i++ )
536 {
537 in.read(reinterpret_cast<char*>( &dictionary[i] ), sizeof(int) ) ; // existing intervals (dictionary)
538 }
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) ) ; // frequencies
542
543 Alphabet<ULong> alphabet( frequencies.begin(), frequencies.end() ) ;
544
545 try
546 {
547 RangeDecoder<ULong> decoder( in ) ;
548 for( int i = 0 ; i < intervalIndices.size() ; i++ )
549 {
550 ULong s = decodeSymbol(decoder,alphabet) ;
551 intervalIndices[i] = dictionary[s] + minIndex ;
552 }
553 }
554 catch( std::ios_base::failure& e ) { std::cout << e.what() << " Decoding error\n" ; }
555
556 // don't use precomputed frequencies for range encoding
557// int symbolCounter = 0 ;
558// std::vector<ULong> symcount(maxIntervals, 1) ;
559// Alphabet<ULong> alphabet( symcount.begin(), symcount.end() ) ;
560// try
561// {
562// RangeDecoder<ULong> decoder( in ) ;
563// for( int i = 0 ; i < intervalIndices.size() ; i++ )
564// {
565// ULong s = decodeSymbol(decoder,alphabet) ;
566// intervalIndices[i] = s + minIndex ;
567// ++symcount[s];
568// ++symbolCounter ;
569// if (symbolCounter>2*alphabet.size())
570// {
571// alphabet.update(symcount.begin(),symcount.end());
572// symbolCounter=0;
573// }
574// }
575// }
576// catch( std::ios_base::failure& e ) { std::cout << e.what() << " Decoding error\n" ; }
577
578
579 difference.read( intervalIndices.begin() ) ;
580
581 if( firstCall )
582 {
583 // on first call to decode, the first file contains the actual interval indices of the
584 // prediction errors quantization
585 *previousIndices *= 0 ;
586 *previousIndices += difference ;
587 corr *= 0 ;
588 corr += difference ;
589 firstCall = false ;
590 }
591 else
592 {
593 // the file from which is read contains the difference between the previous interval
594 // indices and the current indices. The interval indices of the current timestep are
595 // previousIndices - difference.
596 corr *= 0 ;
597 corr += *previousIndices ; corr -= difference ;
598 // prepare next call
599 *previousIndices *= 0 ; *previousIndices += corr ;
600 }
601
602
603 // assign the overall vector to the single levels using levelInfo
604 std::vector<std::vector<ULong> > allIndices( maxLevel+1-coarseLevel ) ;
605 for( int l = coarseLevel ; l <= maxLevel ; l++ )
606 {
607 VertexLevelIterator itEnd = gridManager.grid().levelGridView( l ).template end<dim>();
608 for ( VertexLevelIterator it = gridManager.grid().levelGridView( l ).template begin<dim>();
609 it != itEnd; ++it)
610 {
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)] ) ;
615 }
616 }
617
618 // start reconstruction
619 int vertexCount = 0;
620 VertexLevelIterator itEnd = gridManager.grid().levelGridView( coarseLevel ).template end<dim>();
621
622 if( uniform )
623 {
624 reconstruct( values, allIndices[0], coarseLevel, lb[0], ub[0] );
625 }
626 else
627 {
628 values.clear() ; values.resize( allIndices[0].size() ) ;
629 for ( VertexLevelIterator it = gridManager.grid().levelGridView( coarseLevel ).template begin<dim>() ;
630 it != itEnd; ++it )
631 {
632 values[vertexCount] = reconstruct( allIndices[0][vertexCount], lb[0], ub[0], it->geometry().corner(0) );
633 vertexCount++ ;
634 }
635 }
636
637 vertexCount = 0 ;
638 for ( VertexLevelIterator it = gridManager.grid().levelGridView( coarseLevel ).template begin<dim>();
639 it != itEnd; ++it)
640 {
641 (*boost::fusion::at_c<0>(x.data))[gv.indexSet().index(*it)] = -values[vertexCount] ;
642 vertexCount++ ;
643 }
644
645 // perform prediction and correction
646 for( int l = coarseLevel ; l < maxLevel ; l++ )
647 {
648 itEnd = gridManager.grid().levelGridView( l+1 ).template end<dim>();
649
650 gv = gridManager.grid().levelView(l+1) ;
651 space.setGridView(gv);
652
653 *boost::fusion::at_c<0>(x.data) = *(mlTransfer->apply(l, *boost::fusion::at_c<0>(x.data))) ;
654
655 if( uniform )
656 {
657 reconstruct( values, allIndices[l-coarseLevel+1], l+1, lb[l+1-coarseLevel], ub[l+1-coarseLevel] );
658 }
659 else
660 {
661 vertexCount = 0;
662 values.clear() ; values.resize( allIndices[l-coarseLevel+1].size() ) ;
663 for ( VertexLevelIterator it = gridManager.grid().levelGridView( l+1 ).template begin<dim>() ;
664 it != itEnd; ++it )
665 {
666 values[vertexCount] = reconstruct( allIndices[l-coarseLevel+1][vertexCount], lb[l-coarseLevel+1],
667 ub[l-coarseLevel+1], it->geometry().corner(0));
668 vertexCount++ ;
669 }
670 }
671
672 vertexCount = 0 ;
673 for ( VertexLevelIterator it = gridManager.grid().levelGridView( l+1 ).template begin<dim>();
674 it != itEnd ; ++it)
675 {
676 //correct only vertices on level l+1
677 if( levelInfo[gridManager.grid().globalIdSet().id(*it)] == l+1 )
678 {
679 (*boost::fusion::at_c<0>(x.data))[gv.indexSet().index(*it)] -= values[vertexCount] ;
680 vertexCount++ ;
681 }
682 }
683 }
684
685 itEnd = gridManager.grid().levelGridView(maxLevel).template end<dim>();
686 for ( VertexLevelIterator it = gridManager.grid().levelGridView(maxLevel).template begin<dim>();
687 it != itEnd; ++it)
688 {
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) ] ;
691 }
692
693 std::ostringstream debugfn ;
694 count-- ;
695 in.close() ;
696 }
697
698
699 private:
700 LossyStorage( LossyStorage const& );
701 LossyStorage& operator=( LossyStorage const& ) ;
702
704 void quantize( std::vector<double> const& values, std::vector<ULong>& indices, int level, double lb, double ub )
705 {
706 double range = ub - lb ;
707
708 long int nIntervals = quantizationPolicy.getIntervals( range, aTol );
709
710 if( nIntervals > maxIntervals ) maxIntervals = nIntervals ; // for rangecoder without freq.
711
712// double bits = 0 ;
713// if( nIntervals>0) bits = int(ld(nIntervals)*100)/100.0 ;
714// std::cout << " Level: " << level << " range: " << range << " Intervals: " << nIntervals
715// << " Bits: " << ( (nIntervals > 0) ? (int(ld(nIntervals)*100))/100.0 : 0 )
716// << " nodes: " << values.size() << "\n"
717// << " bits*nodes: " << bits*values.size() << "\n" ;
718
719 indices.clear() ;
720 indices.resize( values.size(), 0 ) ;
721 if( range > 0 ) // if range is empty, indices[i]=0 for all values
722 {
723 ULong idx ;
724 for( int i = 0 ; i < values.size() ; i++ )
725 {
726 idx = (ULong)( (values[i] - lb) * nIntervals / range ) + 1 ;
727 indices[i] = idx ;
728 }
729 }
730 }
731
733 ULong quantize( double value, double lb, double ub, Dune::FieldVector<double,dim> const& coor, bool uniform = false )
734 {
735 double range = ub - lb ;
736
737 if( range == 0 ) return 0 ;
738
739 long int nIntervals = quantizationPolicy.getIntervals( range, aTol, coor, uniform ) ;
740 return (ULong)( (value - lb) * nIntervals / range ) + 1 ;
741 }
742
743
745 void reconstruct( std::vector<double>& values, std::vector<ULong> const& indices, int level, double lb, double ub )
746 {
747 double range = ub - lb ;
748
749 long int nIntervals = quantizationPolicy.getIntervals( range, aTol );
750
751 double delta ;
752 if( nIntervals <= 0 ) delta = 0 ;
753 else delta = range / nIntervals ;
754
755 values.clear() ;
756 values.resize( indices.size() ) ;
757 for( int i = 0 ; i < indices.size() ; i++ )
758 {
759 if( indices[i] == 0 ) values[i] = lb ;
760 else values[i] = lb + (2*indices[i]-1) * delta/2 ;
761 }
762 }
763
765 double reconstruct( ULong index, double lb, double ub, Dune::FieldVector<double,dim> const& coor, bool uniform = false )
766 {
767 double range = ub - lb ;
768 long int nIntervals = quantizationPolicy.getIntervals( range, aTol, coor, uniform ) ;
769 double delta ;
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 ;
774 }
775
776
778 double ld( double val ) { return log(val)/log(2.0) ; }
779
780 private:
781 GridManager<Grid>& gridManager ;
782 VariableSet varSet ;
784
785 int coarseLevel ;
786 double aTol ;
787 std::string filePrefix ;
788
789 int count ; // count timesteps
790 IoOptions ioOptions;
791
792 typename VariableSet::VariableSet* previousIndices ;
793 bool firstCall ;
794 std::string prevFilename ;
795 long int maxIntervals ;
796 bool uniform ;
797 boost::unordered_map<unsigned long int, unsigned char> levelInfo ;
798
799 int order ;
800
801 public:
802 QuantizationPolicy quantizationPolicy ;
803} ;
804
805#endif
A simple alphabet of symbols with frequencies to be used with the range coder.
Definition: rangecoder.hh:342
Grid const & grid() const
Returns a const reference on the owned grid.
Definition: gridmanager.hh:292
A class that stores information about a set of variables.
Definition: variables.hh:537
A class for storing a heterogeneous collection of FunctionSpaceElement s.
Definition: variables.hh:341
static const int dim
Definition: lossystorage.hh:62
Grid::template Codim< dim >::LevelIterator VertexLevelIterator
Definition: lossystorage.hh:69
Grid::LevelGridView LevelView
Definition: lossystorage.hh:72
boost::fusion::vector< Space const * > Spaces
Definition: lossystorage.hh:66
Grid::template Codim< dim >::LeafIterator VertexLeafIterator
Definition: lossystorage.hh:70
unsigned long int ULong
void decode(GridManager< Grid > &gridManagerState, typename VariableSet::VariableSet &sol, std::string fn)
boost::fusion::vector< VariableDescription< 0, 1, 0 > > VariableDescriptions
Definition: lossystorage.hh:67
Dune::FieldVector< double, 1 > StorageValueType
Definition: lossystorage.hh:65
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
VariableSetDescription< Spaces, VariableDescriptions > PredVariableSet
Definition: lossystorage.hh:68
QuantizationPolicy quantizationPolicy
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
bool greaterZero(T t)
Definition: lossystorage.hh:37
unsigned long ULong
Definition: lossystorage.hh:34
bool abscompare(double a, double b)
Definition: lossystorage.hh:36
Range coder for fast entropy coding.
options for VTK/AMIRA output
Definition: iobase.hh:77
OutputType outputType
Definition: iobase.hh:149
long int getIntervals(double range, double aTol, Coor const &coor=Coor(0), bool uniform=true)
Definition: lossystorage.hh:46
Dune::FieldVector< double, D > Coor
Definition: lossystorage.hh:44
Output of mesh and solution for visualization software.