Skip to content
Snippets Groups Projects
Commit 64888548 authored by pospelov's avatar pospelov
Browse files

Merge branch 'master' of git.jcns.frm2:GISASFW

parents ac5a3bbd 1d6605eb
No related branches found
No related tags found
No related merge requests found
......@@ -21,4 +21,10 @@ public:
OutOfBoundsException(const std::string& message);
};
class ClassInitializationException : public std::runtime_error
{
public:
ClassInitializationException(const std::string& message);
};
#endif // EXCEPTIONS_H
......@@ -3,11 +3,17 @@
#include "NamedVector.h"
#include <map>
class MultiIndex
{
template <class T> friend class OutputData;
public:
std::vector<std::string> getLabels() { return m_labels; }
std::vector<size_t> getCoordinate();
void setCoordinate(std::string label, size_t value);
void incrementCoordinate(std::string label);
void decrementCoordinate(std::string label);
MultiIndex& operator++();
private:
MultiIndex();
......@@ -15,15 +21,19 @@ private:
// Disabling copy constructor and assignment
MultiIndex(const MultiIndex& source);
MultiIndex operator=(const MultiIndex& source);
void updateCurrentCoordinate();
void updateCurrentPosition();
void init(const std::vector<NamedVectorBase*>& value_axes);
void clear();
std::vector<std::string> m_labels;
std::map<std::string, size_t> m_label_index_map;
size_t m_dimension;
size_t m_total_size;
size_t m_current_position;
size_t* m_axis_sizes;
size_t* m_current_coordinate;
std::vector<size_t> m_axis_sizes;
std::vector<size_t> m_current_coordinate;
std::vector<size_t> m_steps;
};
template <class T> class OutputData
......@@ -52,6 +62,7 @@ template <class T> OutputData<T>::OutputData()
: m_dimension(0)
, m_data_size(1)
{
allocate();
}
template <class T> OutputData<T>::~OutputData()
......@@ -69,20 +80,25 @@ template <class T> void OutputData<T>::addAxis(NamedVectorBase* p_new_axis)
++m_dimension;
m_data_size *= p_new_axis->getSize();
m_value_axes.push_back(p_new_axis);
allocate();
}
}
template <class T> MultiIndex& OutputData<T>::getIndex()
template <class T> inline MultiIndex& OutputData<T>::getIndex()
{
allocate();
return m_index;
}
template <class T> inline T& OutputData<T>::currentValue()
{
return m_data_vector[m_index.m_current_position];
}
template <class T> void OutputData<T>::allocate()
{
m_index.init(m_value_axes );
if (m_data_vector.size() != m_data_size)
{
m_index.init(m_value_axes );
m_data_vector.resize(m_data_size);
}
}
......
......@@ -14,3 +14,8 @@ OutOfBoundsException::OutOfBoundsException(const std::string& message)
: std::logic_error(message)
{
}
ClassInitializationException::ClassInitializationException(const std::string &message)
: std::runtime_error(message)
{
}
#include "OutputData.h"
#include "Exceptions.h"
MultiIndex& MultiIndex::operator++()
{
......@@ -13,8 +14,6 @@ MultiIndex::MultiIndex()
: m_dimension(0)
, m_total_size(1)
, m_current_position(0)
, m_axis_sizes(0)
, m_current_coordinate(0)
{
}
......@@ -23,36 +22,103 @@ MultiIndex::~MultiIndex()
clear();
}
std::vector<size_t> MultiIndex::getCoordinate()
{
updateCurrentCoordinate();
return m_current_coordinate;
}
void MultiIndex::updateCurrentCoordinate()
{
size_t remainder = m_current_position;
for (size_t i=0; i<m_dimension; ++i)
{
m_current_coordinate[m_dimension-1-i] = remainder % m_axis_sizes[m_dimension-1-i];
remainder /= m_axis_sizes[m_dimension-1-i];
}
}
void MultiIndex::updateCurrentPosition()
{
m_current_position = 0;
for (size_t i=0; i<m_dimension; ++i)
{
m_current_position += m_current_coordinate[i]*m_steps[i];
}
}
void MultiIndex::setCoordinate(std::string label, size_t value)
{
if (m_label_index_map.count(label) == 0) return;
size_t index = m_label_index_map[label];
if (value >= m_axis_sizes[index])
{
throw OutOfBoundsException("Coordinate value out of bounds!");
}
m_current_coordinate[index] = value;
updateCurrentPosition();
}
void MultiIndex::incrementCoordinate(std::string label)
{
if (m_label_index_map.count(label) == 0) return;
size_t index = m_label_index_map[label];
if (m_current_coordinate[index] < m_axis_sizes[index]-2)
{
++m_current_coordinate[index];
return;
}
throw OutOfBoundsException("Coordinate value out of bounds!");
}
void MultiIndex::decrementCoordinate(std::string label)
{
if (m_label_index_map.count(label) == 0) return;
size_t index = m_label_index_map[label];
if (m_current_coordinate[index] > 1)
{
--m_current_coordinate[index];
return;
}
throw OutOfBoundsException("Coordinate value out of bounds!");
}
void MultiIndex::init(const std::vector<NamedVectorBase*>& value_axes)
{
clear();
m_dimension = value_axes.size();
if (m_dimension==0) return;
m_axis_sizes = new size_t[m_dimension];
m_current_coordinate = new size_t[m_dimension];
m_axis_sizes.resize(m_dimension);
m_current_coordinate.resize(m_dimension);
m_steps.resize(m_dimension);
for (size_t i=0; i<m_dimension; ++i)
{
NamedVectorBase* p_axis = value_axes[i];
if (m_label_index_map.count(p_axis->getName()) != 0)
{
throw ClassInitializationException("Axis labels for OutputData object should be unique!");
}
m_label_index_map[p_axis->getName()] = i;
m_labels.push_back(p_axis->getName());
m_axis_sizes[i] = p_axis->getSize();
m_total_size *= p_axis->getSize();
m_current_coordinate[i] = 0;
}
size_t remaining_size = m_total_size;
for (size_t i=0; i<m_dimension; ++i)
{
m_steps[i] = remaining_size / m_axis_sizes[i];
remaining_size = m_steps[i];
}
}
void MultiIndex::clear()
{
if (m_axis_sizes)
{
delete[] m_axis_sizes;
m_axis_sizes = 0;
}
if (m_current_coordinate)
{
delete[] m_current_coordinate;
m_current_coordinate = 0;
}
m_axis_sizes.clear();
m_current_coordinate.clear();
m_labels.clear();
m_label_index_map.clear();
m_steps.clear();
m_dimension = 0;
m_total_size = 1;
m_current_position = 0;
......
......@@ -12,15 +12,25 @@ protected:
OutputData<int> int_data_0d;
OutputData<float> fl_data_1d;
OutputData<double> db_data_3d;
std::vector<size_t> zero_3d_coordinate;
};
OutputDataTest::OutputDataTest()
{
zero_3d_coordinate.push_back(0);
zero_3d_coordinate.push_back(0);
zero_3d_coordinate.push_back(0);
fl_data_1d.addAxis(new NamedVector<double>("angle", 0.0, 0.1, 20));
db_data_3d.addAxis(new NamedVector<double>("angle", 0.0, 0.1, 20));
db_data_3d.addAxis(new NamedVector<double>("length", 0.0, 0.5, 10));
db_data_3d.addAxis(new NamedVector<int>("index", 10, 1, 10));
MultiIndex &db_data_index = db_data_3d.getIndex();
for (size_t i=0; i<2000; ++i)
{
db_data_3d.currentValue() = (double)i;
++db_data_index;
}
}
OutputDataTest::~OutputDataTest()
......
......@@ -3,7 +3,8 @@ CONFIG += console
CONFIG -= qt
SOURCES += main.cpp \
../../Core/src/OutputData.cpp
../../Core/src/OutputData.cpp \
../../Core/src/Exceptions.cpp
INCLUDEPATH += ../../ThirdParty/gtest-1.6.0/include ../../Core/inc
......@@ -12,3 +13,5 @@ LIBS += -L../../ThirdParty/Qt_gtest -lgtest
HEADERS += \
NamedVectorTest.h \
OutputDataTest.h
OBJECTS_DIR = obj
......@@ -23,22 +23,27 @@ TEST_F(NamedVectorTest, ExtendedConstructor)
EXPECT_DOUBLE_EQ(9.9, doubleLengthVector[99]);
}
TEST_F(OutputDataTest, EmptyAfterConstruction)
TEST_F(OutputDataTest, SingleElementAfterConstruction)
{
EXPECT_EQ((size_t)0, int_data_0d.getAllocatedSize());
EXPECT_EQ((size_t)0, fl_data_1d.getAllocatedSize());
EXPECT_EQ((size_t)1, int_data_0d.getAllocatedSize());
}
TEST_F(OutputDataTest, SizeAfterAllocation)
TEST_F(OutputDataTest, SizeAfterAddingAxes)
{
MultiIndex &index_int_data = int_data_0d.getIndex();
MultiIndex &index_fl_data = fl_data_1d.getIndex();
MultiIndex &index_db_data = db_data_3d.getIndex();
EXPECT_EQ((size_t)1, int_data_0d.getAllocatedSize());
EXPECT_EQ((size_t)20, fl_data_1d.getAllocatedSize());
EXPECT_EQ((size_t)2000, db_data_3d.getAllocatedSize());
}
TEST_F(OutputDataTest, DataInitialization)
{
MultiIndex &db_data_index = db_data_3d.getIndex();
db_data_index.setCoordinate("angle", 11);
db_data_index.setCoordinate("length", 4);
db_data_index.setCoordinate("index", 3);
EXPECT_DOUBLE_EQ((double)1143, db_data_3d.currentValue());
}
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment