• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CSMMLab / KiT-RT / #94

27 May 2025 08:36PM UTC coverage: 46.655% (+0.009%) from 46.646%
#94

push

travis-ci

ScSteffen
merged from main

0 of 5 new or added lines in 1 file covered. (0.0%)

2 existing lines in 2 files now uncovered.

4422 of 9478 relevant lines covered (46.66%)

57163.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

53.33
/src/datagenerator/datageneratorbase.cpp
1
/*!
2
 * \file datageneratorbase.cpp
3
 * \brief Class to generate data for the neural entropy closure
4
 * \author S. Schotthoefer
5
 */
6

7
#include "datagenerator/datageneratorbase.hpp"
8
#include "common/config.hpp"
9
#include "datagenerator/datageneratorclassification1D.hpp"
10
#include "datagenerator/datageneratorclassification2D.hpp"
11
#include "datagenerator/datageneratorregression1D.hpp"
12
#include "datagenerator/datageneratorregression2D.hpp"
13
#include "datagenerator/datageneratorregression3D.hpp"
14
#include "entropies/entropybase.hpp"
15
#include "optimizers/newtonoptimizer.hpp"
16
#include "optimizers/partregularizednewtonoptimizer.hpp"
17
#include "optimizers/reducednewtonoptimizer.hpp"
18
#include "optimizers/reducedpartregularizednewtonoptimizer.hpp"
19
#include "optimizers/regularizednewtonoptimizer.hpp"
20
#include "quadratures/quadraturebase.hpp"
21
#include "toolboxes/errormessages.hpp"
22
#include "toolboxes/textprocessingtoolbox.hpp"
23
#include "velocitybasis/sphericalbase.hpp"
24

25
// #include <chrono>
26
#include "spdlog/spdlog.h"
27
#include <iomanip>
28
#include <math.h>
29
#include <omp.h>
30
#include <sstream>
31

32
DataGeneratorBase::DataGeneratorBase( Config* settings ) {
6✔
33
    _settings = settings;
6✔
34
    _setSize  = settings->GetTrainingDataSetSize();
6✔
35

36
    _maxPolyDegree = settings->GetMaxMomentDegree();
6✔
37

38
    // Check consistency between dimension of quadrature and sample basis
39
    if( _settings->GetDim() == 1 ) {
6✔
40
        if( _settings->GetQuadName() != QUAD_GaussLegendre1D && _settings->GetQuadName() != QUAD_GaussChebyshev1D ) {
4✔
41
            ErrorMessages::Error( "For 1D Sampling, please choose a 1D quadrature rule.", CURRENT_FUNCTION );
×
42
        }
43
    }
44
    else {
45
        if( _settings->GetQuadName() == QUAD_GaussLegendre1D || _settings->GetQuadName() == QUAD_GaussChebyshev1D ) {
2✔
46
            ErrorMessages::Error( "For 3D Sampling, please choose a 3D quadrature rule.", CURRENT_FUNCTION );
×
47
        }
48
    }
49
    // Quadrature
50
    _quadrature       = QuadratureBase::Create( settings );
6✔
51
    _nq               = _quadrature->GetNq();
6✔
52
    _quadPoints       = _quadrature->GetPoints();
6✔
53
    _weights          = _quadrature->GetWeights();
6✔
54
    _quadPointsSphere = _quadrature->GetPointsSphere();
6✔
55

56
    // Spherical Harmonics
57
    if( _settings->GetSphericalBasisName() == SPHERICAL_HARMONICS && _maxPolyDegree > 0 && _settings->GetAlphaSampling() == false ) {
6✔
58
        ErrorMessages::Error( "No direct moment sampling algorithm for spherical harmonics basis with degree higher than 0 implemented",
×
59
                              CURRENT_FUNCTION );
60
    }
61
    _basisGenerator = SphericalBase::Create( _settings );
6✔
62

63
    _nTotalEntries = _basisGenerator->GetBasisSize();
6✔
64

65
    _momentBasis = VectorVector( _nq, Vector( _nTotalEntries, 0.0 ) );
6✔
66

67
    // Optimizer
68
    _reducedSampling = false;
6✔
69
    switch( settings->GetOptimizerName() ) {
6✔
70
        case NEWTON: _optimizer = new NewtonOptimizer( settings ); break;
4✔
71
        case REGULARIZED_NEWTON: _optimizer = new RegularizedNewtonOptimizer( settings ); break;
2✔
72
        case PART_REGULARIZED_NEWTON: _optimizer = new PartRegularizedNewtonOptimizer( settings ); break;
×
73
        case REDUCED_NEWTON:
×
74
            _optimizer       = new ReducedNewtonOptimizer( settings );
×
75
            _reducedSampling = true;
×
76
            break;
×
77
        case REDUCED_PART_REGULARIZED_NEWTON:
×
78
            _optimizer       = new ReducedPartRegularizedNewtonOptimizer( settings );
×
79
            _reducedSampling = true;
×
80
            break;
×
81
        default: ErrorMessages::Error( "Optimizer choice not feasible for datagenerator.", CURRENT_FUNCTION ); break;
×
82
    }
83
    // Entropy
84
    _entropy = EntropyBase::Create( _settings );
6✔
85
}
6✔
86

