// This file is part of Bertini 2.
//
// system/start/utility.hpp is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
// system/start/utility.hpp is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with system/start/utility.hpp. If not, see
// .
//
// Copyright(C) 2015 - 2021 by Bertini2 Development Team
//
// See for a copy of the license,
// as well as COPYING. Bertini2 is provided with permitted
// additional terms in the b2/licenses/ directory.
// individual authors of this file include:
// silviana amethyst, university of wisconsin - eau claire
/**
\file system/start/utility.hpp
\brief utilities for start system code.
*/
#ifndef BERTINI_START_SYSTEM_UTILITIES_HPP
#define BERTINI_START_SYSTEM_UTILITIES_HPP
namespace bertini {
/**
\brief Convert a zero-based index to a zero-based subscript vector.
Throws `std::out_of_range` if the index is out-of-range based on the dimensions.
This goes from front to back, top to bottom. So
[0 2 4 [(0,0) (0,1) (0,2)
1 3 5] (1,0) (1,1) (1,2)]
etc for higher-dimensional arrays. The functionality here is identical to that
of Matlab's analagous call.
\param index The index you want to convert.
\param dimensions The dimensions of the object you are subscripting or indexing
into. \return A vector containing the subscripts for the input index. \throws
std::out_of_range, if the index is impossible to convert.
*/
template
std::vector IndexToSubscript(T index, std::vector const& dimensions) {
std::vector subscripts(
dimensions.size()); // for forming a subscript from an index
std::vector k(dimensions.size(), 1);
for (int ii = 0; ii < dimensions.size() - 1; ++ii)
k[ii + 1] = k[ii] * dimensions[ii];
if (index >= k.back() * dimensions.back())
throw std::out_of_range(
"in IndexToSubscript, index exceeds max based on dimension sizes");
for (int ii = dimensions.size() - 1; ii >= 0; --ii) {
T I = index % k[ii];
T J = (index - I) / k[ii];
subscripts[ii] = J;
index = I;
}
return subscripts;
}
} // namespace bertini
#endif