NDArray floatToDataType()

in cpp/src/array_utils.h [83:134]


NDArray<data_t, 2> floatToDataType(NDArray<float, 2> input) {
  // Handle rescaling to integer storage values if necessary:
  if constexpr (std::is_same_v<data_t, float>) {
    if constexpr (scalefactor::num != scalefactor::den) {
      throw std::runtime_error(
          "Index has a non-unity scale factor set, but is using float32 data "
          "storage. This combination is not yet implemented.");
    }

    return input;
  } else if constexpr (std::is_same_v<data_t, E4M3>) {
    NDArray<E4M3, 2> output(input.shape);

    float *inputPointer = input.data.data();
    E4M3 *outputPointer = output.data.data();

    for (unsigned long i = 0; i < input.data.size(); i++) {
      outputPointer[i] = E4M3(inputPointer[i]);
    }

    return output;
  } else {
    // Re-scale the input values by multiplying by `scalefactor`:
    constexpr float lowerBound = (float)std::numeric_limits<data_t>::min() *
                                 (float)scalefactor::num /
                                 (float)scalefactor::den;
    constexpr float upperBound = (float)std::numeric_limits<data_t>::max() *
                                 (float)scalefactor::num /
                                 (float)scalefactor::den;

    NDArray<data_t, 2> output(input.shape);

    // Re-scale the input values by multiplying by `scalefactor`:
    float *inputPointer = input.data.data();
    data_t *outputPointer = output.data.data();

    for (unsigned long i = 0; i < input.data.size(); i++) {
      if (inputPointer[i] > upperBound || inputPointer[i] < lowerBound) {
        throw std::domain_error(
            "One or more vectors contain values outside of [" +
            std::to_string(lowerBound) + ", " + std::to_string(upperBound) +
            "]. Index: " + std::to_string(i) +
            ", invalid value: " + std::to_string(inputPointer[i]));
      }

      outputPointer[i] =
          (inputPointer[i] * (float)scalefactor::den) / (float)scalefactor::num;
    }

    return output;
  }
}