87
DataGeneratorBase::~DataGeneratorBase() {
6✔
88
    delete _quadrature;
6✔
89
    delete _entropy;
6✔
90
}
6✔
91

×
92
DataGeneratorBase* DataGeneratorBase::Create( Config* settings ) {
93

94
    if( settings->GetSamplerName() == REGRESSION_SAMPLER ) {
95
        switch( settings->GetDim() ) {
6✔
96
            case 1: return new DataGeneratorRegression1D( settings );
6✔
97
            case 2: return new DataGeneratorRegression2D( settings );
6✔
98
            case 3: return new DataGeneratorRegression3D( settings );
6✔
99
            default: ErrorMessages::Error( "Sampling for more than 3 dimensions is not yet supported.", CURRENT_FUNCTION );
100
        }
6✔
101
    }
102
    else if( settings->GetSamplerName() == CLASSIFICATION_SAMPLER ) {
6✔
103
        switch( settings->GetDim() ) {
4✔
104
            case 1: return new DataGeneratorClassification1D( settings );
2✔
105
            case 2: return new DataGeneratorClassification2D( settings );
×
106
            default: ErrorMessages::Error( "Sampling for more than 3 dimensions is not yet supported.", CURRENT_FUNCTION );
2✔
107
        }
×
108
    }
109
    return nullptr;
110
}
2✔
111

2✔
112
void DataGeneratorBase::SampleMultiplierAlpha() {
2✔
113
    double maxAlphaValue = _settings->GetAlphaSamplingBound();
×
114
    // Rejection Sampling based on smallest EV of H
×
115
    if( _settings->GetNormalizedSampling() ) {
116
        if( _maxPolyDegree == 0 ) {
117
            ErrorMessages::Error( "Normalized sampling not meaningful for M0 closure", CURRENT_FUNCTION );
×
118
        }
119

120
        VectorVector momentsRed = VectorVector( _nq, Vector( _nTotalEntries - 1, 0.0 ) );
×
121

×
122
        for( unsigned idx_nq = 0; idx_nq < _nq; idx_nq++ ) {    // copy (reduced) moments
123
            for( unsigned idx_sys = 1; idx_sys < _nTotalEntries; idx_sys++ ) {
×
124
                momentsRed[idx_nq][idx_sys - 1] = _momentBasis[idx_nq][idx_sys];
×
125
            }
×
126
        }
127

128
        // Create generator
×
129
        std::default_random_engine generator;
130
        std::uniform_real_distribution<double> distribution( -1 * maxAlphaValue, maxAlphaValue );
×
131
        double mean   = 0.0;
×
132
        double stddev = maxAlphaValue / 3.0;
×
133
        std::normal_distribution<double> distribution_normal( mean, stddev );
134

135
        // Can be parallelized, but check if there is a race condition with datagenerator
136
#pragma omp parallel for
137
        for( unsigned idx_set = 0; idx_set < _setSize; idx_set++ ) {
×
138
            Vector alphaRed = Vector( _nTotalEntries - 1, 0.0 );    // local reduced alpha
×
139

×
140
            bool accepted     = false;
×
141
            bool normAccepted = false;
×
142
            while( !accepted ) {
143
                // Sample random multivariate uniformly distributed alpha between minAlpha and MaxAlpha.
144
                for( unsigned idx_sys = 1; idx_sys < _nTotalEntries; idx_sys++ ) {
×
145
                    if( _settings->GetUniformSamlping() )
146
                        alphaRed[idx_sys - 1] = distribution( generator );
147
                    else {
148
                        alphaRed[idx_sys - 1] = distribution_normal( generator );
149
                        if( alphaRed[idx_sys - 1] > maxAlphaValue ) alphaRed[idx_sys - 1] = maxAlphaValue;
150
                        if( alphaRed[idx_sys - 1] < -1 * maxAlphaValue ) alphaRed[idx_sys - 1] = -1 * maxAlphaValue;
151
                    }
152
                }
153
                normAccepted = true;
154
                if( _settings->GetUniformSamlping() ) {
155
                    if( norm( alphaRed ) > maxAlphaValue ) normAccepted = false;
156
                }
157
                // Compute alpha_0 = log(<exp(alpha m )>) // for maxwell boltzmann! only
158
                double integral = 0.0;
159
                // Integrate <eta'_*(alpha*m)>
160
                for( unsigned idx_quad = 0; idx_quad < _nq; idx_quad++ ) {
161
                    integral += _entropy->EntropyPrimeDual( dot( alphaRed, momentsRed[idx_quad] ) ) * _weights[idx_quad];
162
                }
163
                _alpha[idx_set][0] = -( log( integral ) + log( _momentBasis[0][0] ) ) / _momentBasis[0][0];    //  normalization
164

165
                // Assemble complete alpha (normalized)
166
                for( unsigned idx_sys = 1; idx_sys < _nTotalEntries; idx_sys++ ) {
167
                    _alpha[idx_set][idx_sys] = alphaRed[idx_sys - 1];
168
                }
169

170
                // Compute rejection criteria
171
                accepted = normAccepted;
172
                if( normAccepted ) {
173
                    if( _reducedSampling ) {
174
                        accepted = ComputeReducedEVRejection( momentsRed, alphaRed );
175
                    }
176
                    else {
177
                        accepted = ComputeEVRejection( idx_set );
178
                    }
179
                }
180
            }
181
        }
182
    }
183
    else {
184
        // non normalized sampling
185
        // TODO
186
        ErrorMessages::Error( "Non-Normalized Alpha Sampling is not yet implemented.", CURRENT_FUNCTION );
187
    }
188
}
189

190
void DataGeneratorBase::PrintLoadScreen() {
191
    auto log = spdlog::get( "event" );
192
    log->info( "------------------------ Data Generation Starts --------------------------" );
193
    log->info( "| Generating {} datapoints.", _setSize );
194
}
×
195

196
bool DataGeneratorBase::ComputeEVRejection( unsigned idx_set ) {
197
    Matrix hessian = Matrix( _nTotalEntries, _nTotalEntries, 0.0 );
198
    _optimizer->ComputeHessian( _alpha[idx_set], _momentBasis, hessian );
6✔
199
    SymMatrix hessianSym( hessian );    // Bad solution, rewrite with less memory need
18✔
200
    Vector ew = Vector( _nTotalEntries, 0.0 );
6✔
201
    eigen( hessianSym, ew );
6✔
202
    if( min( ew ) < _settings->GetMinimalEVBound() ) {
6✔
203
        return false;
204
    }
902✔
205
    return true;
1,804✔
206
}
902✔
207

1,804✔
208
bool DataGeneratorBase::ComputeReducedEVRejection( VectorVector& redMomentBasis, Vector& redAlpha ) {
1,804✔
209
    Matrix hessian = Matrix( _nTotalEntries - 1, _nTotalEntries - 1, 0.0 );
902✔
210
    _optimizer->ComputeHessian( redAlpha, redMomentBasis, hessian );
902✔
211
    SymMatrix hessianSym( hessian );    // Bad solution, rewrite with less memory need
886✔
212
    Vector ew = Vector( _nTotalEntries - 1, 0.0 );
213
    eigen( hessianSym, ew );
16✔
214
    if( min( ew ) < _settings->GetMinimalEVBound() ) {
215
        return false;
216
    }
×
217
    return true;
×
218
}
×
219

×
220
void DataGeneratorBase::ComputeRealizableSolution() {
×
221
    if( _reducedSampling ) {
×
UNCOV
222
        VectorVector momentsRed = VectorVector( _nq, Vector( _nTotalEntries - 1, 0.0 ) );
×
223
        for( unsigned idx_nq = 0; idx_nq < _nq; idx_nq++ ) {    // copy (reduced) moments
×
224
            for( unsigned idx_sys = 1; idx_sys < _nTotalEntries; idx_sys++ ) {
225
                momentsRed[idx_nq][idx_sys - 1] = _momentBasis[idx_nq][idx_sys];
×
226
            }
227
        }
228
#pragma omp parallel for schedule( guided )
2✔
229
        for( unsigned idx_sol = 0; idx_sol < _setSize; idx_sol++ ) {
2✔
230
            Vector uSolRed( _nTotalEntries - 1, 0.0 );
×
231
            Vector alphaRed( _nTotalEntries - 1, 0.0 );
×
232
            for( unsigned idx_sys = 1; idx_sys < _nTotalEntries; idx_sys++ ) {
×
233
                alphaRed[idx_sys - 1] = _alpha[idx_sol][idx_sys];
×
234
            }
235
            _optimizer->ReconstructMoments( uSolRed, alphaRed, momentsRed );
236

×
237
            for( unsigned idx_sys = 1; idx_sys < _nTotalEntries; idx_sys++ ) {
238
                _uSol[idx_sol][idx_sys] = uSolRed[idx_sys - 1];
239
            }
240
            _uSol[idx_sol][0] = 1.0;
241
        }
242
    }
243
    else {
244
#pragma omp parallel for schedule( guided )
245
        for( unsigned idx_sol = 0; idx_sol < _setSize; idx_sol++ ) {
246
            _optimizer->ReconstructMoments( _uSol[idx_sol], _alpha[idx_sol], _momentBasis );
247
        }
248
    }
249
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc