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