KASKADE 7 development version
lossystorageWithoutTemporalPred.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
23#ifndef LOSSYSTORAGE_HH
24#define LOSSYSTORAGE_HH
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
34bool abscompare( double a, double b ) { return fabs( a ) < fabs( b ) ; }
35template< class T > bool greaterZero( T t ) { return t > 0 ; }
36
37typedef unsigned long ULong ;
38
39// Use policies for determining the quantization intervals
40template <class VariableSetSens, class Grid, int D=2>
42{
44
45 void update( typename VariableSetSens::VariableSet const&, GridManager<Grid> & ){}
46
47 void resetCount() {}
48
49 long int getIntervals(double range, double aTol, Coor const& coor = Coor(0),
50 bool uniform = true, unsigned int vidx=0 )
51 {
52// return (long int) ceil( range / aTol / 2.0 ) ;
53
54// symmetric mid-tread quantization : need odd number of intervals
55 long int nIntervals = (long int) ceil( range / aTol / 2.0 ) ;
56 if( nIntervals % 2 == 0 ) return nIntervals + 1 ;
57 return nIntervals ;
58 }
59} ;
60
61
62template <class Grid, class VariableSet, class Space, class QuantizationPolicy=UniformQuantizationPolicy<VariableSet,Grid> >
63class LossyStorage
64{
65 public:
66 static const int dim = Grid::dimension ;
67
68
69 // some typedefs used throughout the class
71 typedef boost::fusion::vector<Space const*> Spaces ;
72 typedef boost::fusion::vector<VariableDescription<0,1,0> > VariableDescriptions;
74 typedef typename Grid::template Codim<dim>::LevelIterator VertexLevelIterator ;
75 typedef typename Grid::template Codim<dim>::LeafIterator VertexLeafIterator ;
76 typedef typename Grid::template Codim<dim>::LeafIndexSet IndexSet ;
77 typedef typename Grid::LevelGridView LevelView ;
78
79
80 public:
81
82 LossyStorage( GridManager<Grid>& gridManager_, VariableSet const& varSet_, int coarseLevel_, double aTol_ , bool uniform_ = false,
83 QuantizationPolicy& quantizationPolicy_ = QuantizationPolicy() )
84 : gridManager(gridManager_), varSet(varSet_), coarseLevel(coarseLevel_), aTol(aTol_),
85 count(0), firstCall(true), uniform(uniform_), order(1), quantizationPolicy(quantizationPolicy_)
86 {
87 mlTransfer = NULL ;
88 ioOptions.outputType = IoOptions::ascii ;
89 }
90
92 {
93 if( mlTransfer != NULL ) delete mlTransfer ;
94 }
95
101 typename VariableSet::VariableSet encode( typename VariableSet::VariableSet const& sol, std::string fn )
102 {
103 fn += ".dat" ;
104
105 // for adaptivity in space, mlTransfer has to be recomputed
106 if( mlTransfer != NULL ) delete mlTransfer ;
107 mlTransfer = new MultilevelTransfer<Space,Grid>( gridManager, order, coarseLevel ) ;
108
109 // build map: vertex id - level the vertex is created
110 unsigned long int ID ;
111 levelInfo.clear();
112 for( int level = 0 ; level <= gridManager.grid().maxLevel() ; level++ )
113 {
114 for ( VertexLevelIterator it = gridManager.grid().levelGridView( level ).begin<dim>();
115 it != gridManager.grid().levelGridView( level ).end<dim>(); ++ it)
116 {
117 ID = gridManager.grid().globalIdSet().id( *it ) ;
118 if( levelInfo.find(ID) != levelInfo.end() ) continue ;
119 levelInfo[ID] = level ;
120 }
121 }
122
123 IndexSet const& indexSet = varSet.indexSet ;
124 int maxLevel = gridManager.grid().maxLevel() ;
125
126 // for some debug output
127 std::ostringstream debugfn ;
128 typename VariableSet::VariableSet predictionError(varSet) ;
129 predictionError *= 0 ;
130
131 // create variable set over hierarchic function space for multilevel-prediction
132 LevelView gv = gridManager.grid().levelView( coarseLevel ) ;
133 Space space( gridManager, gv, order ) ;
134 Spaces spaces( &space ) ;
135 std::string varNames[1] = { "pred" };
136 PredVariableSet predVarSet( spaces, varNames ) ;
137
138 typename PredVariableSet::VariableSet x( predVarSet ) ;
139 x *= 0 ;
140
141 // calculate quantization (for coarseLevel)
142 std::vector<std::vector<ULong> > allIndices ;
143 std::vector<ULong> indices ;
144 std::vector<double> nodalValues ;
145 for ( VertexLevelIterator it = gridManager.grid().levelGridView( coarseLevel ).template begin<dim>() ;
146 it != gridManager.grid().levelGridView( coarseLevel ).template end<dim>(); ++it )
147 {
148 nodalValues.push_back( -(*boost::fusion::at_c<0>(sol.data))[indexSet.index(*it)] ) ;
149 }
150
151 double ub = *std::max_element( nodalValues.begin(), nodalValues.end() ) ;
152 double lb = *std::min_element( nodalValues.begin(), nodalValues.end() ) ;
153
154 // symmetric quantization
155 ub = *std::max_element( nodalValues.begin(), nodalValues.end(), abscompare ) ;
156 if( ub < 0 ) { lb = ub ; ub = -lb ; }
157 else { lb = -ub ; }
158 // --
159
160 double range = ub - lb ;
161
162 // only needed if no pre-computed frequencies are used for range coding
163 double maxBits ;
164 if( range > 0 ) maxBits = (-ld(aTol) ) ;
165 else maxBits = 0 ;
166 if( maxBits < 0 ) maxBits = 0 ;
167 maxIntervals = (long int)ceil(pow( 2, maxBits ));
168
169 std::ofstream out( fn.c_str(), std::ios::binary ) ;
170
171 // write interval bounds for coarse level
172 out.write(reinterpret_cast<char*>( &lb ), sizeof(double) ) ;
173 out.write(reinterpret_cast<char*>( &ub ), sizeof(double) ) ;
174
175 // for iterating over grid level, used throughout this method
176 VertexLevelIterator itEnd = gridManager.grid().levelGridView( coarseLevel ).template end<dim>();
177
178 unsigned long vertexCount = 0 ;
179 if( uniform )
180 {
181 quantize( nodalValues, indices, coarseLevel, lb, ub ) ;
182
183 // collect indices on each level in a common vector, and after finishing the
184 // multilevel prediction, calculate occuring frequencies of interval numbers, and encode
185 // using range coder
186 allIndices.push_back( indices ) ;
187
188 reconstruct( nodalValues, indices, coarseLevel, lb, ub ) ;
189 }
190 else
191 {
192 // perform quantization adaptively, possibly different for each node
193 indices.clear() ;
194 indices.resize(nodalValues.size(), 0) ;
195 for ( VertexLevelIterator it = gridManager.grid().levelGridView( coarseLevel ).template begin<dim>() ;
196 it != itEnd; ++it )
197 {
198 unsigned int vidx = gridManager.grid().leafIndexSet().index(*it) ;
199
200 indices[vertexCount] = quantize( nodalValues[vertexCount], lb, ub, it->geometry().corner(0),vidx );
201
202 nodalValues[vertexCount] = reconstruct( indices[vertexCount], lb, ub, it->geometry().corner(0),vidx);
203
204 vertexCount++ ;
205 }
206 allIndices.push_back( indices ) ;
207 }
208
209 // assign reconstructed coarse grid values of solution to hierarchic variable
210 vertexCount = 0 ;
211 for ( VertexLevelIterator it = gridManager.grid().levelGridView( coarseLevel ).template begin<dim>();
212 it != itEnd ; ++it)
213 {
214 (*boost::fusion::at_c<0>(x.data))[gv.indexSet().index(*it)] -= nodalValues[vertexCount] ;
215 vertexCount++ ;
216 }
217
218
219 typename VariableSet::VariableSet pred(varSet) ;
220 for ( VertexLevelIterator it = gridManager.grid().levelGridView(coarseLevel).template begin<dim>();
221 it != itEnd; ++it)
222 {
223 (*boost::fusion::at_c<0>(pred.data))[ indexSet.index(*it) ] = (*boost::fusion::at_c<0>(x.data))[ gv.indexSet().index(*it) ] ;
224 }
225
226 // now iterate over all grid levels
227 for( int l = coarseLevel ; l < maxLevel ; l++ )
228 {
229 gv = gridManager.grid().levelView(l+1) ;
230 space.setGridView(gv);
231
232 *boost::fusion::at_c<0>(x.data) = *(mlTransfer->apply(l, *boost::fusion::at_c<0>(x.data))) ;
233
234 nodalValues.clear() ;
235 itEnd = gridManager.grid().levelGridView( l+1 ).template end<dim>();
236 for ( VertexLevelIterator it = gridManager.grid().levelGridView( l+1 ).template begin<dim>();
237 it != itEnd; ++it)
238 {
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)] ;
241
242 nodalValues.push_back(val);
243 }
244
245 ub = *std::max_element( nodalValues.begin(), nodalValues.end() ) ;
246 lb = *std::min_element( nodalValues.begin(), nodalValues.end() ) ;
247
248 // symmetric mid tread quant
249 ub = *std::max_element( nodalValues.begin(), nodalValues.end(), abscompare ) ;
250 if( ub < 0 ) { lb = ub ; ub = -lb ; }
251 else { lb = -ub ; }
252 // --
253
254 out.write(reinterpret_cast<char*>( &lb ), sizeof(double) ) ;
255 out.write(reinterpret_cast<char*>( &ub ), sizeof(double) ) ;
256
257 if( uniform )
258 {
259 quantize( nodalValues, indices, l+1, lb, ub) ;
260 allIndices.push_back( indices ) ;
261 reconstruct( nodalValues, indices, l+1, lb, ub ) ;
262 }
263 else
264 {
265 vertexCount = 0 ;
266 indices.clear() ; indices.resize(nodalValues.size(), 0);
267
268 for ( VertexLevelIterator it = gridManager.grid().levelGridView( l+1 ).template begin<dim>() ;
269 it != itEnd; ++it )
270 {
271 unsigned int vidx = gridManager.grid().leafIndexSet().index(*it) ;
272
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 );
275 vertexCount++ ;
276 }
277 allIndices.push_back( indices ) ;
278 }
279
280 // prepare prediction on next level -- use reconstructed values
281 vertexCount = 0 ;
282 unsigned long skipped = 0 ;
283 for ( VertexLevelIterator it = gridManager.grid().levelGridView( l+1 ).template begin<dim>();
284 it != itEnd; ++it)
285 {
286 // correction only for the nodes on level l+1
287 unsigned long ID = gridManager.grid().globalIdSet().id( *it ) ;
288 unsigned char vertexLevel = levelInfo[ID] ;
289 if( vertexLevel < l+1 ) { vertexCount++ ; skipped++ ; continue ; }
290
291 (*boost::fusion::at_c<0>(x.data))[gv.indexSet().index(*it)] -= nodalValues[vertexCount] ;
292 vertexCount++ ;
293 }
294// std::cout << "vertices on level " << l+1 << ": " << vertexCount - skipped << std::endl ;
295
296 // now prediction to level l+1 is finished -- store in prediction variable set
297 for ( VertexLevelIterator it = gridManager.grid().levelGridView(l+1).template begin<dim>();
298 it != itEnd; ++it)
299 {
300 (*boost::fusion::at_c<0>(pred.data))[ indexSet.index(*it) ] = (*boost::fusion::at_c<0>(x.data))[ gv.indexSet().index(*it) ] ;
301 }
302 }
303
304 // evaluation of quantization error
305 pred -= sol ;
306// std::vector<double> foo( gridManager.grid().size(dim) ) ;
307// pred.write( foo.begin() ) ;
308// double absQuantErr = fabs(*std::max_element(foo.begin(),foo.end(),abscompare)) ;
309// sol.write( foo.begin() ) ;
310// double relQuantErr = absQuantErr / fabs(*std::max_element(foo.begin(),foo.end(),abscompare)) ;
311// std::cout << "Linf quant err: abs = " << absQuantErr << "\trel = " << relQuantErr << "\n" ;
312//
313// L2Norm l2 ;
314// double l2q2 = l2.square( boost::fusion::at_c<0>(pred.vars) ) ;
315// double l2y2 = l2.square( boost::fusion::at_c<0>(sol.vars) ) ;
316// relQuantErr = sqrt(l2q2) / sqrt(l2y2) ;
317// absQuantErr = sqrt(l2q2) ;
318// std::cout << " L2 quant err: abs = " << absQuantErr << "\trel = " << relQuantErr << "\n" ;
319
320 // debug output
321// debugfn.str("") ; debugfn << "predErr" << count ; debugfn.flush() ;
322// writeVTKFile( gridManager.grid().leafGridView(), varSet, pred, debugfn.str(), ioOptions ) ;
323
324
325 // Now allIndices contains the collected interval numbers of all levels.
326 // In order to maximize efficiency of the range coder, precalculate the
327 // frequency of each interval, befor encoding.
328 typename VariableSet::VariableSet intervals(varSet) ; intervals *= 0 ;
329 for( int l = maxLevel ; l >= coarseLevel ; l-- )
330 {
331 vertexCount = 0 ;
332 itEnd = gridManager.grid().levelGridView( l ).template end<dim>();
333 for ( VertexLevelIterator it = gridManager.grid().levelGridView( l ).template begin<dim>();
334 it != itEnd; ++it)
335 {
336 (*boost::fusion::at_c<0>(intervals.data))[indexSet.index(*it)] = allIndices[l-coarseLevel][vertexCount] ;
337 vertexCount++ ;
338 }
339 }
340
341 count++ ;
342
343 // and output the indices
344 std::vector<long int> intervalIndicesTmp( gridManager.grid().size(dim) ) ;
345 intervals.write( intervalIndicesTmp.begin() ) ;
346
347 // shift indices, only positive indices for range encoding
348 // TODO: could be skipped when not using differential encoding in time, indices are always >=0.
349 long int minIndex = *std::min_element( intervalIndicesTmp.begin(), intervalIndicesTmp.end() ) ;
350 std::vector<ULong> intervalIndices( gridManager.grid().size(dim) ) ;
351
352 for( int i = 0 ; i < intervalIndicesTmp.size() ; i++ )
353 intervalIndices[i] = intervalIndicesTmp[i] - minIndex ;
354
355 out.write(reinterpret_cast<char*>( &minIndex ), sizeof(long int) ) ;
356
357 long int maxIndex = *std::max_element( intervalIndices.begin(), intervalIndices.end() ) + 1 ;
358
359 std::vector<ULong> frequencies( maxIndex, 0 ) ;
360 for( int i = 0 ; i < intervalIndices.size() ; i++ ) frequencies[ intervalIndices[i] ]++ ;
361
362 // only need to store symbols with nonzero frequency
363 unsigned int nnz = (unsigned int) std::count_if( frequencies.begin(), frequencies.end(), greaterZero<ULong> ) ;
364
365 std::vector<int> dictionary( frequencies.size(), -1 ) ;
366 int cur_no = 0 ;
367 for( int i = 0 ; i < frequencies.size() ; i++ )
368 {
369 if( frequencies[i] > 0 )
370 {
371 dictionary[i] = cur_no ; cur_no++ ;
372 }
373 }
374 out.write(reinterpret_cast<char*>( &nnz ), sizeof(unsigned int) ) ;
375 for( int i = 0 ; i < dictionary.size() ; i++ )
376 {
377 if( dictionary[i] >= 0 ) out.write(reinterpret_cast<char*>( &i ), sizeof(int) ) ;
378 }
379
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) ) ;
383
384 Alphabet<ULong> alphabet( frequencies.begin(), frequencies.end() ) ;
385 RangeEncoder<ULong> encoder( out ) ;
386
387 for( int i = 0 ; i < intervalIndices.size(); i++ )
388 {
389 encodeSymbol( encoder, alphabet, dictionary[intervalIndices[i]] );
390 }
391
392 // encoding without using precomputed frequencies
393// int symbolCounter = 0 ;
394// std::vector<ULong> count(maxIntervals, 1) ;
395// Alphabet<ULong> alphabet( count.begin(), count.end() ) ;
396// for( int i = 0 ; i < intervalIndices.size(); i++ )
397// {
398// encodeSymbol( encoder, alphabet, intervalIndices[i] );
399// ++count[intervalIndices[i]];
400// ++symbolCounter ;
401// if (symbolCounter>2*alphabet.size())
402// {
403// alphabet.update(count.begin(),count.end());
404// symbolCounter=0;
405// }
406// }
407
408 return pred ; // return quantization error
409 }
410
412 void flush() { } // not needed for version without temporal correlations
413
414 void finish() { firstCall = true ; quantizationPolicy.resetCount() ; } ;
415
416
422 void decode( GridManager<Grid>& gridManagerState, typename VariableSet::VariableSet& sol, std::string fn )
423 {
424 fn += ".dat" ;
425
426 // for adaptivity in space, mlTransfer has to be recomputed
427 if( mlTransfer != NULL ) delete mlTransfer ;
428 mlTransfer = new MultilevelTransfer<Space,Grid>( gridManagerState, order, coarseLevel ) ;
429
430 // build map: vertex id - level the vertex is created
431 unsigned long int ID ;
432 levelInfo.clear() ;
433 for( int level = 0 ; level <= gridManagerState.grid().maxLevel() ; level++ )
434 {
435 for ( VertexLevelIterator it = gridManagerState.grid().levelGridView( level ).template begin<dim>();
436 it != gridManagerState.grid().levelGridView( level ).template end<dim>(); ++ it)
437 {
438 ID = gridManagerState.grid().globalIdSet().id( *it ) ;
439 if( levelInfo.find(ID) != levelInfo.end() ) continue ;
440 levelInfo[ID] = level ;
441 }
442 }
443
444 // build hierarchic variable set -- could probably be moved to constructor
445 LevelView gv = gridManagerState.grid().levelView( coarseLevel ) ;
446 Space space( gridManagerState, gv, order ) ;
447 Spaces spaces( &space ) ;
448 std::string varNames[1] = { "pred" };
449 PredVariableSet predVarSet( spaces, varNames ) ;
450 typename PredVariableSet::VariableSet x( predVarSet ) ;
451 x *= 0 ;
452
453 // prepare prediction
454 int maxLevel = gridManagerState.grid().maxLevel() ;
455 IndexSet const& indexSet = gridManagerState.grid().leafIndexSet();
456
457 std::vector<double> values ;
458
459 std::vector<double> lb(maxLevel-coarseLevel+1), ub(maxLevel-coarseLevel+1) ;
460
461 // read lb, ub from file
462 std::ifstream in( fn.c_str(), std::ios::binary ) ;
463 for( int i = 0 ; i <= maxLevel-coarseLevel ; i++ )
464 {
465 in.read( reinterpret_cast<char*>( &lb[i] ), sizeof(double) ) ;
466 in.read( reinterpret_cast<char*>( &ub[i] ), sizeof(double) ) ;
467 }
468
469 // read in indices from file
470 std::vector<long int> intervalIndices( gridManagerState.grid().size(dim) ) ;
471
472 long int minIndex ;
473 in.read(reinterpret_cast<char*>( &minIndex ), sizeof(long int) ) ;
474
475 // # non-empty intervals
476 unsigned int nnz ;
477 in.read(reinterpret_cast<char*>( &nnz ), sizeof(unsigned int) ) ;
478
479 // existing intervals (dictionary)
480 std::vector<int> dictionary( nnz ) ;
481 for( int i = 0 ; i < nnz ; i++ )
482 {
483 in.read(reinterpret_cast<char*>( &dictionary[i] ), sizeof(int) ) ;
484 }
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) ) ; // frequencies
488
489 Alphabet<ULong> alphabet( frequencies.begin(), frequencies.end() ) ;
490 try
491 {
492 RangeDecoder<ULong> decoder( in ) ;
493 for( int i = 0 ; i < intervalIndices.size() ; i++ )
494 {
495 ULong s = decodeSymbol(decoder,alphabet) ;
496 intervalIndices[i] = dictionary[s] + minIndex ;
497 }
498 }
499 catch( std::ios_base::failure& e ) { std::cout << e.what() << " Decoding error\n" ; }
500
501 // version without using precomputed frequencies
502// int symbolCounter = 0 ; // 2010-02-19
503// std::vector<ULong> symcount(maxIntervals, 1) ; // 2010-02-19
504// Alphabet<ULong> alphabet( symcount.begin(), symcount.end() ) ;//2010-02-19
505// try
506// {
507// RangeDecoder<ULong> decoder( in ) ;
508// for( int i = 0 ; i < intervalIndices.size() ; i++ )
509// {
510// ULong s = decodeSymbol(decoder,alphabet) ;
511// intervalIndices[i] = s + minIndex ;
512// ++symcount[s];
513// ++symbolCounter ;
514// if (symbolCounter>2*alphabet.size())
515// {
516// alphabet.update(symcount.begin(),symcount.end());
517// symbolCounter=0;
518// }
519// }
520// }
521// catch( std::ios_base::failure& e ) { std::cout << e.what() << " Decoding error\n" ; }
522
523
524 // assign corrections to variableSet
525 typename VariableSet::VariableSet corr(sol) ; corr *= 0 ;
526 corr.read( intervalIndices.begin() ) ;
527
528 // assign the overall vector to the single levels
529 std::vector<std::vector<ULong> > allIndices( maxLevel+1-coarseLevel ) ;
530 for( int l = coarseLevel ; l <= maxLevel ; l++ )
531 {
532 for ( VertexLevelIterator it = gridManagerState.grid().levelGridView( l ).template begin<dim>();
533 it != gridManagerState.grid().levelGridView( l ).template end<dim>(); ++it)
534 {
535 allIndices[l-coarseLevel].push_back( (*boost::fusion::at_c<0>(corr.data))[indexSet.index(*it)] ) ;
536 }
537 }
538
539 // start reconstruction
540 VertexLevelIterator itEnd = gridManagerState.grid().levelGridView( coarseLevel ).template end<dim>();
541
542 int vertexCount = 0;
543 if( uniform )
544 {
545 reconstruct( values, allIndices[0], coarseLevel, lb[0], ub[0] );
546 }
547 else
548 {
549 values.clear() ; values.resize( allIndices[0].size() ) ;
550 for ( VertexLevelIterator it = gridManagerState.grid().levelGridView( coarseLevel ).template begin<dim>() ;
551 it != itEnd; ++it )
552 {
553 unsigned int vidx = gridManagerState.grid().leafIndexSet().index(*it) ;
554
555 values[vertexCount] = reconstruct( allIndices[0][vertexCount], lb[0], ub[0], it->geometry().corner(0),vidx );
556 vertexCount++ ;
557 }
558 }
559
560 vertexCount = 0 ;
561 for ( VertexLevelIterator it = gridManagerState.grid().levelGridView( coarseLevel ).template begin<dim>();
562 it != itEnd; ++it)
563 {
564 (*boost::fusion::at_c<0>(x.data))[gv.indexSet().index(*it)] = -values[vertexCount] ;
565 vertexCount++ ;
566 }
567
568 // store predicted values for the coarse grid in solution vector
569 for ( VertexLevelIterator it = gridManagerState.grid().levelGridView( coarseLevel ).template begin<dim>();
570 it != itEnd; ++it)
571 {
572 (*boost::fusion::at_c<0>(sol.data))[ indexSet.index(*it) ] = (*boost::fusion::at_c<0>(x.data))[ gv.indexSet().index(*it) ] ;
573 vertexCount++ ;
574 }
575
576 // perform prediction and correction
577 for( int l = coarseLevel ; l < maxLevel ; l++ )
578 {
579 itEnd = gridManagerState.grid().levelGridView( l+1 ).template end<dim>();
580
581 gv = gridManagerState.grid().levelView(l+1) ;
582 space.setGridView(gv);
583
584 *boost::fusion::at_c<0>(x.data) = *(mlTransfer->apply(l, *boost::fusion::at_c<0>(x.data))) ;
585
586 if( uniform )
587 {
588 reconstruct( values, allIndices[l-coarseLevel+1], l+1, lb[l+1-coarseLevel], ub[l+1-coarseLevel] );
589 }
590 else
591 {
592 vertexCount = 0;
593 values.clear();
594 values.resize( allIndices[l-coarseLevel+1].size() ) ;
595
596 for ( VertexLevelIterator it = gridManagerState.grid().levelGridView( l+1 ).template begin<dim>() ;
597 it != itEnd; ++it )
598 {
599 unsigned int vidx = gridManagerState.grid().leafIndexSet().index(*it) ;
600
601 values[vertexCount] = reconstruct( allIndices[l-coarseLevel+1][vertexCount], lb[l-coarseLevel+1],
602 ub[l-coarseLevel+1], it->geometry().corner(0), vidx );
603 vertexCount++ ;
604 }
605 }
606
607 vertexCount = 0 ;
608 for ( VertexLevelIterator it = gridManagerState.grid().levelGridView( l+1 ).template begin<dim>();
609 it != itEnd; ++it)
610 {
611 //correct only vertices new on level l+1
612 if( levelInfo[gridManagerState.grid().globalIdSet().id(*it)] == l+1 )
613 {
614 (*boost::fusion::at_c<0>(x.data))[gv.indexSet().index(*it)] -= values[vertexCount] ;
615 }
616 vertexCount++ ;
617 }
618
619 // store predicted values for the coarse grid in solution vector
620 for ( VertexLevelIterator it = gridManagerState.grid().levelGridView( l+1 ).template begin<dim>();
621 it != itEnd; ++it)
622 {
623 (*boost::fusion::at_c<0>(sol.data))[ indexSet.index(*it) ] = (*boost::fusion::at_c<0>(x.data))[ gv.indexSet().index(*it) ] ;
624 vertexCount++ ;
625 }
626 }
627
628 count-- ;
629
630 // debug output
631// std::ostringstream debugfn ;
632// debugfn << "reconstruction" << count ; debugfn.flush() ;
633// writeVTKFile( varSet, sol, debugfn.str(), ioOptions ) ;
634
635 in.close() ;
636 }
637
638
639 private:
640 LossyStorage( LossyStorage const& );
641 LossyStorage& operator=( LossyStorage const& ) ;
642
644 void quantize( std::vector<double> const& values, std::vector<ULong>& indices, int level, double lb, double ub )
645 {
646 double range = ub - lb ;
647
648 long int nIntervals = quantizationPolicy.getIntervals( range, aTol );
649
650 // needed for range encoding without precomputed frequencies
651 if( nIntervals > maxIntervals ) maxIntervals = nIntervals ;
652
653 // debug output
654// std::cout << nIntervals << "="
655// << ( (nIntervals > 0) ? (int(ld(nIntervals)*100))/100.0 : 0 ) << " / " ;
656
657// std::cout << " Level: " << level << " Intervals: " << nIntervals
658// << " Bits: " << ( (nIntervals > 0) ? (int(ld(nIntervals)*100))/100.0 : 0 )
659// << "\n" ;
660
661 indices.clear() ;
662 indices.resize( values.size(), 0 ) ;
663 if( range > 0 ) // if range is empty, indices[i]=0 for all values
664 {
665 ULong idx ;
666 for( int i = 0 ; i < values.size() ; i++ )
667 {
668 idx = (ULong)( (values[i] - lb) * nIntervals / range ) + 1 ;
669 indices[i] = idx ;
670 }
671 }
672 }
673
675 ULong quantize( double value, double lb, double ub, Dune::FieldVector<double,dim> const& coor,
676 bool uniform = false, unsigned int vidx = 0 )
677 {
678 double range = ub - lb ;
679
680 if( range == 0 ) return 0 ;
681
682 long int nIntervals = quantizationPolicy.getIntervals( range, aTol, coor, uniform, vidx ) ;
683
684 // needed for range encoding without precomputed frequencies
685 if( nIntervals > maxIntervals ) maxIntervals = nIntervals ;
686
687 return (ULong)( (value - lb) * nIntervals / range ) + 1 ;
688 }
689
690
692 void reconstruct( std::vector<double>& values, std::vector<ULong> const& indices, int level, double lb, double ub )
693 {
694 double range = ub - lb ;
695
696 long int nIntervals = quantizationPolicy.getIntervals( range, aTol );
697
698 double delta ;
699 if( nIntervals <= 0 ) delta = 0 ;
700 else delta = range / nIntervals ;
701
702 values.clear() ;
703 values.resize( indices.size() ) ;
704 for( int i = 0 ; i < indices.size() ; i++ )
705 {
706 if( indices[i] == 0 ) values[i] = lb ;
707 else values[i] = lb + (2*indices[i]-1) * delta/2 ;
708 }
709 }
710
712 double reconstruct( ULong index, double lb, double ub, Dune::FieldVector<double,dim> const& coor,
713 bool uniform = false, unsigned int vidx = 0 )
714 {
715 double range = ub - lb ;
716 long int nIntervals = quantizationPolicy.getIntervals( range, aTol, coor, uniform, vidx ) ;
717 double delta ;
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 ;
722 }
723
724
726 double ld( double val ) { return log(val)/log(2.0) ; }
727
728 void setTolerance( double tol ) { aTol = tol ; }
729
730
731 private:
732 GridManager<Grid>& gridManager ;
733 VariableSet varSet ;
735
736 int coarseLevel ;
737 double aTol ;
738 std::string filePrefix ;
739
740 int count ; // count timesteps
741 IoOptions ioOptions;
742
743 bool firstCall ;
744 long int maxIntervals ;
745
746 bool uniform ;
747 boost::unordered_map<unsigned long int, unsigned char> levelInfo ;
748
749 int order; // degree of interpolation polynomials; currently only linear interpolation is supported
750
751 public:
752 QuantizationPolicy quantizationPolicy ;
753
754} ;
755
756#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
Grid::LevelGridView LevelView
boost::fusion::vector< Space const * > Spaces
Grid::template Codim< dim >::LeafIterator VertexLeafIterator
unsigned long int ULong
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.
Definition: rangecoder.hh:245
Entropy coding with range encoder.
Definition: rangecoder.hh:136
unsigned long ULong
Definition: lossystorage.hh:34
bool greaterZero(T t)
unsigned long ULong
bool abscompare(double a, double b)
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, unsigned int vidx=0)
void update(typename VariableSetSens::VariableSet const &, GridManager< Grid > &)
Dune::FieldVector< double, D > Coor
Output of mesh and solution for visualization software.