forked from ngageoint/csm
-
Notifications
You must be signed in to change notification settings - Fork 13
/
LinearDecayCorrelationModel.cpp
239 lines (210 loc) · 6.82 KB
/
LinearDecayCorrelationModel.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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
//#############################################################################
//
// FILENAME: LinearDecayCorrelationModel.cpp
//
// CLASSIFICATION: Unclassified
//
// DESCRIPTION:
//
// This class is used to compute the correlation between model
// parameters in a community sensor model (CSM).
//
// LIMITATIONS: None
//
//
// SOFTWARE HISTORY:
// Date Author Comment
// ----------- ------ -------
// 20-Nov-2012 ISK Initial Release.
// 30-Oct-2012 SCM Renamed to LinearDecayCorrelationModel.h
// 17-Dec-2012 BAH Documentation updates.
// 20-Dec-2012 JPK Fixed bug in constructor.
// 18-Feb-2013 JPK Removed getNumCorrelationParameterGroups,
// now provided on base class.
//
// NOTES:
// Refer to LinearDecayCorrelationModel.h for more information.
//#############################################################################
#define CSM_LIBRARY
#include "LinearDecayCorrelationModel.h"
#include "Error.h"
#ifdef IRIXN32
#include "math.h"
#else
#include <cmath>
using std::exp;
using std::fabs;
#endif
namespace csm {
LinearDecayCorrelationModel::LinearDecayCorrelationModel(size_t numSMParams,
size_t numCPGroups)
:
CorrelationModel ("LinearDecayCorrelation",
numCPGroups),
theGroupMapping (numSMParams, -1),
theCorrParams (numCPGroups)
{}
LinearDecayCorrelationModel::~LinearDecayCorrelationModel()
{
}
size_t LinearDecayCorrelationModel::getNumSensorModelParameters() const
{
return theGroupMapping.size();
}
int LinearDecayCorrelationModel::getCorrelationParameterGroup(size_t smParamIndex) const
{
// make sure the index falls within the acceptable range
checkSensorModelParameterIndex(smParamIndex, "getCorrelationParameterGroup");
// return the correlation parameter group index by reference
return theGroupMapping[smParamIndex];
}
void LinearDecayCorrelationModel::setCorrelationParameterGroup(
size_t smParamIndex,
size_t cpGroupIndex)
{
// make sure the indices fall within the acceptable ranges
checkSensorModelParameterIndex(smParamIndex, "setCorrelationParameterGroup");
checkParameterGroupIndex(cpGroupIndex, "setCorrelationParameterGroup");
// set the group index for the given model parameter
theGroupMapping[smParamIndex] = cpGroupIndex;
}
void LinearDecayCorrelationModel::setCorrelationGroupParameters(
size_t cpGroupIndex,
const std::vector<double>& initialCorrsPerSegment,
const std::vector<double>& timesPerSegment)
{
setCorrelationGroupParameters(
cpGroupIndex, Parameters(initialCorrsPerSegment, timesPerSegment) );
}
void LinearDecayCorrelationModel::setCorrelationGroupParameters(
size_t cpGroupIndex,
const Parameters& params)
{
static const char* const MODULE =
"csm::LinearDecayCorrelationModel::setCorrelationGroupParameters";
// make sure the index falls within the acceptable range
checkParameterGroupIndex(cpGroupIndex, "setCorrelationGroupParameters");
// make sure the values of each correlation model parameter
// fall within acceptable ranges
size_t size = params.theInitialCorrsPerSegment.size();
if (size != params.theTimesPerSegment.size())
{
throw Error(
Error::BOUNDS,
"Must have equal number of correlations and times.",
MODULE);
}
double corr, prevCorr;
double time, prevTime;
if (size > 1)
{
for(size_t i = 0; i < size; ++i)
{
corr = params.theInitialCorrsPerSegment[i];
time = params.theTimesPerSegment[i];
if (corr < 0.0 || corr > 1.0)
{
throw Error(
Error::BOUNDS,
"Correlation must be in range [0..1].",
MODULE);
}
if (i > 0)
{
prevCorr = params.theInitialCorrsPerSegment[i-1];
prevTime = params.theTimesPerSegment[i-1];
if (corr > prevCorr)
{
throw Error(
Error::BOUNDS,
"Correlation must be monotomically decreasing.",
MODULE);
}
if (time < prevTime)
{
throw Error(
Error::BOUNDS,
"Time must be monotomically increasing.",
MODULE);
}
}
}
}
// store the correlation parameter values
theCorrParams[cpGroupIndex] = params;
}
double LinearDecayCorrelationModel::getCorrelationCoefficient(
size_t cpGroupIndex,
double deltaTime) const
{
// make sure the index falls within the acceptable range
checkParameterGroupIndex(cpGroupIndex, "getCorrelationCoefficient");
// compute the value of the correlation coefficient
const Parameters& cp = theCorrParams[cpGroupIndex];
const size_t size = cp.theInitialCorrsPerSegment.size();
const double adt = fabs(deltaTime);
double prevCorr = cp.theInitialCorrsPerSegment[0];
double prevTime = cp.theTimesPerSegment[0];
double correlation = prevCorr;
for(size_t s = 1; s < size; ++s)
{
const double corr = cp.theInitialCorrsPerSegment[s];
const double time = cp.theTimesPerSegment[s];
if (adt <= time)
{
if (time - prevTime != 0.0)
{
correlation =
prevCorr +
(adt - prevTime) / (time - prevTime) * (corr - prevCorr);
}
break;
}
prevCorr = corr;
prevTime = time;
correlation = prevCorr;
}
// if necessary, clamp the coefficient value to the acceptable range
if (correlation < 0.0)
{
correlation = 0.0;
}
else if (correlation > 1.0)
{
correlation = 1.0;
}
return correlation;
}
const LinearDecayCorrelationModel::Parameters&
LinearDecayCorrelationModel::getCorrelationGroupParameters(
size_t cpGroupIndex) const
{
// make sure the index falls within the acceptable range
checkParameterGroupIndex(cpGroupIndex, "getCorrelationGroupParameters");
return theCorrParams[cpGroupIndex];
}
void LinearDecayCorrelationModel::checkSensorModelParameterIndex(
size_t smParamIndex,
const std::string& functionName) const
{
if (smParamIndex >= theGroupMapping.size())
{
throw Error(
Error::INDEX_OUT_OF_RANGE,
"Sensor model parameter index is out of range.",
"csm::LinearDecayCorrelationModel::" + functionName);
}
}
void LinearDecayCorrelationModel::checkParameterGroupIndex(
size_t groupIndex,
const std::string& functionName) const
{
if (groupIndex >= theCorrParams.size())
{
throw Error(
Error::INDEX_OUT_OF_RANGE,
"Correlation parameter group index is out of range.",
"csm::LinearDecayCorrelationModel::" + functionName);
}
}
} // namespace csm