Commit 2623b317 authored by Purves, Murray's avatar Purves, Murray
Browse files

Refactored interpolation routines to accept floats or doubles.

Further work would be required for ints
parent 422ab48f
......@@ -18,12 +18,12 @@ namespace radix
* angles in degrees)
* @param missingValue The value which indicates that the value is missing
*/
std::vector<float> interpolateValues(
const std::vector<float> &baseValues,
const std::vector<float> &valuesToInterpolate, const bool circular,
const float missingValue)
template <typename T>
std::vector<T> interpolateValues(const std::vector<T> &baseValues,
const std::vector<T> &valuesToInterpolate,
const bool circular, const T missingValue)
{
std::vector<float> interpolatedValues = valuesToInterpolate;
std::vector<T> interpolatedValues = valuesToInterpolate;
// Ensure pressure and other vector are same length for interpolation
if (baseValues.size() != valuesToInterpolate.size())
......@@ -31,17 +31,17 @@ std::vector<float> interpolateValues(
radix_line("Error! Pressure vector is not same size ("
<< baseValues.size() << ") as vector to interpolate ("
<< valuesToInterpolate.size() << ") - can't use to interpolate");
return std::vector<float>();
return std::vector<T>();
}
// Ensure we have no missing values in the pressure dataset
for (float pressure : baseValues)
for (T pressure : baseValues)
{
if (pressure == missingValue)
{
radix_line("Error! Base vector contains missing ("
<< missingValue << ") values - can't use to interpolate");
return std::vector<float>();
return std::vector<T>();
}
}
......@@ -90,8 +90,8 @@ std::vector<float> interpolateValues(
// Interpolate between the two good values
for (size_t j = lastGood + 1; j < nextGood; ++j)
{
float lastGoodValue = valuesToInterpolate[lastGood],
nextGoodValue = valuesToInterpolate[nextGood];
T lastGoodValue = valuesToInterpolate[lastGood],
nextGoodValue = valuesToInterpolate[nextGood];
if (circular && fabs(lastGoodValue - nextGoodValue) > 180.0)
{
......@@ -124,6 +124,14 @@ std::vector<float> interpolateValues(
return interpolatedValues;
}
template std::vector<float> interpolateValues<float>(
const std::vector<float> &baseValues,
const std::vector<float> &valuesToInterpolate, const bool circular,
const float missingValue);
template std::vector<double> interpolateValues<double>(
const std::vector<double> &baseValues,
const std::vector<double> &valuesToInterpolate, const bool circular,
const double missingValue);
/**
* @brief interpolateToOtherBaseValues
......@@ -134,25 +142,25 @@ std::vector<float> interpolateValues(
* @param missingValues
* @return
*/
std::vector<float> interpolateToOtherBaseValues(
const std::vector<float> &baseValues,
const std::vector<float> &newBaseValues,
const std::vector<float> &valuesToInterpolate, const bool circular,
const float missingValues)
template <typename T>
std::vector<T> interpolateToOtherBaseValues(
const std::vector<T> &baseValues, const std::vector<T> &newBaseValues,
const std::vector<T> &valuesToInterpolate, const bool circular,
const T missingValues)
{
std::vector<float> finalInterpolatedValues(newBaseValues.size());
std::vector<T> finalInterpolatedValues(newBaseValues.size());
radix_line("Interpolating values to new base values");
// First interpolate across the existing data to ensure there are no missing
radix_line(" Initial interpolation to remove missing values in input data");
std::vector<float> initialInterpolatedValues = interpolateValues(
std::vector<T> initialInterpolatedValues = interpolateValues(
baseValues, valuesToInterpolate, circular, missingValues);
// If this fails, we have to fail this one too
if (initialInterpolatedValues.size() == 0)
{
radix_line("Initial interpolation failed - returning empty vector");
return std::vector<float>();
return std::vector<T>();
}
radix_line(" Initial interpolation complete");
......@@ -192,8 +200,8 @@ std::vector<float> interpolateToOtherBaseValues(
}
// Interpolate between these values
float lastGoodValue = initialInterpolatedValues[lowerBaseIndex],
nextGoodValue = initialInterpolatedValues[higherBaseIndex];
T lastGoodValue = initialInterpolatedValues[lowerBaseIndex],
nextGoodValue = initialInterpolatedValues[higherBaseIndex];
if (circular && fabs(lastGoodValue - nextGoodValue) > 180.0)
{
......@@ -226,5 +234,15 @@ std::vector<float> interpolateToOtherBaseValues(
return finalInterpolatedValues;
}
template std::vector<float> interpolateToOtherBaseValues<float>(
const std::vector<float> &baseValues,
const std::vector<float> &newBaseValues,
const std::vector<float> &valuesToInterpolate, const bool circular,
const float missingValues);
template std::vector<double> interpolateToOtherBaseValues<double>(
const std::vector<double> &baseValues,
const std::vector<double> &newBaseValues,
const std::vector<double> &valuesToInterpolate, const bool circular,
const double missingValues);
} // namespace radix
......@@ -11,16 +11,16 @@
namespace radix
{
std::vector<float> RADIX_PUBLIC interpolateValues(
const std::vector<float> &baseValues,
const std::vector<float> &valuesToInterpolate, const bool circular = false,
const float missingValue = -9999.f);
template <typename T>
extern std::vector<T> RADIX_PUBLIC interpolateValues(
const std::vector<T> &baseValues, const std::vector<T> &valuesToInterpolate,
const bool circular = false, const T missingValue = -9999.f);
std::vector<float> RADIX_PUBLIC interpolateToOtherBaseValues(
const std::vector<float> &baseValues,
const std::vector<float> &newBaseValues,
const std::vector<float> &valuesToInterpolate, const bool circular = false,
const float missingValues = -9999.f);
template <typename T>
std::vector<T> RADIX_PUBLIC interpolateToOtherBaseValues(
const std::vector<T> &baseValues, const std::vector<T> &newBaseValues,
const std::vector<T> &valuesToInterpolate, const bool circular = false,
const T missingValues = -9999.f);
} // namespace radix
......
......@@ -18,7 +18,7 @@ TEST(Interpolate, InternalInterpolation)
std::vector<float> testValues1 =
interpolateValues(baseValues1, interpValues1);
ASSERT_EQ(expectValues1.size(), testValues1.size());
for (int i = 0; i < testValues1.size(); ++i)
for (size_t i = 0; i < testValues1.size(); ++i)
{
EXPECT_NEAR(expectValues1[i], testValues1[i], expectValues1[i] * tolerance);
}
......@@ -44,12 +44,33 @@ TEST(Interpolate, InternalInterpolation)
std::vector<float> testValues3 =
interpolateValues(baseValues3, interpValues3, false, missingValue);
ASSERT_EQ(expectValues3.size(), testValues3.size());
for (int i = 0; i < testValues3.size(); ++i)
for (size_t i = 0; i < testValues3.size(); ++i)
{
EXPECT_NEAR(expectValues3[i], testValues3[i], expectValues3[i] * tolerance);
}
}
TEST(Interpolate, Doubles)
{
double missingValue = -9999.0;
double tolerance = 0.0001;
std::vector<double> baseValues1{5.0, 10.0, 20.0, 30.0, 40.0,
50.0, 60.0, 70.0, 75.0};
std::vector<double> interpValues1{missingValue, 1.0, missingValue,
3.0, missingValue, 6.0,
missingValue, 1.0, missingValue};
std::vector<double> expectValues1{1.0, 1.0, 2.0, 3.0, 4.5,
6.0, 3.5, 1.0, 1.0};
std::vector<double> testValues1 =
interpolateValues(baseValues1, interpValues1);
ASSERT_EQ(expectValues1.size(), testValues1.size());
for (size_t i = 0; i < testValues1.size(); ++i)
{
EXPECT_NEAR(expectValues1[i], testValues1[i], expectValues1[i] * tolerance);
}
}
TEST(Interpolate, CircularInterpolation)
{
float missingValue = 713.3;
......@@ -62,7 +83,7 @@ TEST(Interpolate, CircularInterpolation)
std::vector<float> testValues1 =
interpolateValues(baseValues1, interpValues1, true, missingValue);
ASSERT_EQ(expectValues1.size(), testValues1.size());
for (int i = 0; i < testValues1.size(); ++i)
for (size_t i = 0; i < testValues1.size(); ++i)
{
EXPECT_NEAR(expectValues1[i], testValues1[i], expectValues1[i] * tolerance);
}
......@@ -79,7 +100,7 @@ TEST(Interpolate, FillInBeginning)
std::vector<float> testValues1 =
interpolateValues(baseValues1, interpValues1);
ASSERT_EQ(expectValues1.size(), testValues1.size());
for (int i = 0; i < testValues1.size(); ++i)
for (size_t i = 0; i < testValues1.size(); ++i)
{
EXPECT_NEAR(expectValues1[i], testValues1[i], expectValues1[i] * tolerance);
}
......@@ -96,7 +117,7 @@ TEST(Interpolate, FillInEnd)
std::vector<float> testValues1 =
interpolateValues(baseValues1, interpValues1);
ASSERT_EQ(expectValues1.size(), testValues1.size());
for (int i = 0; i < testValues1.size(); ++i)
for (size_t i = 0; i < testValues1.size(); ++i)
{
EXPECT_NEAR(expectValues1[i], testValues1[i], expectValues1[i] * tolerance);
}
......@@ -114,7 +135,7 @@ TEST(Interpolate, NewBaseValues)
std::vector<float> testValues1 =
interpolateToOtherBaseValues(baseValues1, newBaseValues1, interpValues1);
ASSERT_EQ(expectValues1.size(), testValues1.size());
for (int i = 0; i < testValues1.size(); ++i)
for (size_t i = 0; i < testValues1.size(); ++i)
{
EXPECT_NEAR(expectValues1[i], testValues1[i], expectValues1[i] * tolerance);
}
......@@ -123,7 +144,7 @@ TEST(Interpolate, NewBaseValues)
std::vector<float> testValuesMissing = interpolateToOtherBaseValues(
baseValues1, newBaseValues1, interpValuesMissing);
ASSERT_EQ(expectValues1.size(), testValuesMissing.size());
for (int i = 0; i < testValuesMissing.size(); ++i)
for (size_t i = 0; i < testValuesMissing.size(); ++i)
{
EXPECT_NEAR(expectValues1[i], testValuesMissing[i],
expectValues1[i] * tolerance);
......@@ -144,3 +165,31 @@ TEST(Interpolate, NewBaseValues)
// tolerance);
// }
}
TEST(Interpolate, NewBaseValuesDoubles)
{
double missingValue = -9999.0;
double tolerance = 0.0001;
std::vector<double> baseValues1{1000.0, 2000.0, 3000.0};
std::vector<double> newBaseValues1{500.0, 1500.0, 2500.0, 3500.0};
std::vector<double> interpValues1{10.5, 20.5, 30.5};
std::vector<double> expectValues1{10.5, 15.5, 25.5, 30.5};
std::vector<double> testValues1 =
interpolateToOtherBaseValues(baseValues1, newBaseValues1, interpValues1);
ASSERT_EQ(expectValues1.size(), testValues1.size());
for (size_t i = 0; i < testValues1.size(); ++i)
{
EXPECT_NEAR(expectValues1[i], testValues1[i], expectValues1[i] * tolerance);
}
std::vector<double> interpValuesMissing{10.5, missingValue, 30.5};
std::vector<double> testValuesMissing = interpolateToOtherBaseValues(
baseValues1, newBaseValues1, interpValuesMissing);
ASSERT_EQ(expectValues1.size(), testValuesMissing.size());
for (size_t i = 0; i < testValuesMissing.size(); ++i)
{
EXPECT_NEAR(expectValues1[i], testValuesMissing[i],
expectValues1[i] * tolerance);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment