Mantid
Loading...
Searching...
No Matches
Utils.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#pragma once
8
9#include "MantidKernel/DllConfig.h"
10#include <cmath>
11#include <vector>
12
13namespace Mantid {
14namespace Kernel {
15
28namespace Utils {
29
30//------------------------------------------------------------------------------------------------
37inline long round(double x) { return long(x + (x < 0 ? -0.5 : +0.5)); }
38
39//------------------------------------------------------------------------------------------------
46inline double rounddbl(double r) { return (r > 0.0) ? std::floor(r + 0.5) : std::ceil(r - 0.5); }
47
48//------------------------------------------------------------------------------------------------
56inline double roundToSF(double r, int f) {
57 double factor = pow(10.0, f - ceil(log10(fabs(r))));
58 return rounddbl(r * factor) / factor;
59}
60
61//------------------------------------------------------------------------------------------------
69inline double roundToDP(double r, int d) {
70 double m = pow(10.0, d);
71 return (int)r + (1.0 / m) * rounddbl((r - (int)r) * m);
72}
73
74namespace NestedForLoop {
75//------------------------------------------------------------------------------------------------
82inline void SetUp(const size_t numDims, size_t *out, const size_t value = 0) {
83 // Allocate and clear to 0.
84 for (size_t d = 0; d < numDims; d++)
85 out[d] = value;
86}
87
88//------------------------------------------------------------------------------------------------
104inline void SetUpIndexMaker(const size_t numDims, size_t *out, const size_t *index_max) {
105 // Allocate and start at 1
106 for (size_t d = 0; d < numDims; d++)
107 out[d] = 1;
108
109 for (size_t d = 1; d < numDims; d++)
110 out[d] = out[d - 1] * index_max[d - 1];
111}
112
113//------------------------------------------------------------------------------------------------
125inline size_t GetLinearIndex(const size_t numDims, size_t *index, size_t *index_maker) {
126 size_t out = 0;
127 for (size_t d = 0; d < numDims; d++)
128 out += index[d] * index_maker[d];
129 return out;
130}
131
132//------------------------------------------------------------------------------------------------
144inline void GetIndicesFromLinearIndex(const size_t numDims, const size_t linear_index, const size_t *index_maker,
145 const size_t *index_max, size_t *out_indices) {
146 for (size_t d = 0; d < numDims; d++) {
147 out_indices[d] = (linear_index / index_maker[d]) % index_max[d];
148 }
149}
150//------------------------------------------------------------------------------------------------
165inline bool Increment(const size_t numDims, size_t *index, size_t *index_max, size_t *index_min) {
166 size_t d = 0;
167 while (d < numDims) {
168 // Add one to the index in this dimension
169 if (++index[d] >= index_max[d]) {
170 // Roll this counter back to 0 (or whatever the min is)
171 index[d] = index_min[d];
172 // Go up one in a higher dimension
173 d++;
174 // Reached the maximum of the last dimension. Time to exit the entire
175 // loop.
176 if (d == numDims)
177 return true;
178 } else
179 return false;
180 }
181 return false;
182}
183
184//------------------------------------------------------------------------------------------------
195inline bool Increment(const size_t numDims, size_t *index, size_t *index_max) {
196 size_t d = 0;
197 while (d < numDims) {
198 // Add one to the index in this dimension
199 if (++index[d] >= index_max[d]) {
200 // Roll this counter back to 0
201 index[d] = 0;
202 // Go up one in a higher dimension
203 d++;
204 // Reached the maximum of the last dimension. Time to exit the entire
205 // loop.
206 if (d == numDims)
207 return true;
208 } else
209 return false;
210 }
211 return false;
212}
213
214} // namespace NestedForLoop
215 //------------------------------------------------------------------------------------------------
228inline void getIndicesFromLinearIndex(const size_t linear_index, size_t const *const numBins, const size_t numDims,
229 size_t *const out_indices) {
230 // number of bins in first dimension
231 size_t nBins = *(numBins + 0);
232 // first index
233 size_t ind = linear_index % nBins;
234 *(out_indices + 0) = ind;
235 // what left in linear index after first was removed;
236 size_t rest = linear_index / nBins;
237 for (size_t d = 1; d < numDims; d++) {
238 nBins = *(numBins + d);
239 ind = rest % nBins;
240 *(out_indices + d) = ind;
241 rest = rest / nBins;
242 }
243}
244//------------------------------------------------------------------------------------------------
255inline std::vector<size_t> getIndicesFromLinearIndex(const size_t linear_index, const std::vector<size_t> &num_bins) {
256 std::vector<size_t> out_indices;
257 if (!num_bins.empty()) {
258 size_t nBins = num_bins.size();
259 out_indices.resize(nBins);
260 getIndicesFromLinearIndex(linear_index, &num_bins[0], nBins, &out_indices[0]);
261 }
262 return out_indices;
263}
264
283inline bool isNeighbourOfSubject(const size_t ndims, const size_t neighbour_linear_index, const size_t *subject_indices,
284 const size_t *num_bins, const size_t *index_max, const std::vector<int> &widths) {
285 for (size_t ind = 0; ind < ndims; ++ind) {
286 size_t neigh_index = (neighbour_linear_index / num_bins[ind]) % index_max[ind];
287 const long double subj = static_cast<long double>(subject_indices[ind]);
288 const long double neigh = static_cast<long double>(neigh_index);
289 const long double diff = std::abs(subj - neigh);
290 if (diff > (widths[ind] >> 1))
291 return false;
292 }
293 return true;
294}
295
296} // namespace Utils
297
298} // namespace Kernel
299} // namespace Mantid
double value
The value of the point.
Definition: FitMW.cpp:51
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
#define fabs(x)
Definition: Matrix.cpp:22
void GetIndicesFromLinearIndex(const size_t numDims, const size_t linear_index, const size_t *index_maker, const size_t *index_max, size_t *out_indices)
Set up a nested for loop by creating an array of counters.
Definition: Utils.h:144
bool Increment(const size_t numDims, size_t *index, size_t *index_max, size_t *index_min)
Utility function for performing arbitrarily nested for loops in a serial way.
Definition: Utils.h:165
size_t GetLinearIndex(const size_t numDims, size_t *index, size_t *index_maker)
Return a linear index from dimensional indices of a nested for loop.
Definition: Utils.h:125
void SetUp(const size_t numDims, size_t *out, const size_t value=0)
Set up a nested for loop by setting an array of counters.
Definition: Utils.h:82
void SetUpIndexMaker(const size_t numDims, size_t *out, const size_t *index_max)
Set up an "index maker" for a nested for loop.
Definition: Utils.h:104
void getIndicesFromLinearIndex(const size_t linear_index, size_t const *const numBins, const size_t numDims, size_t *const out_indices)
Convert an linear index in nDim workspace into vector of loop indexes of nDim depth loop Unsafe (poin...
Definition: Utils.h:228
double rounddbl(double r)
Custom rounding method for a double->double because none is portable in C++ (!)
Definition: Utils.h:46
double roundToDP(double r, int d)
Custom rounding method for a double->double because none is portable in C++ (!)
Definition: Utils.h:69
double roundToSF(double r, int f)
Custom rounding method for a double->double because none is portable in C++ (!)
Definition: Utils.h:56
bool isNeighbourOfSubject(const size_t ndims, const size_t neighbour_linear_index, const size_t *subject_indices, const size_t *num_bins, const size_t *index_max, const std::vector< int > &widths)
Determine, using an any-vertex touching type approach, whether the neighbour linear index corresponds...
Definition: Utils.h:283
long round(double x)
Custom rounding method for a double->long because none is portable in C++ (!)
Definition: Utils.h:37
Helper class which provides the Collimation Length for SANS instruments.