Skip to content

Commit

Permalink
using AlmostEqualRelative
Browse files Browse the repository at this point in the history
  • Loading branch information
cheroy-ntia committed Nov 25, 2024
1 parent 0f9ab36 commit d1ec139
Show file tree
Hide file tree
Showing 11 changed files with 3,737 additions and 3,681 deletions.
2 changes: 2 additions & 0 deletions include/ITS.Propagation.LFMF/LFMF.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#define __ITS_PROPAGATION_LFMF_LFMF_H__

#include <complex>
#include <cfloat>

#include "LFMFConfig.h"
#include "ReturnCodes.h"
Expand Down Expand Up @@ -99,6 +100,7 @@ complex<double> Airy(complex<double> Z, int kind, int scaling);
complex<double> WiRoot(int i, complex<double> *DWi, complex<double> q, complex<double> *Wi, int kind, int scaling);
ReturnCode ValidateInput(double h_tx__meter, double h_rx__meter, double f__mhz, double P_tx__watt,
double N_s, double d__km, double epsilon, double sigma, int pol);
bool AlmostEqualRelative(double A, double B, double maxRelDiff = DBL_EPSILON);

} // namespace LFMF
} // namespace Propagation
Expand Down
6 changes: 3 additions & 3 deletions src/Airy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,8 +648,8 @@ complex<double> Airy(complex<double> Z, int kind, int scaling)
// Determine if the data for the center of expansion is exceeded
if (((ZU.real() < -6.5) || (ZU.real() > 7.5) || (ZU.imag() > 6.35))
|| (N >= NQ8)
|| (abs(Z.real()) < 1.0e-9 && abs(Z.imag()) < 1.0e-9)) {
//|| (Z.real() == 0.0 && Z.imag() == 0.0)) {
//|| (Z.real() == 0.0 && Z.imag() == 0.0)) { //Replaced with AlmostEqualRelative
|| (AlmostEqualRelative(Z.real(), 0.0) && AlmostEqualRelative(Z.imag(), 0.0))) {

///////////////////////////////////////////////
// Compute the function by Asymptotic Series //
Expand Down Expand Up @@ -818,7 +818,7 @@ complex<double> Airy(complex<double> Z, int kind, int scaling)

return Ai;

};
}

} // namespace LFMF
} // namespace Propagation
Expand Down
2 changes: 1 addition & 1 deletion src/FlatEarthCurveCorrection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ double FlatEarthCurveCorrection(complex<double> Delta, complex<double> q, double
double E_gw__mVm = abs(fofx*(1.0 + j * k*h_2__km*Delta)*(1.0 + j * k*h_1__km*Delta));

return E_gw__mVm;
};
}

} // namespace LFMF
} // namespace Propagation
Expand Down
24 changes: 24 additions & 0 deletions src/LFMF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,30 @@ ReturnCode LFMF(double h_tx__meter, double h_rx__meter, double f__mhz, double P_
return SUCCESS;
}

/******************************************************************************
*
* Description: Relative epsilon comparisons method
*
* @param[in] A - First double to compare
* @param[in] B - Second double to compare
* @param[in] maxRelDiff - Maximum relative difference
*
* @return equal - if it is equal of the two doubles
*
*****************************************************************************/
bool AlmostEqualRelative(double A, double B, double maxRelDiff) {
// Calculate the difference.
double diff = fabs(A - B);
A = fabs(A);
B = fabs(B);
// Find the largest
double largest = (B > A) ? B : A;

if (diff <= largest * maxRelDiff)
return true;
return false;
}

} // namespace LFMF
} // namespace Propagation
} // namespace ITS
11 changes: 6 additions & 5 deletions src/ResidueSeries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ double ResidueSeries(double k, double h_1__km, double h_2__km, double nu, double

if (i != 0)
{
//if ((GW.real() * GW.real() + GW.imag() * GW.imag()) < 1.0e-16)
//if ((abs((GW * GW).real()) + abs((GW * GW).imag())) < 1.0e-16) // when the ground wave is too small, close to 0
if ((abs((GW * GW).real()) + (abs((GW * GW).imag()))) == 0.0) // when the ground wave is too small, close to 0
return 0; // end the loop and output E = 0
//if ((abs((GW * GW).real()) + (abs((GW * GW).imag()))) == 0.0) // when the ground wave is too small close to 0.
// Replaced with AlmostEqualRelative
if (AlmostEqualRelative((abs((GW * GW).real()) + (abs((GW * GW).imag()))), 0.0)) {
return 0; // end the loop and output E = 0
}
else if (((abs((G / GW).real())) + (abs((G / GW).imag()))) < 0.0005) // when the new G is too small compared to its series sum
{
// when the new G is too small compared to its series sum, it's ok to stop the loop
Expand All @@ -88,7 +89,7 @@ double ResidueSeries(double k, double h_1__km, double h_2__km, double nu, double

return E_gw;

};
}

} // namespace LFMF
} // namespace Propagation
Expand Down
2 changes: 1 addition & 1 deletion src/WiRoot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ complex<double> WiRoot(int i, complex<double> *DWi, complex<double> q, complex<d
};

