Move HammingNumber to its own class for reuse

This commit is contained in:
30hours 2023-12-19 09:36:38 +00:00
parent db92616481
commit 7025854db8
6 changed files with 80 additions and 45 deletions

View file

@ -28,6 +28,7 @@ add_executable(blah2
${PROJECT_SOURCE_DIR}/process/detection/Centroid.cpp
${PROJECT_SOURCE_DIR}/process/detection/Interpolate.cpp
${PROJECT_SOURCE_DIR}/process/spectrum/SpectrumAnalyser.cpp
${PROJECT_SOURCE_DIR}/process/meta/HammingNumber.cpp
${PROJECT_SOURCE_DIR}/data/IqData.cpp
${PROJECT_SOURCE_DIR}/data/Map.cpp
${PROJECT_SOURCE_DIR}/data/Detection.cpp
@ -74,6 +75,7 @@ include_directories("${PROJECT_SOURCE_DIR}/process/ambiguity/")
include_directories("${PROJECT_SOURCE_DIR}/process/clutter/")
include_directories("${PROJECT_SOURCE_DIR}/process/detection/")
include_directories("${PROJECT_SOURCE_DIR}/process/spectrum/")
include_directories("${PROJECT_SOURCE_DIR}/process/meta/")
include_directories("${PROJECT_SOURCE_DIR}/data/")
include_directories("${PROJECT_SOURCE_DIR}/data/meta/")
@ -82,6 +84,7 @@ add_executable(testAmbiguity
${PROJECT_TEST_DIR}/unit/process/ambiguity/TestAmbiguity.cpp
${PROJECT_SOURCE_DIR}/data/IqData.cpp
${PROJECT_SOURCE_DIR}/data/Map.cpp
${PROJECT_SOURCE_DIR}/process/ambiguity/Ambiguity.cpp)
${PROJECT_SOURCE_DIR}/process/ambiguity/Ambiguity.cpp
${PROJECT_SOURCE_DIR}/process/meta/HammingNumber.cpp)
target_link_libraries(testAmbiguity catch2 fftw3 fftw3_threads)
set_target_properties(testAmbiguity PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_TEST_DIR}")

View file

@ -183,45 +183,6 @@ Map<std::complex<double>> *Ambiguity::process(IqData *x, IqData *y)
return map_.get();
}
/**
* @brief Hamming number generator
*
* @author Nigel Galloway
* @cite https://rosettacode.org/wiki/Hamming_numbers
* @todo Can this be done with constexpr???
*/
class HammingGenerator {
private:
std::vector<unsigned int> _H, _hp, _hv, _x;
public:
bool operator!=(const HammingGenerator &other) const { return true; }
HammingGenerator begin() const { return *this; }
HammingGenerator end() const { return *this; }
unsigned int operator*() const { return _x.back(); }
HammingGenerator(const std::vector<unsigned int> &pfs) : _H(pfs), _hp(pfs.size(), 0), _hv({pfs}), _x({1}) {}
const HammingGenerator &operator++()
{
for (int i = 0; i < _H.size(); i++)
for (; _hv[i] <= _x.back(); _hv[i] = _x[++_hp[i]] * _H[i])
;
_x.push_back(_hv[0]);
for (int i = 1; i < _H.size(); i++)
if (_hv[i] < _x.back())
_x.back() = _hv[i];
return *this;
}
};
uint32_t next_hamming(uint32_t value) {
for (auto i : HammingGenerator({2,3,5})) {
if (i > value) {
return i;
}
}
return 0;
}
std::ostream& operator<<(std::ostream& str, const Ambiguity::PerformanceStats& stats) {
return str << "Total time: " << stats.process_time_ms << "ms\n" <<
"Range FFT time: " << stats.range_fft_time_ms << "ms\n" <<

View file

@ -10,6 +10,7 @@
#include <IqData.h>
#include <Map.h>
#include <HammingNumber.h>
#include <stdint.h>
#include <fftw3.h>
#include <memory>
@ -126,9 +127,4 @@ private:
PerformanceStats latest_performance_;
};
/// @brief Calculate the next 5-smooth Hamming Number larger than value
/// @param value Value to round
/// @return value rounded to Hamming number
uint32_t next_hamming(uint32_t value);
std::ostream& operator<<(std::ostream& str, const Ambiguity::PerformanceStats& stats);

View file

@ -0,0 +1,40 @@
#include "HammingNumber.h"
bool HammingNumber::operator!=(const HammingNumber &other) const {
return true;
}
HammingNumber HammingNumber::begin() const {
return *this;
}
HammingNumber HammingNumber::end() const {
return *this;
}
unsigned int HammingNumber::operator*() const {
return _x.back();
}
HammingNumber::HammingNumber(const std::vector<unsigned int> &pfs)
: _H(pfs), _hp(pfs.size(), 0), _hv({pfs}), _x({1}) {}
const HammingNumber &HammingNumber::operator++() {
for (int i = 0; i < _H.size(); i++)
for (; _hv[i] <= _x.back(); _hv[i] = _x[++_hp[i]] * _H[i])
;
_x.push_back(_hv[0]);
for (int i = 1; i < _H.size(); i++)
if (_hv[i] < _x.back())
_x.back() = _hv[i];
return *this;
}
uint32_t next_hamming(uint32_t value) {
for (auto i : HammingNumber({2, 3, 5})) {
if (i > value) {
return i;
}
}
return 0;
}

View file

@ -0,0 +1,34 @@
/// @file HammingNumber.h
/// @class HammingNumber
/// @brief Hamming number generator
/// @author Nigel Galloway
/// @cite https://rosettacode.org/wiki/Hamming_numbers
/// @todo Can this be done with constexpr???
#ifndef HAMMING_GENERATOR_H
#define HAMMING_GENERATOR_H
#include <vector>
#include <stdint.h>
class HammingNumber
{
private:
std::vector<unsigned int> _H, _hp, _hv, _x;
public:
bool operator!=(const HammingNumber &other) const;
HammingNumber begin() const;
HammingNumber end() const;
unsigned int operator*() const;
HammingNumber(const std::vector<unsigned int> &pfs);
const HammingNumber &operator++();
};
/// @brief Calculate the next 5-smooth Hamming Number larger than value
/// @param value Value to round
/// @return value rounded to Hamming number
uint32_t next_hamming(uint32_t value);
#endif

View file

@ -4,6 +4,7 @@
/// @details Simple decimate and FFT on CPI IQ data for frequency spectrum.
/// @author 30hours
/// @todo Potentially create k spectrum plots from sub-CPIs.
/// @todo FFT with HammingNumber class.
#ifndef SPECTRUMANALYSER_H
#define SPECTRUMANALYSER_H