Mantid
Loading...
Searching...
No Matches
VectorHelper.cpp
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#include <cmath>
8#include <stdexcept>
9
11#include <algorithm>
12#include <boost/algorithm/string.hpp>
13#include <numeric>
14#include <sstream>
15
16using std::size_t;
17
19
34int DLLExport createAxisFromRebinParams(const std::vector<double> &params, std::vector<double> &xnew,
35 const bool resize_xnew, const bool full_bins_only, const double xMinHint,
36 const double xMaxHint, const bool useReverseLogarithmic, const double power) {
37 std::vector<double> tmp;
38 const std::vector<double> &fullParams = [&params, &tmp, xMinHint, xMaxHint]() {
39 if (params.size() == 1) {
40 if (std::isnan(xMinHint) || std::isnan(xMaxHint)) {
41 throw std::runtime_error("createAxisFromRebinParams: xMinHint and "
42 "xMaxHint must be supplied if params "
43 "contains only the bin width.");
44 }
45 tmp.resize(3);
46 tmp = {xMinHint, params.front(), xMaxHint};
47 return tmp;
48 }
49 return params;
50 }();
51 int ibound(2), istep(1), inew(1);
52 // highest index in params array containing a bin boundary
53 auto ibounds = static_cast<int>(fullParams.size());
54 int isteps = ibounds - 1; // highest index in params array containing a step
55
56 // This coefficitent represents the maximum difference between the size of the last bin and all
57 // the other bins.
58 double lastBinCoef(0.25);
59
60 if (full_bins_only) {
61 // For full_bin_only, we want it so that last bin couldn't be smaller than the previous bin
62 lastBinCoef = 1.0;
63 }
64
65 double xs = 0;
66 double xcurr = fullParams[0];
67
68 xnew.clear();
69 if (resize_xnew)
70 xnew.emplace_back(xcurr);
71
72 int currDiv = 1;
73
74 bool isPower = power > 0 && power <= 1;
75
76 while ((ibound <= ibounds) && (istep <= isteps)) {
77 // if step is negative then it is logarithmic step
78 bool isLogBin = (fullParams[istep] < 0.0);
79 bool isReverseLogBin = isLogBin && useReverseLogarithmic;
80 double alpha = std::fabs(fullParams[istep]);
81
82 if (isReverseLogBin && xcurr == fullParams[ibound - 2]) {
83 // we are starting a new bin, but since it is a rev log, xcurr needs to be at its end
84 xcurr = fullParams[ibound];
85 }
86 if (!isPower) {
87 if (!isLogBin)
88 xs = fullParams[istep];
89 else {
90 if (useReverseLogarithmic) {
91 // we go through a reverse log bin by starting from its end, and working our way back to the beginning
92 // this way we can define the bins in a reccuring way, and with a more obvious closeness with the usual log.
93 double x0 = fullParams[ibound - 2];
94 double step = x0 + fullParams[ibound] - xcurr;
95
96 xs = -step * alpha;
97
98 } else
99 xs = xcurr * fabs(fullParams[istep]);
100 }
101 } else {
102 xs = fullParams[istep] * std::pow(currDiv, -power);
103 ++currDiv;
104 }
105
106 if (fabs(xs) == 0.0) {
107 // Someone gave a 0-sized step! What a dope.
108 throw std::runtime_error("Invalid binning step provided! Can't create binning axis.");
109 } else if (!std::isfinite(xs)) {
110 throw std::runtime_error("An infinite or NaN value was found in the binning parameters.");
111 }
112
113 if ((!isReverseLogBin && xcurr + xs * (1.0 + lastBinCoef) <= fullParams[ibound]) ||
114 (isReverseLogBin && xcurr + 2 * xs >= fullParams[ibound - 2])) {
115 // If we can still fit current bin _plus_ specified portion of a last bin, continue
116 xcurr += xs;
117
118 } else {
119 // If this is the start of the last bin, finish this range
120 if (!isReverseLogBin) {
121 if (full_bins_only)
122 // For full_bins_only, finish the range by adding one more full bin, so that last bin is not bigger than the
123 // previous one
124 xcurr += xs;
125 else
126 // For non full_bins_only, finish by adding as much as is left from the range
127 xcurr = fullParams[ibound];
128 } else {
129 // we have finished this range, because its starting time has already been added, so we jump back to the last
130 // value of the bin and resume normal behaviour
131 xcurr = fullParams[ibound];
132 }
133 istep += 2;
134 ibound += 2;
135 }
136 if (resize_xnew)
137 xnew.emplace_back(xcurr);
138 inew++;
139 }
140 std::sort(xnew.begin(), xnew.end());
141 return inew;
142}
143
163void rebin(const std::vector<double> &xold, const std::vector<double> &yold, const std::vector<double> &eold,
164 const std::vector<double> &xnew, std::vector<double> &ynew, std::vector<double> &enew, bool distribution,
165 bool addition) {
166 // Make sure y and e vectors are of correct sizes
167 const size_t size_xold = xold.size();
168 if (size_xold != (yold.size() + 1) || size_xold != (eold.size() + 1))
169 throw std::runtime_error("rebin: old y and error vectors should be of same "
170 "size & 1 shorter than x");
171 const size_t size_xnew = xnew.size();
172 if (size_xnew != (ynew.size() + 1) || size_xnew != (enew.size() + 1))
173 throw std::runtime_error("rebin: new y and error vectors should be of same "
174 "size & 1 shorter than x");
175
176 size_t size_yold = yold.size();
177 size_t size_ynew = ynew.size();
178
179 if (!addition) {
180 // Make sure ynew & enew contain zeroes
181 std::fill(ynew.begin(), ynew.end(), 0.0);
182 std::fill(enew.begin(), enew.end(), 0.0);
183 }
184
185 size_t iold = 0, inew = 0;
186 double width;
187
188 while ((inew < size_ynew) && (iold < size_yold)) {
189 double xo_low = xold[iold];
190 double xo_high = xold[iold + 1];
191 double xn_low = xnew[inew];
192 double xn_high = xnew[inew + 1];
193 if (xn_high <= xo_low)
194 inew++; /* old and new bins do not overlap */
195 else if (xo_high <= xn_low)
196 iold++; /* old and new bins do not overlap */
197 else {
198 // delta is the overlap of the bins on the x axis
199 // delta = std::min(xo_high, xn_high) - std::max(xo_low, xn_low);
200 double delta = xo_high < xn_high ? xo_high : xn_high;
201 delta -= xo_low > xn_low ? xo_low : xn_low;
202 width = xo_high - xo_low;
203 if ((delta <= 0.0) || (width <= 0.0)) {
204 // No need to throw here, just return (ynew & enew will be empty)
205 // throw std::runtime_error("rebin: no bin overlap detected");
206 return;
207 }
208 /*
209 * yoldp contains counts/unit time, ynew contains counts
210 * enew contains counts**2
211 * ynew has been filled with zeros on creation
212 */
213 if (distribution) {
214 // yold/eold data is distribution
215 ynew[inew] += yold[iold] * delta;
216 // this error is calculated in the same way as opengenie
217 enew[inew] += eold[iold] * eold[iold] * delta * width;
218 } else {
219 // yold/eold data is not distribution
220 // do implicit division of yold by width in summing.... avoiding the
221 // need for temporary yold array
222 // this method is ~7% faster and uses less memory
223 ynew[inew] += yold[iold] * delta / width; // yold=yold/width
224 // eold=eold/width, so divide by width**2 compared with distribution
225 // calculation
226 enew[inew] += eold[iold] * eold[iold] * delta / width;
227 }
228 if (xn_high > xo_high) {
229 iold++;
230 } else {
231 inew++;
232 }
233 }
234 }
235
236 if (!addition) // If using the addition facility, have to do bin width and
237 // sqrt errors externally
238 {
239 if (distribution) {
240 /*
241 * convert back to counts/unit time
242 */
243 for (size_t i = 0; i < size_ynew; ++i) {
244 {
245 width = xnew[i + 1] - xnew[i];
246 if (width != 0.0) {
247 ynew[i] /= width;
248 enew[i] = sqrt(enew[i]) / width;
249 } else {
250 throw std::invalid_argument("rebin: Invalid output X array, contains consecutive X values");
251 }
252 }
253 }
254 } else {
255 // non-distribution, just square root final error value
256 using pf = double (*)(double);
257 pf uf = std::sqrt;
258 std::transform(enew.begin(), enew.end(), enew.begin(), uf);
259 }
260 }
261}
262
263//-------------------------------------------------------------------------------------------------
280void rebinHistogram(const std::vector<double> &xold, const std::vector<double> &yold, const std::vector<double> &eold,
281 const std::vector<double> &xnew, std::vector<double> &ynew, std::vector<double> &enew,
282 bool addition) {
283 // Make sure y and e vectors are of correct sizes
284 const size_t size_yold = yold.size();
285 if (xold.size() != (size_yold + 1) || size_yold != eold.size())
286 throw std::runtime_error("rebin: y and error vectors should be of same size & 1 shorter than x");
287 const size_t size_ynew = ynew.size();
288 if (xnew.size() != (size_ynew + 1) || size_ynew != enew.size())
289 throw std::runtime_error("rebin: y and error vectors should be of same size & 1 shorter than x");
290
291 // If not adding to existing vectors, make sure ynew & enew contain zeroes
292 if (!addition) {
293 ynew.assign(size_ynew, 0.0);
294 enew.assign(size_ynew, 0.0);
295 }
296
297 // Find the starting points to avoid wasting time processing irrelevant bins
298 size_t iold = 0, inew = 0; // iold/inew is the bin number under consideration
299 // (counting from 1, so index+1)
300 if (xnew.front() > xold.front()) {
301 auto it = std::upper_bound(xold.cbegin(), xold.cend(), xnew.front());
302 if (it == xold.end())
303 return;
304 // throw std::runtime_error("No overlap: max of X-old < min of X-new");
305 iold = std::distance(xold.begin(), it) - 1; // Old bin to start at (counting from 0)
306 } else {
307 auto it = std::upper_bound(xnew.cbegin(), xnew.cend(), xold.front());
308 if (it == xnew.cend())
309 return;
310 // throw std::runtime_error("No overlap: max of X-new < min of X-old");
311 inew = std::distance(xnew.cbegin(), it) - 1; // New bin to start at (counting from 0)
312 }
313
314 double frac, fracE;
315 double oneOverWidth, overlap;
316 double temp;
317
318 // loop over old vector from starting point calculated above
319 for (; iold < size_yold; ++iold) {
320 double xold_of_iold_p_1 = xold[iold + 1]; // cache for speed
321 // If current old bin is fully enclosed by new bin, just unload the counts
322 if (xold_of_iold_p_1 <= xnew[inew + 1]) {
323 ynew[inew] += yold[iold];
324 temp = eold[iold];
325 enew[inew] += temp * temp;
326 // If the upper bin boundaries were equal, then increment inew
327 if (xold_of_iold_p_1 == xnew[inew + 1])
328 inew++;
329 } else {
330 double xold_of_iold = xold[iold]; // cache for speed
331 // This is the counts per unit X in current old bin
332 oneOverWidth = 1. / (xold_of_iold_p_1 - xold_of_iold); // cache 1/width to speed things up
333 frac = yold[iold] * oneOverWidth;
334 temp = eold[iold];
335 fracE = temp * temp * oneOverWidth;
336
337 // Now loop over bins in new vector overlapping with current 'old' bin
338 while (inew < size_ynew && xnew[inew + 1] <= xold_of_iold_p_1) {
339 overlap = xnew[inew + 1] - std::max(xnew[inew], xold_of_iold);
340 ynew[inew] += frac * overlap;
341 enew[inew] += fracE * overlap;
342 ++inew;
343 }
344
345 // Stop if at end of new X range
346 if (inew == size_ynew)
347 break;
348
349 // Unload the rest of the current old bin into the current new bin
350 overlap = xold_of_iold_p_1 - xnew[inew];
351 ynew[inew] += frac * overlap;
352 enew[inew] += fracE * overlap;
353 }
354 } // loop over old bins
355
356 if (!addition) // If this used to add at the same time then not necessary
357 // (should be done externally)
358 {
359 // Now take the root-square of the errors
360 using pf = double (*)(double);
361 pf uf = std::sqrt;
362 std::transform(enew.begin(), enew.end(), enew.begin(), uf);
363 }
364}
365
366//-------------------------------------------------------------------------------------------------
372void convertToBinCentre(const std::vector<double> &bin_edges, std::vector<double> &bin_centres) {
373 const std::vector<double>::size_type npoints = bin_edges.size();
374 if (bin_centres.size() != npoints) {
375 bin_centres.resize(npoints);
376 }
377
378 // The custom binary function modifies the behaviour of the algorithm to
379 // compute the average of
380 // two adjacent bin boundaries
381 std::adjacent_difference(bin_edges.begin(), bin_edges.end(), bin_centres.begin(), SimpleAverage<double>());
382 // The algorithm copies the first element of the input to the first element of
383 // the output so we need to
384 // remove the first element of the output
385 bin_centres.erase(bin_centres.begin());
386}
387
388//-------------------------------------------------------------------------------------------------
404void convertToBinBoundary(const std::vector<double> &bin_centers, std::vector<double> &bin_edges) {
405 const auto n = bin_centers.size();
406
407 // Special case empty input: output is also empty
408 if (n == 0) {
409 bin_edges.resize(0);
410 return;
411 }
412
413 bin_edges.resize(n + 1);
414
415 // Special case input of size one: we have no means of guessing the bin size,
416 // set it to 1.
417 if (n == 1) {
418 bin_edges[0] = bin_centers[0] - 0.5;
419 bin_edges[1] = bin_centers[0] + 0.5;
420 return;
421 }
422
423 for (size_t i = 0; i < n - 1; ++i) {
424 bin_edges[i + 1] = 0.5 * (bin_centers[i] + bin_centers[i + 1]);
425 }
426
427 bin_edges[0] = bin_centers[0] - (bin_edges[1] - bin_centers[0]);
428
429 bin_edges[n] = bin_centers[n - 1] + (bin_centers[n - 1] - bin_edges[n - 1]);
430}
431
442size_t indexOfValueFromCenters(const std::vector<double> &bin_centers, const double value) {
443 int index = indexOfValueFromCentersNoThrow(bin_centers, value);
444 if (index >= 0)
445 return static_cast<size_t>(index);
446 else
447 throw std::out_of_range("indexOfValue - value out of range");
448}
449
450int indexOfValueFromCentersNoThrow(const std::vector<double> &bin_centers, const double value) {
451 if (bin_centers.empty()) {
452 throw std::out_of_range("indexOfValue - vector is empty");
453 }
454 if (bin_centers.size() == 1) {
455 // no mean to guess bin size, assuming 1
456 if (value < bin_centers[0] - 0.5 || value > bin_centers[0] + 0.5) {
457 return -1;
458 } else {
459 return 0;
460 }
461 } else {
462 const size_t n = bin_centers.size();
463 const double firstBinLowEdge = bin_centers[0] - 0.5 * (bin_centers[1] - bin_centers[0]);
464 const double lastBinHighEdge = bin_centers[n - 1] + 0.5 * (bin_centers[n - 1] - bin_centers[n - 2]);
465 if (value < firstBinLowEdge || value > lastBinHighEdge) {
466 return -1;
467 } else {
468 const auto it = std::lower_bound(bin_centers.begin(), bin_centers.end(), value);
469 if (it == bin_centers.end()) {
470 return static_cast<int>(n - 1);
471 }
472 size_t binIndex = std::distance(bin_centers.begin(), it);
473 if (binIndex > 0 &&
474 value < bin_centers[binIndex - 1] + 0.5 * (bin_centers[binIndex] - bin_centers[binIndex - 1])) {
475 binIndex--;
476 }
477 return static_cast<int>(binIndex);
478 }
479 }
480}
481
490size_t indexOfValueFromEdges(const std::vector<double> &bin_edges, const double value) {
491 if (bin_edges.empty()) {
492 throw std::out_of_range("indexOfValue - vector is empty");
493 }
494 if (bin_edges.size() == 1) {
495 throw std::out_of_range("indexOfValue - requires at least two bin edges");
496 }
497 if (value < bin_edges.front()) {
498 throw std::out_of_range("indexOfValue - value out of range");
499 }
500 const auto it = std::lower_bound(bin_edges.begin(), bin_edges.end(), value);
501 if (it == bin_edges.end()) {
502 throw std::out_of_range("indexOfValue - value out of range");
503 }
504 // index of closest edge above value is distance of iterator from start
505 size_t edgeIndex = std::distance(bin_edges.begin(), it);
506 // if the element n is the first that is >= value, then the value is in (n-1)
507 // th bin
508 if (edgeIndex > 0)
509 edgeIndex--;
510 return edgeIndex;
511}
512
513//-------------------------------------------------------------------------------------------------
518bool isConstantValue(const std::vector<double> &arra) {
519 // make comparisons with the first value
520 auto i = arra.cbegin();
521
522 if (i == arra.cend()) { // empty array
523 return true;
524 }
525
526 double val(*i);
527 // this loop can be entered! NAN values make comparisons difficult because nan
528 // != nan, deal with these first
529 for (; val != val;) {
530 ++i;
531 if (i == arra.cend()) {
532 // all values are contant (NAN)
533 return true;
534 }
535 val = *i;
536 }
537
538 for (; i != arra.cend(); ++i) {
539 if (*i != val) {
540 return false;
541 }
542 }
543 // no different value was found and so every must be equal to c
544 return true;
545}
546
547//-------------------------------------------------------------------------------------------------
554template <typename NumT> std::vector<NumT> splitStringIntoVector(std::string listString) {
555 // Split the string and turn it into a vector.
556 std::vector<NumT> values;
557
558 using split_vector_type = std::vector<std::string>;
559 split_vector_type strs;
560
561 boost::split(strs, listString, boost::is_any_of(", "));
562 for (auto &str : strs) {
563 if (!str.empty()) {
564 // String not empty
565 std::stringstream oneNumber(str);
566 NumT num;
567 oneNumber >> num;
568 values.emplace_back(num);
569 }
570 }
571 return values;
572}
573
574//-------------------------------------------------------------------------------------------------
583int getBinIndex(const std::vector<double> &bins, const double value) {
584 assert(bins.size() >= 2);
585 // Since we cast to an int below:
586 assert(bins.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
587 // If X is below the min value
588 if (value < bins.front())
589 return 0;
590
591 // upper_bound will find the right-hand bin boundary (even if the value is
592 // equal to
593 // the left-hand one) - hence we subtract 1 from the found point.
594 // Since we want to return the LH boundary of the last bin if the value is
595 // outside
596 // the upper range, we leave the last value out (i.e. bins.end()-1)
597 auto it = std::upper_bound(bins.begin(), bins.end() - 1, value) - 1;
598 assert(it >= bins.begin());
599 // Convert an iterator to an index for the return value
600 return static_cast<int>(it - bins.begin());
601}
602
603//-------------------------------------------------------------------------------------------------
604
605namespace {
618double runAverage(size_t index, size_t startIndex, size_t endIndex, const double halfWidth,
619 const std::vector<double> &input, std::vector<double> const *const binBndrs) {
620
621 size_t iStart, iEnd;
622 double weight0(0), weight1(0), start(0.0), end(0.0);
623 //
624 if (binBndrs) {
625 // identify initial and final bins to
626 // integrate over. Notice the difference
627 // between start and end bin and shift of
628 // the interpolating function into the center
629 // of each bin
630 auto &rBndrs = *binBndrs;
631 // bin0 = binBndrs->operator[](index + 1) - binBndrs->operator[](index);
632
633 double binC = 0.5 * (rBndrs[index + 1] + rBndrs[index]);
634 start = binC - halfWidth;
635 end = binC + halfWidth;
636 if (start <= rBndrs[startIndex]) {
637 iStart = startIndex;
638 start = rBndrs[iStart];
639 } else {
640 iStart = getBinIndex(*binBndrs, start);
641 weight0 = (rBndrs[iStart + 1] - start) / (rBndrs[iStart + 1] - rBndrs[iStart]);
642 iStart++;
643 }
644 if (end >= rBndrs[endIndex]) {
645 iEnd = endIndex; // the signal defined up to i<iEnd
646 end = rBndrs[endIndex];
647 } else {
648 iEnd = getBinIndex(*binBndrs, end);
649 weight1 = (end - rBndrs[iEnd]) / (rBndrs[iEnd + 1] - rBndrs[iEnd]);
650 }
651 if (iStart > iEnd) { // start and end get into the same bin
652 weight1 = 0;
653 weight0 = (end - start) / (rBndrs[iStart] - rBndrs[iStart - 1]);
654 }
655 } else { // integer indexes and functions defined in the bin centers
656 auto iHalfWidth = static_cast<size_t>(halfWidth);
657 iStart = index - iHalfWidth;
658 if (startIndex + iHalfWidth > index)
659 iStart = startIndex;
660 iEnd = index + iHalfWidth;
661 if (iEnd > endIndex)
662 iEnd = endIndex;
663 }
664
665 double avrg = 0;
666 size_t ic = 0;
667 for (size_t j = iStart; j < iEnd; j++) {
668 avrg += input[j];
669 ic++;
670 }
671 if (binBndrs) { // add values at edges
672 if (iStart != startIndex)
673 avrg += input[iStart - 1] * weight0;
674 if (iEnd != endIndex)
675 avrg += input[iEnd] * weight1;
676
677 double div = end - start;
678 if (.0 == div)
679 return 0;
680 else
681 return avrg / (end - start);
682 } else {
683 if (0 == ic) {
684 return 0;
685 } else {
686 return avrg / double(ic);
687 }
688 }
689}
690} // namespace
691
716void smoothInRange(const std::vector<double> &input, std::vector<double> &output, const double avrgInterval,
717 std::vector<double> const *const binBndrs, size_t startIndex, size_t endIndex,
718 std::vector<double> *const outBins) {
719
720 if (endIndex == 0)
721 endIndex = input.size();
722 if (endIndex > input.size())
723 endIndex = input.size();
724
725 if (endIndex <= startIndex) {
726 output.resize(0);
727 return;
728 }
729
730 size_t max_size = input.size();
731 if (binBndrs) {
732 if (binBndrs->size() != max_size + 1) {
733 throw std::invalid_argument("Array of bin boundaries, "
734 "if present, have to be one bigger then the input array");
735 }
736 }
737
738 size_t length = endIndex - startIndex;
739 output.resize(length);
740
741 double halfWidth = avrgInterval / 2;
742 if (!binBndrs) {
743 if (std::floor(halfWidth) * 2 - avrgInterval > 1.e-6) {
744 halfWidth = std::floor(halfWidth) + 1;
745 }
746 }
747
748 if (outBins)
749 outBins->resize(length + 1);
750
751 // Run averaging
752 double binSize = 1;
753 for (size_t i = startIndex; i < endIndex; i++) {
754 if (binBndrs) {
755 binSize = binBndrs->operator[](i + 1) - binBndrs->operator[](i);
756 }
757 output[i - startIndex] = runAverage(i, startIndex, endIndex, halfWidth, input, binBndrs) * binSize;
758 if (outBins && binBndrs) {
759 outBins->operator[](i - startIndex) = binBndrs->operator[](i);
760 }
761 }
762 if (outBins && binBndrs) {
763 outBins->operator[](endIndex - startIndex) = binBndrs->operator[](endIndex);
764 }
765}
766
768template DLLExport std::vector<int32_t> splitStringIntoVector<int32_t>(std::string listString);
769template DLLExport std::vector<int64_t> splitStringIntoVector<int64_t>(std::string listString);
770template DLLExport std::vector<size_t> splitStringIntoVector<size_t>(std::string listString);
771template DLLExport std::vector<float> splitStringIntoVector<float>(std::string listString);
772template DLLExport std::vector<double> splitStringIntoVector<double>(std::string listString);
773template DLLExport std::vector<std::string> splitStringIntoVector<std::string>(std::string listString);
774
775} // namespace Mantid::Kernel::VectorHelper
gsl_vector * tmp
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
#define DLLExport
Definitions of the DLLImport compiler directives for MSVC.
Definition: System.h:53
size_t iEnd
size_t iStart
MANTID_KERNEL_DLL void smoothInRange(const std::vector< double > &input, std::vector< double > &output, double avrgInterval, std::vector< double > const *const binBndrs=nullptr, size_t startIndex=0, size_t endIndex=0, std::vector< double > *const outBins=nullptr)
Basic running average of input vector within specified range, considering variable bin-boundaries if ...
template DLLExport std::vector< int32_t > splitStringIntoVector< int32_t >(std::string listString)
Declare all version of this.
template DLLExport std::vector< double > splitStringIntoVector< double >(std::string listString)
size_t MANTID_KERNEL_DLL indexOfValueFromCenters(const std::vector< double > &bin_centers, const double value)
Gets the bin of a value from a vector of bin centers and throws exception if out of range.
template DLLExport std::vector< std::string > splitStringIntoVector< std::string >(std::string listString)
void MANTID_KERNEL_DLL convertToBinCentre(const std::vector< double > &bin_edges, std::vector< double > &bin_centres)
Convert an array of bin boundaries to bin center values.
template DLLExport std::vector< float > splitStringIntoVector< float >(std::string listString)
bool MANTID_KERNEL_DLL isConstantValue(const std::vector< double > &arra)
Assess if all the values in the vector are equal or if there are some different values.
MANTID_KERNEL_DLL int getBinIndex(const std::vector< double > &bins, const double value)
Return the index into a vector of bin boundaries for a particular X value.
MANTID_KERNEL_DLL std::vector< NumT > splitStringIntoVector(std::string listString)
Take a string of comma or space-separated values, and splits it into a vector of doubles.
size_t MANTID_KERNEL_DLL indexOfValueFromEdges(const std::vector< double > &bin_edges, const double value)
Gets the bin of a value from a vector of bin edges.
template DLLExport std::vector< int64_t > splitStringIntoVector< int64_t >(std::string listString)
int MANTID_KERNEL_DLL createAxisFromRebinParams(const std::vector< double > &params, std::vector< double > &xnew, const bool resize_xnew=true, const bool full_bins_only=false, const double xMinHint=std::nan(""), const double xMaxHint=std::nan(""), const bool useReverseLogarithmic=false, const double power=-1)
Creates a new output X array given a 'standard' set of rebinning parameters.
void MANTID_KERNEL_DLL rebin(const std::vector< double > &xold, const std::vector< double > &yold, const std::vector< double > &eold, const std::vector< double > &xnew, std::vector< double > &ynew, std::vector< double > &enew, bool distribution, bool addition=false)
Rebins data according to a new output X array.
void MANTID_KERNEL_DLL rebinHistogram(const std::vector< double > &xold, const std::vector< double > &yold, const std::vector< double > &eold, const std::vector< double > &xnew, std::vector< double > &ynew, std::vector< double > &enew, bool addition)
Rebins histogram data according to a new output X array.
void MANTID_KERNEL_DLL convertToBinBoundary(const std::vector< double > &bin_centers, std::vector< double > &bin_edges)
Convert an array of bin centers to bin boundary values.
template DLLExport std::vector< size_t > splitStringIntoVector< size_t >(std::string listString)
int MANTID_KERNEL_DLL indexOfValueFromCentersNoThrow(const std::vector< double > &bin_centers, const double value)
Gets the bin of a value from a vector of bin centers and returns -1 if out of range.
A binary functor to compute the simple average of 2 numbers.
Definition: VectorHelper.h:221