return tw;
};
}

} // namespace LFMF
} // namespace Propagation
Expand Down
8 changes: 4 additions & 4 deletions src/wofz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,17 +191,17 @@ if (A) {
}
}

if (abs(H) < 1e-9) {
//if (H == 0.0) {
//if (H == 0.0) { // Replaced with AlmostEqualRelative
if (AlmostEqualRelative(H, 0.0)) {
U = FACTOR*RX;
V = FACTOR*RY;
} else {
U = FACTOR*SX;
V = FACTOR*SY;
}

if (abs(YABS) < 1.0e-9) {
//if (YABS == 0.0) {
//if (YABS == 0.0) { // Replaced with AlmostEqualRelative
if (AlmostEqualRelative(YABS, 0.0)) {
U = exp(-XABS*XABS);
}
}
Expand Down
6 changes: 6 additions & 0 deletions tests/LFMFGTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

using namespace ITS::Propagation::LFMF;

#define INF std::numeric_limits<double>::infinity() ///< Infinity in double

/** @struct LFMFInputsAndResult
* struct Inputs and Outputs for LFMF Model
*/
Expand Down Expand Up @@ -38,4 +40,8 @@ void AppendDirectorySep(std::string& str);

std::string GetDirectory(std::string name);

double stringToDouble(std::string s);

void compareDouble(double expected, double actual);

#endif
175 changes: 106 additions & 69 deletions tests/LFMFGTestUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,84 +18,100 @@
*
*****************************************************************************/
std::vector<LFMFInputsAndResult> ReadLFMFInputsAndResult(const std::string &filename) {
std::vector<LFMFInputsAndResult> testData;
std::string dataDir = GetDirectory("data");
std::ifstream file(dataDir + filename);
LFMFInputsAndResult d {}; // struct to store data from a single line of CSV

std::vector<std::vector<std::string>> csvRows = readCSV(file);
if (csvRows.size() <= 1) {
return testData;
}

std::vector<LFMFInputsAndResult> testData;
std::string dataDir = GetDirectory("data");
std::ifstream file(dataDir + filename);
LFMFInputsAndResult d {
}; // struct to store data from a single line of CSV
try {
std::vector<std::vector<std::string>> csvRows = readCSV(file);
if (csvRows.size() <= 1) {
return testData;
}


typedef std::vector<std::vector<std::string> >::size_type row_vec_size_t;
typedef std::vector<std::string>::size_type cell_vec_size_t;

for (row_vec_size_t r = 1; r < csvRows.size(); r++) {
int c = 0;
for (cell_vec_size_t i = 0; i < csvRows[0].size(); i++) {
if (csvRows[0][i] == "h_tx__meter") {
d.h_tx__meter = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "h_rx__meter") {
d.h_rx__meter = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "f__mhz") {
d.f__mhz = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "P_tx__watt") {
d.P_tx__watt = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "N_s") {
d.N_s = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "d__km") {
d.d__km = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "epsilon") {
d.epsilon = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "sigma") {
d.sigma = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "pol") {
d.pol = std::stoi(csvRows[r][i]);
c++;
}
if (r % 100 == 0) {
std::cout << " Test instance: " << r << std::endl;
}
for (cell_vec_size_t i = 0; i < csvRows[0].size(); i++) {
try {
if (csvRows[0][i] == "h_tx__meter") {
d.h_tx__meter = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "h_rx__meter") {
d.h_rx__meter = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "f__mhz") {
d.f__mhz = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "P_tx__watt") {
d.P_tx__watt = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "N_s") {
d.N_s = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "d__km") {
d.d__km = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "epsilon") {
d.epsilon = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "sigma") {
d.sigma = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "pol") {
d.pol = std::stoi(csvRows[r][i]);
c++;
}

if (csvRows[0][i] == "rtn") {
d.expectedReturn = std::stoi(csvRows[r][i]);
}
if (csvRows[0][i] == "A_btl__db") {
d.expectedResult.A_btl__db = std::stod(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "E_dBuVm") {
d.expectedResult.E_dBuVm = std::stod(csvRows[r][i]);
c++;
if (csvRows[0][i] == "rtn") {
d.expectedReturn = std::stoi(csvRows[r][i]);
}
if (csvRows[0][i] == "A_btl__db") {
d.expectedResult.A_btl__db = stringToDouble(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "E_dBuVm") {
d.expectedResult.E_dBuVm = stringToDouble(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "P_rx__dbm") {
d.expectedResult.P_rx__dbm = stringToDouble(csvRows[r][i]);
c++;
}
if (csvRows[0][i] == "method") {
d.expectedResult.method = std::stoi(csvRows[r][i]);
c++;
}
} catch (const char *msg) {

Check warning on line 100 in tests/LFMFGTestUtils.cpp

View workflow job for this annotation

GitHub Actions / windows-latest / CMake 3.21

'msg': unreferenced local variable [D:\a\LFMF\LFMF\build\release\tests\LFMFTest.vcxproj]

Check warning on line 100 in tests/LFMFGTestUtils.cpp

View workflow job for this annotation

GitHub Actions / windows-latest / CMake latest

'msg': unreferenced local variable [D:\a\LFMF\LFMF\build\release\tests\LFMFTest.vcxproj]
// Code to handle the exception
std::cerr << "Error: " << r << ", " << csvRows[r][i]
<< std::endl;
}
}
if (csvRows[0][i] == "P_rx__dbm") {
d.expectedResult.P_rx__dbm = std::stod(csvRows[r][i]);
c++;
if (c == 13) {
testData.push_back(d);
}
if (csvRows[0][i] == "method") {
d.expectedResult.method = std::stoi(csvRows[r][i]);
c++;
}
}
if (c == 13) {
testData.push_back(d);
}

}
} catch (const char *msg) {

Check warning on line 111 in tests/LFMFGTestUtils.cpp

View workflow job for this annotation

GitHub Actions / windows-latest / CMake 3.21

'msg': unreferenced local variable [D:\a\LFMF\LFMF\build\release\tests\LFMFTest.vcxproj]

Check warning on line 111 in tests/LFMFGTestUtils.cpp

View workflow job for this annotation

GitHub Actions / windows-latest / CMake latest

'msg': unreferenced local variable [D:\a\LFMF\LFMF\build\release\tests\LFMFTest.vcxproj]
// Code to handle the exception
std::cerr << "Error: " << std::endl;
}

return testData;
}

Expand Down Expand Up @@ -218,4 +234,25 @@ std::vector<std::vector<std::string>> readCSV(std::istream& in) {
table.push_back(fields);
}
return table;
}
}

double stringToDouble(std::string s) {
if (s == "Inf") {
return INF;
} else if (s == "-Inf") {
return -INF;
} else {
return std::stod(s);
}
}

void compareDouble(double expected, double actual) {
double TOLERANCE = 1.0e-6;
if (expected == INF) {
EXPECT_EQ(INF, actual);
} else if (expected == -INF) {
EXPECT_EQ(-INF, actual);
} else {
EXPECT_NEAR(actual, expected, TOLERANCE);
}
}
Loading

0 comments on commit d1ec139

Please sign in to comment.