Newer
Older
Laurent Chapon
committed
#include <stdexcept>
#include <cmath>
#include "MantidKernel/VectorHelper.h"
#include <iostream>
Janik Zikovsky
committed
#include <sstream>
#include <boost/algorithm/string.hpp>
Laurent Chapon
committed
Peterson, Peter
committed
using std::size_t;
namespace Mantid {
namespace Kernel {
namespace VectorHelper {
Russell Taylor
committed
/** Creates a new output X array given a 'standard' set of rebinning parameters.
* @param[in] params Rebin parameters input [x_1, delta_1,x_2, ...
*,x_n-1,delta_n-1,x_n]
Russell Taylor
committed
* @param[out] xnew The newly created axis resulting from the input params
* @param[in] resize_xnew If false then the xnew vector is NOT resized. Useful
*if on the number of bins needs determining. (Default=True)
* @param[in] full_bins_only If true, bins of the size less than the current
*step are not included
Russell Taylor
committed
* @return The number of bin boundaries in the new axis
**/
int DLLExport createAxisFromRebinParams(const std::vector<double> ¶ms,
std::vector<double> &xnew,
const bool resize_xnew,
const bool full_bins_only) {
Russell Taylor
committed
double xs;
Russell Taylor
committed
int ibound(2), istep(1), inew(1);
int ibounds = static_cast<int>(
params.size()); // highest index in params array containing a bin boundary
Russell Taylor
committed
int isteps = ibounds - 1; // highest index in params array containing a step
xnew.clear();
// This coefficitent represents the maximum difference between the size of the
// last bin and all
// the other bins.
double lastBinCoef(0.25);
if (full_bins_only) {
// For full_bin_only, we want it so that last bin couldn't be smaller then
// the pervious bin
lastBinCoef = 1.0;
}
Russell Taylor
committed
double xcurr = params[0];
if (resize_xnew)
xnew.push_back(xcurr);
Russell Taylor
committed
while ((ibound <= ibounds) && (istep <= isteps)) {
Russell Taylor
committed
// if step is negative then it is logarithmic step
if (params[istep] >= 0.0)
xs = params[istep];
else
xs = xcurr * fabs(params[istep]);
if (fabs(xs) == 0.0) {
// Someone gave a 0-sized step! What a dope.
throw std::runtime_error(
"Invalid binning step provided! Can't creating binning axis.");
if ((xcurr + xs * (1.0 + lastBinCoef)) <= params[ibound]) {
// If we can still fit current bin _plus_ specified portion of a last bin,
// continue
Russell Taylor
committed
xcurr += xs;
// If this is the start of the last bin, finish this range
if (full_bins_only)
// For full_bins_only, finish the range by adding one more full bin, so
// that last bin is not
// bigger than the previous one
xcurr += xs;
else
// For non full_bins_only, finish by adding as mush as is left from the
// range
xcurr = params[ibound];
Russell Taylor
committed
ibound += 2;
istep += 2;
}
if (resize_xnew)
xnew.push_back(xcurr);
Russell Taylor
committed
inew++;
// if (xnew.size() > 10000000)
// {
// //Max out at 1 million bins
// throw std::runtime_error("Over ten million binning steps created.
// Exiting to avoid infinite loops.");
// return inew;
// }
Russell Taylor
committed
}
return inew;
}
/** Rebins data according to a new output X array
*
* @param[in] xold Old X array of data.
Russell Taylor
committed
* @param[in] yold Old Y array of data. Must be 1 element shorter than xold.
* @param[in] eold Old error array of data. Must be same length as yold.
* @param[in] xnew X array of data to rebin to.
* @param[out] ynew Rebinned data. Must be 1 element shorter than xnew.
* @param[out] enew Rebinned errors. Must be same length as ynew.
* @param[in] distribution Flag defining if distribution data (true) or not
*(false).
* @param[in] addition If true, rebinned values are added to the existing
*ynew/enew vectors.
* NOTE THAT, IN THIS CASE THE RESULTING enew WILL BE THE
*SQUARED ERRORS
* AND THE ynew WILL NOT HAVE THE BIN WIDTH DIVISION PUT
*IN!
Russell Taylor
committed
* @throw runtime_error Thrown if algorithm cannot execute.
* @throw invalid_argument Thrown if input to function is incorrect.
void 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) {
Russell Taylor
committed
// Make sure y and e vectors are of correct sizes
const size_t size_xold = xold.size();
if (size_xold != (yold.size() + 1) || size_xold != (eold.size() + 1))
throw std::runtime_error(
"rebin: y and error vectors should be of same size & 1 shorter than x");
Russell Taylor
committed
const size_t size_xnew = xnew.size();
if (size_xnew != (ynew.size() + 1) || size_xnew != (enew.size() + 1))
throw std::runtime_error(
"rebin: y and error vectors should be of same size & 1 shorter than x");
Laurent Chapon
committed
size_t size_yold = yold.size();
size_t size_ynew = ynew.size();
Russell Taylor
committed
Russell Taylor
committed
// Make sure ynew & enew contain zeroes
std::fill(ynew.begin(), ynew.end(), 0.0);
std::fill(enew.begin(), enew.end(), 0.0);
Russell Taylor
committed
}
Laurent Chapon
committed
Russell Taylor
committed
size_t iold = 0, inew = 0;
Laurent Chapon
committed
while ((inew < size_ynew) && (iold < size_yold)) {
double xo_low = xold[iold];
double xo_high = xold[iold + 1];
double xn_low = xnew[inew];
double xn_high = xnew[inew + 1];
if (xn_high <= xo_low)
inew++; /* old and new bins do not overlap */
else if (xo_high <= xn_low)
iold++; /* old and new bins do not overlap */
// delta is the overlap of the bins on the x axis
// delta = std::min(xo_high, xn_high) - std::max(xo_low, xn_low);
double delta = xo_high < xn_high ? xo_high : xn_high;
delta -= xo_low > xn_low ? xo_low : xn_low;
width = xo_high - xo_low;
if ((delta <= 0.0) || (width <= 0.0)) {
Russell Taylor
committed
// No need to throw here, just return (ynew & enew will be empty)
// throw std::runtime_error("rebin: no bin overlap detected");
Russell Taylor
committed
return;
Laurent Chapon
committed
}
/*
* yoldp contains counts/unit time, ynew contains counts
* enew contains counts**2
* ynew has been filled with zeros on creation
*/
// yold/eold data is distribution
ynew[inew] += yold[iold] * delta;
// this error is calculated in the same way as opengenie
enew[inew] += eold[iold] * eold[iold] * delta * width;
// yold/eold data is not distribution
// do implicit division of yold by width in summing.... avoiding the
// need for temporary yold array
// this method is ~7% faster and uses less memory
ynew[inew] += yold[iold] * delta / width; // yold=yold/width
// eold=eold/width, so divide by width**2 compared with distribution
// calculation
enew[inew] += eold[iold] * eold[iold] * delta / width;
}
iold++;
inew++;
Laurent Chapon
committed
}
}
}
if (!addition) // If using the addition facility, have to do bin width and
// sqrt errors externally
Russell Taylor
committed
/*
* convert back to counts/unit time
*/
for (size_t i = 0; i < size_ynew; ++i) {
Russell Taylor
committed
width = xnew[i + 1] - xnew[i];
Russell Taylor
committed
ynew[i] /= width;
enew[i] = sqrt(enew[i]) / width;
} else {
throw std::invalid_argument(
"rebin: Invalid output X array, contains consecutive X values");
Russell Taylor
committed
}
}
}
Russell Taylor
committed
// non-distribution, just square root final error value
typedef double (*pf)(double);
pf uf = std::sqrt;
std::transform(enew.begin(), enew.end(), enew.begin(), uf);
}
Russell Taylor
committed
Janik Zikovsky
committed
//-------------------------------------------------------------------------------------------------
/** Rebins histogram data according to a new output X array. Should be faster
*than previous one.
* @author Laurent Chapon 10/03/2009
*
* @param[in] xold Old X array of data.
* @param[in] yold Old Y array of data. Must be 1 element shorter than xold.
* @param[in] eold Old error array of data. Must be same length as yold.
* @param[in] xnew X array of data to rebin to.
* @param[out] ynew Rebinned data. Must be 1 element shorter than xnew.
* @param[out] enew Rebinned errors. Must be same length as ynew.
* @param[in] addition If true, rebinned values are added to the existing
*ynew/enew vectors.
* NOTE THAT, IN THIS CASE THE RESULTING enew WILL BE THE
*SQUARED ERRORS!
Russell Taylor
committed
* @throw runtime_error Thrown if vector sizes are inconsistent
void 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) {
// Make sure y and e vectors are of correct sizes
Russell Taylor
committed
const size_t size_yold = yold.size();
if (xold.size() != (size_yold + 1) || size_yold != eold.size())
throw std::runtime_error(
"rebin: y and error vectors should be of same size & 1 shorter than x");
Russell Taylor
committed
const size_t size_ynew = ynew.size();
if (xnew.size() != (size_ynew + 1) || size_ynew != enew.size())
throw std::runtime_error(
"rebin: y and error vectors should be of same size & 1 shorter than x");
// If not adding to existing vectors, make sure ynew & enew contain zeroes
Russell Taylor
committed
ynew.assign(size_ynew, 0.0);
enew.assign(size_ynew, 0.0);
Russell Taylor
committed
// Find the starting points to avoid wasting time processing irrelevant bins
size_t iold = 0, inew = 0; // iold/inew is the bin number under consideration
// (counting from 1, so index+1)
if (xnew.front() > xold.front()) {
std::vector<double>::const_iterator it =
std::upper_bound(xold.begin(), xold.end(), xnew.front());
if (it == xold.end())
return;
// throw std::runtime_error("No overlap: max of X-old < min of X-new");
iold = std::distance(xold.begin(), it) -
1; // Old bin to start at (counting from 0)
} else {
std::vector<double>::const_iterator it =
std::upper_bound(xnew.begin(), xnew.end(), xold.front());
if (it == xnew.end())
return;
// throw std::runtime_error("No overlap: max of X-new < min of X-old");
inew = std::distance(xnew.begin(), it) -
1; // New bin to start at (counting from 0)
Russell Taylor
committed
double frac, fracE;
// loop over old vector from starting point calculated above
for (; iold < size_yold; ++iold) {
double xold_of_iold_p_1 = xold[iold + 1]; // cache for speed
Russell Taylor
committed
// If current old bin is fully enclosed by new bin, just unload the counts
if (xold_of_iold_p_1 <= xnew[inew + 1]) {
Russell Taylor
committed
ynew[inew] += yold[iold];
Russell Taylor
committed
// If the upper bin boundaries were equal, then increment inew
if (xold_of_iold_p_1 == xnew[inew + 1])
inew++;
} else {
double xold_of_iold = xold[iold]; // cache for speed
Russell Taylor
committed
// This is the counts per unit X in current old bin
oneOverWidth = 1. / (xold_of_iold_p_1 -
xold_of_iold); // cache 1/width to speed things up
frac = yold[iold] * oneOverWidth;
temp = eold[iold];
fracE = temp * temp * oneOverWidth;
Russell Taylor
committed
// Now loop over bins in new vector overlapping with current 'old' bin
while (inew < size_ynew && xnew[inew + 1] <= xold_of_iold_p_1) {
overlap = xnew[inew + 1] - std::max(xnew[inew], xold_of_iold);
Russell Taylor
committed
ynew[inew] += frac * overlap;
enew[inew] += fracE * overlap;
++inew;
}
Russell Taylor
committed
// Stop if at end of new X range
if (inew == size_ynew)
break;
Russell Taylor
committed
// Unload the rest of the current old bin into the current new bin
overlap = xold_of_iold_p_1 - xnew[inew];
Russell Taylor
committed
ynew[inew] += frac * overlap;
enew[inew] += fracE * overlap;
Russell Taylor
committed
} // loop over old bins
if (!addition) // If this used to add at the same time then not necessary
// (should be done externally)
// Now take the root-square of the errors
typedef double (*pf)(double);
pf uf = std::sqrt;
std::transform(enew.begin(), enew.end(), enew.begin(), uf);
}
Russell Taylor
committed
return;
}
Janik Zikovsky
committed
//-------------------------------------------------------------------------------------------------
Gigg, Martyn Anthony
committed
/**
* Convert the given set of bin boundaries into bin centre values
Janik Zikovsky
committed
* @param bin_edges :: A vector of values specifying bin boundaries
* @param bin_centres :: An output vector of bin centre values.
Gigg, Martyn Anthony
committed
*/
void convertToBinCentre(const std::vector<double> &bin_edges,
std::vector<double> &bin_centres) {
Gigg, Martyn Anthony
committed
const std::vector<double>::size_type npoints = bin_edges.size();
if (bin_centres.size() != npoints) {
Gigg, Martyn Anthony
committed
bin_centres.resize(npoints);
}
// The custom binary function modifies the behaviour of the algorithm to
// compute the average of
Gigg, Martyn Anthony
committed
// two adjacent bin boundaries
std::adjacent_difference(bin_edges.begin(), bin_edges.end(),
bin_centres.begin(), SimpleAverage<double>());
// The algorithm copies the first element of the input to the first element of
// the output so we need to
Gigg, Martyn Anthony
committed
// remove the first element of the output
bin_centres.erase(bin_centres.begin());
}
//-------------------------------------------------------------------------------------------------
/**
* Convert the given set of bin centers into bin boundary values.
* NOTE: the first and last bin boundaries are calculated so
* that the first and last bin centers are in the center of the
* first and last bins, respectively. For a particular set of
* bin centers, this may not be correct, but it is the best that
* can be done, lacking any other information. For an empty input vector, an
* empty output is returned. For an input vector of size 1, i.e., a single bin,
* there is no information about a proper bin size, so it is set to 1.0.
* @param bin_centers :: A vector of values specifying bin centers.
* @param bin_edges :: An output vector of values specifying bin
* boundaries
*
*/
void convertToBinBoundary(const std::vector<double> &bin_centers,
std::vector<double> &bin_edges) {
const std::vector<double>::size_type n = bin_centers.size();
// Special case empty input: output is also empty
if (n == 0) {
bin_edges.resize(0);
return;
bin_edges.resize(n + 1);
// Special case input of size one: we have no means of guessing the bin size,
// set it to 1.
if (n == 1) {
bin_edges[0] = bin_centers[0] - 0.5;
bin_edges[1] = bin_centers[0] + 0.5;
return;
}
for (size_t i = 0; i < n - 1; ++i) {
bin_edges[i + 1] = 0.5 * (bin_centers[i] + bin_centers[i + 1]);
}
bin_edges[0] = bin_centers[0] - (bin_edges[1] - bin_centers[0]);
bin_edges[n] = bin_centers[n - 1] + (bin_centers[n - 1] - bin_edges[n - 1]);
Janik Zikovsky
committed
//-------------------------------------------------------------------------------------------------
/** Assess if all the values in the vector are equal or if there are some
* different values
Steve Williams
committed
* @param[in] arra the vector to examine
*/
bool isConstantValue(const std::vector<double> &arra) {
// make comparisons with the first value
Steve Williams
committed
std::vector<double>::const_iterator i = arra.begin();
if (i == arra.end()) { // empty array
Steve Williams
committed
return true;
}
Steve Williams
committed
double val(*i);
// this loop can be entered! NAN values make comparisons difficult because nan
// != nan, deal with these first
for (; val != val;) {
Steve Williams
committed
++i;
if (i == arra.end()) {
// all values are contant (NAN)
Steve Williams
committed
return true;
}
val = *i;
}
for (; i != arra.end(); ++i) {
if (*i != val) {
Steve Williams
committed
return false;
}
}
// no different value was found and so every must be equal to c
Steve Williams
committed
return true;
}
Janik Zikovsky
committed
//-------------------------------------------------------------------------------------------------
/** Take a string of comma or space-separated values, and splits it into
* a vector of doubles.
Janik Zikovsky
committed
* @param listString :: a string like "0.0 1.2" or "2.4, 5.67, 88"
Janik Zikovsky
committed
* @return a vector of doubles
* @throw an error if there was a string that could not convert to a double.
*/
template <typename NumT>
std::vector<NumT> splitStringIntoVector(std::string listString) {
// Split the string and turn it into a vector.
Janik Zikovsky
committed
std::vector<NumT> values;
typedef std::vector<std::string> split_vector_type;
split_vector_type strs;
Janik Zikovsky
committed
boost::split(strs, listString, boost::is_any_of(", "));
for (std::vector<std::string>::iterator it = strs.begin(); it != strs.end();
++it) {
if (!it->empty()) {
Janik Zikovsky
committed
// String not empty
std::stringstream oneNumber(*it);
NumT num;
oneNumber >> num;
values.push_back(num);
}
Janik Zikovsky
committed
}
return values;
}
//-------------------------------------------------------------------------------------------------
/** Return the index into a vector of bin boundaries for a particular X value.
* The index returned is the one for the left edge of the bin.
* If beyond the range of the vector, it will return either 0 or bins.size()-2.
* @param bins A reference to the set of bin boundaries to search. It is
* assumed that they are
* monotonically increasing values and this is NOT checked
* @param value The value whose boundaries should be found
Janik Zikovsky
committed
*/
int getBinIndex(const std::vector<double> &bins, const double value) {
assert(bins.size() >= 2);
// Since we cast to an int below:
assert(bins.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
// If X is below the min value
if (value < bins.front())
return 0;
// upper_bound will find the right-hand bin boundary (even if the value is
// equal to
// the left-hand one) - hence we subtract 1 from the found point.
// Since we want to return the LH boundary of the last bin if the value is
// outside
// the upper range, we leave the last value out (i.e. bins.end()-1)
auto it = std::upper_bound(bins.begin(), bins.end() - 1, value) - 1;
assert(it >= bins.begin());
// Convert an iterator to an index for the return value
return static_cast<int>(it - bins.begin());
Janik Zikovsky
committed
}
Gigg, Martyn Anthony
committed
//-------------------------------------------------------------------------------------------------
/**
* Linearly interpolates between Y points separated by the given step size.
Janik Zikovsky
committed
* @param x :: The X array
* @param y :: The Y array with end points and values at stepSize intervals
* calculated
Janik Zikovsky
committed
* @param stepSize :: The distance between each pre-calculated point
Gigg, Martyn Anthony
committed
*/
void linearlyInterpolateY(const std::vector<double> &x, std::vector<double> &y,
const double stepSize) {
Gigg, Martyn Anthony
committed
int specSize = static_cast<int>(y.size());
int xSize = static_cast<int>(x.size());
bool isHistogram(xSize == specSize + 1);
int step(static_cast<int>(stepSize)), index2(0);
Gigg, Martyn Anthony
committed
double x1 = 0, x2 = 0, y1 = 0, y2 = 0, xp = 0, overgap = 0;
for (int i = 0; i < specSize - 1; ++i) // Last point has been calculated
Gigg, Martyn Anthony
committed
{
if (step ==
stepSize) // Point numerically integrated, does not need interpolation
Gigg, Martyn Anthony
committed
{
x1 = (isHistogram ? (0.5 * (x[i] + x[i + 1])) : x[i]);
index2 = static_cast<int>(
((i + stepSize) >= specSize ? specSize - 1 : (i + stepSize)));
Gigg, Martyn Anthony
committed
x2 = (isHistogram ? (0.5 * (x[index2] + x[index2 + 1])) : x[index2]);
overgap = 1.0 / (x2 - x1);
y1 = y[i];
y2 = y[index2];
step = 1;
continue;
}
xp = (isHistogram ? (0.5 * (x[i] + x[i + 1])) : x[i]);
// Linear interpolation
y[i] = (xp - x1) * y2 + (x2 - xp) * y1;
y[i] *= overgap;
step++;
}
}
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
namespace {
// internal function converted from Lambda to identify interval around specified point and
// run average around this point
double runAverage(size_t index,size_t startIndex,size_t endIndex,
const double halfWidth,
const std::vector<double> &input,
std::vector<double> const *const binBndrs) {
size_t iStart, iEnd;
double bin0(0), weight0(0), weight1(0), start, end;
//
if (binBndrs) {
// identify initial and final bins to
// integrate over. Notice the difference
// between start and end bin and shift of
// the interpolating function into the center
// of each bin
bin0 = binBndrs->operator[](index + 1) - binBndrs->operator[](index);
double binC =
0.5 * (binBndrs->operator[](index + 1) + binBndrs->operator[](index));
start = binC - halfWidth;
end = binC + halfWidth;
if (start <= binBndrs->operator[](startIndex)) {
iStart = startIndex;
start = binBndrs->operator[](iStart);
} else {
iStart = getBinIndex(*binBndrs, start);
weight0 =
(binBndrs->operator[](iStart + 1) - start) /
(binBndrs->operator[](iStart + 1) - binBndrs->operator[](iStart));
iStart++;
}
if (end >= binBndrs->operator[](endIndex)) {
iEnd = endIndex; // the signal defined up to i<iEnd
end = binBndrs->operator[](endIndex);
} else {
iEnd = getBinIndex(*binBndrs, end);
weight1 = (end - binBndrs->operator[](iEnd)) /
(binBndrs->operator[](iEnd + 1) - binBndrs->operator[](iEnd));
}
} else { // integer indexes and functions defined in the bin centers
iStart = index - static_cast<size_t>(halfWidth);
if (startIndex + static_cast<size_t>(halfWidth) > index)
iStart = startIndex;
iEnd = index + static_cast<size_t>(halfWidth);
if (iEnd > endIndex)
iEnd = endIndex;
}
double avrg = 0;
size_t ic = 0;
for (size_t j = iStart; j < iEnd; j++) {
avrg += input[j];
ic++;
}
if (binBndrs) { // add values at edges
if (iStart != startIndex)
avrg += input[iStart - 1] * weight0;
if (iEnd != endIndex)
avrg += input[iEnd] * weight1;
return avrg * bin0 / (end - start);
} else {
return avrg / double(ic);
}
};
}
/** Basic running average of input vector within specified range, considering
*variable bin-boundaries
* if such boundaries are provided.
* The algorithm is trapezium integration, so some peak shift related to first
*derivative of the
* integrated function does happen.
*
* @param input:: input vector to smooth
* @param output:: resulting vector (can not coincide with input)
* @param avrgInterval:: the interval to average function in.
* the function is averaged within +-0.5*avrgInterval
*@param binBndrs :: pointer to the vector, containing bin boundaries. If
*provided,
* its length has to be input.size()+1, if not, equal size
*bins of size 1
* are assumed, so avrgInterval becomes the number of points
*to average over.
* Bin boundaries array have to increase and can not contain
*equal
* boundaries.
* @param startIndex:: if provided, its start index to run averaging from.
* if not, averaging starts from the index 0
* @param endIndex :: final index to run average to, if provided. If
* not, or higher then number of elements in input array,
* averaging is performed to the end point of the input
*array
* @param outBins :: if present, pointer to a vector to return
* bin boundaries for output array.
void smoothInRange(const std::vector<double> &input,
std::vector<double> &output, double avrgInterval,
std::vector<double> const *const binBndrs, size_t startIndex,
size_t endIndex, std::vector<double> *const outBins) {
if (endIndex == 0)
endIndex = input.size();
if (endIndex > input.size())
endIndex = input.size();
output.resize(0);
return;
}
size_t max_size = input.size();
if (binBndrs) {
if (binBndrs->size() != max_size + 1) {
throw std::invalid_argument(
"Array of bin boundaries, "
"if present, have to be one bigger then the input array");
double halfWidth = avrgInterval / 2;
if (!binBndrs) {
if (std::fabs(double(static_cast<size_t>(halfWidth)) * 2 - avrgInterval) >
1.e-6) {
halfWidth = static_cast<double>(static_cast<size_t>(halfWidth) + 1);
if (outBins) outBins->resize(length + 1);
for (size_t i = startIndex; i < endIndex; i++) {
output[i - startIndex] = runAverage(i,startIndex,endIndex,halfWidth,
input,binBndrs);
if (outBins) {
outBins->operator[](i - startIndex) = binBndrs->operator[](i);
if (outBins) {
outBins->operator[](endIndex - startIndex) = binBndrs->operator[](endIndex);
Gigg, Martyn Anthony
committed
Janik Zikovsky
committed
/// Declare all version of this
template DLLExport std::vector<int32_t>
splitStringIntoVector<int32_t>(std::string listString);
template DLLExport std::vector<int64_t>
splitStringIntoVector<int64_t>(std::string listString);
template DLLExport std::vector<size_t>
splitStringIntoVector<size_t>(std::string listString);
template DLLExport std::vector<float>
splitStringIntoVector<float>(std::string listString);
template DLLExport std::vector<double>
splitStringIntoVector<double>(std::string listString);
template DLLExport std::vector<std::string>
splitStringIntoVector<std::string>(std::string listString);
Steve Williams
committed
} // End namespace VectorHelper
Laurent Chapon
committed
} // End namespace Mantid