##// END OF EJS Templates
Creates ctor for two-dimensional ArrayData
Alexandre Leroux -
r501:9f279df280f0
parent child
Show More
@@ -1,156 +1,186
1 #ifndef SCIQLOP_ARRAYDATA_H
1 #ifndef SCIQLOP_ARRAYDATA_H
2 #define SCIQLOP_ARRAYDATA_H
2 #define SCIQLOP_ARRAYDATA_H
3
3
4 #include <QReadLocker>
4 #include <QReadLocker>
5 #include <QReadWriteLock>
5 #include <QReadWriteLock>
6 #include <QVector>
6 #include <QVector>
7
7
8 #include <memory>
8 #include <memory>
9
9
10 /**
10 /**
11 * @brief The ArrayData class represents a dataset for a data series.
11 * @brief The ArrayData class represents a dataset for a data series.
12 *
12 *
13 * A dataset can be unidimensional or two-dimensional. This property is determined by the Dim
13 * A dataset can be unidimensional or two-dimensional. This property is determined by the Dim
14 * template-parameter.
14 * template-parameter. In a case of a two-dimensional dataset, each dataset component has the same
15 * number of values
15 *
16 *
16 * @tparam Dim the dimension of the ArrayData (one or two)
17 * @tparam Dim the dimension of the ArrayData (one or two)
17 * @sa IDataSeries
18 * @sa IDataSeries
18 */
19 */
19 template <int Dim>
20 template <int Dim>
20 class ArrayData {
21 class ArrayData {
21 public:
22 public:
22 /**
23 /**
23 * Ctor for a unidimensional ArrayData
24 * Ctor for a unidimensional ArrayData
24 * @param data the data the ArrayData will hold
25 * @param data the data the ArrayData will hold
25 */
26 */
26 template <int D = Dim, typename = std::enable_if_t<D == 1> >
27 template <int D = Dim, typename = std::enable_if_t<D == 1> >
27 explicit ArrayData(QVector<double> data) : m_Data{1, QVector<double>{}}
28 explicit ArrayData(QVector<double> data) : m_Data{1, QVector<double>{}}
28 {
29 {
29 m_Data[0] = std::move(data);
30 m_Data[0] = std::move(data);
30 }
31 }
31
32
33 /**
34 * Ctor for a two-dimensional ArrayData. The number of components (number of vectors) must be
35 * greater than 2 and each component must have the same number of values
36 * @param data the data the ArrayData will hold
37 * @throws std::invalid_argument if the number of components is less than 2
38 * @remarks if the number of values is not the same for each component, no value is set
39 */
40 template <int D = Dim, typename = std::enable_if_t<D == 2> >
41 explicit ArrayData(QVector<QVector<double> > data)
42 {
43 auto nbComponents = data.size();
44 if (nbComponents < 2) {
45 throw std::invalid_argument{
46 QString{"A multidimensional ArrayData must have at least 2 components (found: %1"}
47 .arg(data.size())
48 .toStdString()};
49 }
50
51 auto nbValues = data.front().size();
52 if (std::all_of(data.cbegin(), data.cend(), [nbValues](const auto &component) {
53 return component.size() == nbValues;
54 })) {
55 m_Data = std::move(data);
56 }
57 else {
58 m_Data = QVector<QVector<double> >{nbComponents, QVector<double>{}};
59 }
60 }
61
32 /// Copy ctor
62 /// Copy ctor
33 explicit ArrayData(const ArrayData &other)
63 explicit ArrayData(const ArrayData &other)
34 {
64 {
35 QReadLocker otherLocker{&other.m_Lock};
65 QReadLocker otherLocker{&other.m_Lock};
36 m_Data = other.m_Data;
66 m_Data = other.m_Data;
37 }
67 }
38
68
39 /**
69 /**
40 * @return the data at a specified index
70 * @return the data at a specified index
41 * @remarks index must be a valid position
71 * @remarks index must be a valid position
42 * @remarks this method is only available for a unidimensional ArrayData
72 * @remarks this method is only available for a unidimensional ArrayData
43 */
73 */
44 template <int D = Dim, typename = std::enable_if_t<D == 1> >
74 template <int D = Dim, typename = std::enable_if_t<D == 1> >
45 double at(int index) const noexcept
75 double at(int index) const noexcept
46 {
76 {
47 QReadLocker locker{&m_Lock};
77 QReadLocker locker{&m_Lock};
48 return m_Data[0].at(index);
78 return m_Data[0].at(index);
49 }
79 }
50
80
51 /**
81 /**
52 * Sets a data at a specified index. The index has to be valid to be effective
82 * Sets a data at a specified index. The index has to be valid to be effective
53 * @param index the index to which the data will be set
83 * @param index the index to which the data will be set
54 * @param data the data to set
84 * @param data the data to set
55 * @remarks this method is only available for a unidimensional ArrayData
85 * @remarks this method is only available for a unidimensional ArrayData
56 */
86 */
57 template <int D = Dim, typename = std::enable_if_t<D == 1> >
87 template <int D = Dim, typename = std::enable_if_t<D == 1> >
58 void setData(int index, double data) noexcept
88 void setData(int index, double data) noexcept
59 {
89 {
60 QWriteLocker locker{&m_Lock};
90 QWriteLocker locker{&m_Lock};
61 if (index >= 0 && index < m_Data.at(0).size()) {
91 if (index >= 0 && index < m_Data.at(0).size()) {
62 m_Data[0].replace(index, data);
92 m_Data[0].replace(index, data);
63 }
93 }
64 }
94 }
65
95
66 /**
96 /**
67 * @return the data as a vector
97 * @return the data as a vector
68 * @remarks this method is only available for a unidimensional ArrayData
98 * @remarks this method is only available for a unidimensional ArrayData
69 */
99 */
70 template <int D = Dim, typename = std::enable_if_t<D == 1> >
100 template <int D = Dim, typename = std::enable_if_t<D == 1> >
71 QVector<double> data() const noexcept
101 QVector<double> data() const noexcept
72 {
102 {
73 QReadLocker locker{&m_Lock};
103 QReadLocker locker{&m_Lock};
74 return m_Data[0];
104 return m_Data[0];
75 }
105 }
76
106
77 /**
107 /**
78 * @return the data as a vector, as a const reference
108 * @return the data as a vector, as a const reference
79 * @remarks this method is only available for a unidimensional ArrayData
109 * @remarks this method is only available for a unidimensional ArrayData
80 */
110 */
81 template <int D = Dim, typename = std::enable_if_t<D == 1> >
111 template <int D = Dim, typename = std::enable_if_t<D == 1> >
82 const QVector<double> &cdata() const noexcept
112 const QVector<double> &cdata() const noexcept
83 {
113 {
84 QReadLocker locker{&m_Lock};
114 QReadLocker locker{&m_Lock};
85 return m_Data.at(0);
115 return m_Data.at(0);
86 }
116 }
87
117
88 /**
118 /**
89 * Merges into the array data an other array data
119 * Merges into the array data an other array data
90 * @param other the array data to merge with
120 * @param other the array data to merge with
91 * @param prepend if true, the other array data is inserted at the beginning, otherwise it is
121 * @param prepend if true, the other array data is inserted at the beginning, otherwise it is
92 * inserted at the end
122 * inserted at the end
93 * @remarks this method is only available for a unidimensional ArrayData
123 * @remarks this method is only available for a unidimensional ArrayData
94 */
124 */
95 template <int D = Dim, typename = std::enable_if_t<D == 1> >
125 template <int D = Dim, typename = std::enable_if_t<D == 1> >
96 void add(const ArrayData<1> &other, bool prepend = false)
126 void add(const ArrayData<1> &other, bool prepend = false)
97 {
127 {
98 QWriteLocker locker{&m_Lock};
128 QWriteLocker locker{&m_Lock};
99 if (!m_Data.empty()) {
129 if (!m_Data.empty()) {
100 QReadLocker otherLocker{&other.m_Lock};
130 QReadLocker otherLocker{&other.m_Lock};
101
131
102 if (prepend) {
132 if (prepend) {
103 const auto &otherData = other.data();
133 const auto &otherData = other.data();
104 const auto otherDataSize = otherData.size();
134 const auto otherDataSize = otherData.size();
105
135
106 auto &data = m_Data[0];
136 auto &data = m_Data[0];
107 data.insert(data.begin(), otherDataSize, 0.);
137 data.insert(data.begin(), otherDataSize, 0.);
108
138
109 for (auto i = 0; i < otherDataSize; ++i) {
139 for (auto i = 0; i < otherDataSize; ++i) {
110 data.replace(i, otherData.at(i));
140 data.replace(i, otherData.at(i));
111 }
141 }
112 }
142 }
113 else {
143 else {
114 m_Data[0] += other.data();
144 m_Data[0] += other.data();
115 }
145 }
116 }
146 }
117 }
147 }
118
148
119 template <int D = Dim, typename = std::enable_if_t<D == 1> >
149 template <int D = Dim, typename = std::enable_if_t<D == 1> >
120 int size() const
150 int size() const
121 {
151 {
122 QReadLocker locker{&m_Lock};
152 QReadLocker locker{&m_Lock};
123 return m_Data[0].size();
153 return m_Data[0].size();
124 }
154 }
125
155
126 template <int D = Dim, typename = std::enable_if_t<D == 1> >
156 template <int D = Dim, typename = std::enable_if_t<D == 1> >
127 std::shared_ptr<ArrayData<Dim> > sort(const std::vector<int> sortPermutation)
157 std::shared_ptr<ArrayData<Dim> > sort(const std::vector<int> sortPermutation)
128 {
158 {
129 QReadLocker locker{&m_Lock};
159 QReadLocker locker{&m_Lock};
130
160
131 const auto &data = m_Data.at(0);
161 const auto &data = m_Data.at(0);
132
162
133 // Inits result
163 // Inits result
134 auto sortedData = QVector<double>{};
164 auto sortedData = QVector<double>{};
135 sortedData.resize(data.size());
165 sortedData.resize(data.size());
136
166
137 std::transform(sortPermutation.cbegin(), sortPermutation.cend(), sortedData.begin(),
167 std::transform(sortPermutation.cbegin(), sortPermutation.cend(), sortedData.begin(),
138 [&data](int i) { return data[i]; });
168 [&data](int i) { return data[i]; });
139
169
140 return std::make_shared<ArrayData<Dim> >(std::move(sortedData));
170 return std::make_shared<ArrayData<Dim> >(std::move(sortedData));
141 }
171 }
142
172
143 template <int D = Dim, typename = std::enable_if_t<D == 1> >
173 template <int D = Dim, typename = std::enable_if_t<D == 1> >
144 void clear()
174 void clear()
145 {
175 {
146 QWriteLocker locker{&m_Lock};
176 QWriteLocker locker{&m_Lock};
147 m_Data[0].clear();
177 m_Data[0].clear();
148 }
178 }
149
179
150
180
151 private:
181 private:
152 QVector<QVector<double> > m_Data;
182 QVector<QVector<double> > m_Data;
153 mutable QReadWriteLock m_Lock;
183 mutable QReadWriteLock m_Lock;
154 };
184 };
155
185
156 #endif // SCIQLOP_ARRAYDATA_H
186 #endif // SCIQLOP_ARRAYDATA_H
General Comments 0
You need to be logged in to leave comments. Login now