-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathElastanceDenormalizer.cpp
154 lines (123 loc) · 4.91 KB
/
ElastanceDenormalizer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//
// Created by andrei on 14.09.2020.
//
#include "ElastanceDenormalizer.h"
#include <algorithm>
#include <cmath>
#include <fstream>
#include <cassert>
// Constructor
ElastanceDenormalizer::ElastanceDenormalizer(double elastanceMax, double elastanceMin, double timeMax, double step) {
this->elastanceMin = elastanceMin;
this->elastanceMax = elastanceMax;
this->timeAtMaxElastance = timeMax;
this->step = step;
}
void ElastanceDenormalizer::exportCsv(const char *filename) {
std::ofstream f(filename);
f << "Time,Value,DenormTime,DenormValue\n";
for (int i = 0; i < ELASTANCE_SIZE; i++)
f << elastanceTime[i] << ',' << elastanceValue[i] << ',' << timeDenorm[i] << ',' << valueDenorm[i] << '\n';
f.close();
}
// Experimental elastance denormalization
void ExperimentalExtendedElastanceDenormalizer::denormalize() {
const double elastanceMinNorm = *std::min_element(elastanceValue.begin(), elastanceValue.end());
const double elastanceMaxNorm = *std::max_element(elastanceValue.begin(), elastanceValue.end());;
const double deltaNorm = elastanceMaxNorm - elastanceMinNorm;
const double delta = elastanceMax - elastanceMin;
const double ratio = delta / deltaNorm;
const double conv = 1333.22;
const auto atMaxNormalizedElastance = std::max_element(elastanceValue.begin(), elastanceValue.end());
size_t indexOfMaxElement = std::distance(elastanceValue.begin(), atMaxNormalizedElastance);
double timeAtMaxElastanceNormalized = 1.0;
double timeAtEndElastanceNormalized = 3.0;
for (int i = 0; i < ELASTANCE_SIZE; ++i)
{
if (i <= indexOfMaxElement)
{
timeDenorm[i] = elastanceTime[i] * timeAtMaxElastance;
}
else
{
timeDenorm[i] = (elastanceTime[i] - *atMaxNormalizedElastance) * (m_endTime - timeAtMaxElastance) / (timeAtEndElastanceNormalized - timeAtMaxElastanceNormalized) + timeAtMaxElastance;
}
valueDenorm[i] = ((elastanceValue[i] - elastanceMinNorm) * ratio + elastanceMin) * conv ;
}
}
// Experimental elastance denormalization
void ExperimentalElastanceDenormalizer::denormalize() {
const double elastanceMinNorm = *std::min_element(elastanceValue.begin(), elastanceValue.end());
const double elastanceMaxNorm = *std::max_element(elastanceValue.begin(), elastanceValue.end());;
const double deltaNorm = elastanceMaxNorm - elastanceMinNorm;
const double delta = elastanceMax - elastanceMin;
const double ratio = delta / deltaNorm;
const double conv = 1333.22;
const auto atMaxNormalizedElastance = std::max_element(elastanceValue.begin(), elastanceValue.end());
size_t indexOfMaxElement = std::distance(elastanceValue.begin(), atMaxNormalizedElastance);
double timeAtMaxElastanceNormalized = 1.0;
double timeAtEndElastanceNormalized = 3.0;
for (int i = 0; i < ELASTANCE_SIZE; ++i)
{
timeDenorm[i] = elastanceTime[i] * timeAtMaxElastance;
valueDenorm[i] = ((elastanceValue[i] - elastanceMinNorm) * ratio + elastanceMin) * conv ;
}
}
// Analytical elastance denormalization
void AnalyticalElastanceDenormalizer::denormalize() {
double timeAtMaxElastanceNormalized = 1.0;
double maxElastanceTime = 3.0;
double cyclePeriod = maxElastanceTime * timeAtMaxElastance / timeAtMaxElastanceNormalized;
double tau1 = 0.110 * cyclePeriod;
double tau2 = 0.180 * cyclePeriod;
double m1 = 1.32;
double m2 = 13.1;
double g1 = 0.;
double g2 = 0.;
double h1 = 0.;
double h2 = 0.;
double maxVal = 0.;
double k = 0;
const double conv = 1333.22;
for (int i = 0; i < ELASTANCE_SIZE; i++) {
timeDenorm[i] = elastanceTime[i] * timeAtMaxElastance / timeAtMaxElastanceNormalized;
g1 = pow((timeDenorm[i] / tau1), m1);
g2 = pow((timeDenorm[i] / tau2), m2);
h1 = g1 / (1 + g1);
h2 = 1 / (1 + g2);
if (h1 > h2)
maxVal = h1;
else
maxVal = h2;
k = (elastanceMax - elastanceMin) / maxVal;
valueDenorm[i] = (k * h1 * h2 + elastanceMin) * conv ;
}
}
// Linear interpolation function
double interpolate(double t0, double t1, double x0, double x1, double t) {
double factor = (t1 - t) / (t1 - t0);
double x_interp = x0 * factor + x1 * (1 - factor);
return x_interp;
}
// Precompute values
void ElastanceDenormalizer::precomputeValues() {
double t = 0;
int i = 0;
double endTime = timeDenorm.back();
while (t < endTime) {
double value = interpolate(timeDenorm[i], timeDenorm[i + 1], valueDenorm[i], valueDenorm[i + 1], t);
valuePrep.push_back(value);
t += step;
if (timeDenorm[i + 1] < t) {
i++;
}
}
}
// Constant time retrieval
double ElastanceDenormalizer::at(double t)
{
double endTime = timeDenorm.back();
int index = int(t / endTime * valuePrep.size());
index = index % valuePrep.size(); // Periodicity
return valuePrep[index];
}