Skip to content

File radialprojectionsingledatum.h

File List > code_source > templat > include > TempLat > lattice > measuringtools > projectionhelpers > radialprojectionsingledatum.h

Go to the documentation of this file

#ifndef TEMPLAT_LATTICE_MEASUREMENTS_PROJECTIONHELPERS_RADIALPROJECTIONSINGLEDATUM_H
#define TEMPLAT_LATTICE_MEASUREMENTS_PROJECTIONHELPERS_RADIALPROJECTIONSINGLEDATUM_H

/* This file is part of TempLat, available at https://cosmolattice.github.io/templat .
   Copyright 2021-2026 The TempLat authors, see AUTHORS.md.
   Released under the MIT license, see LICENSE.md. */

// File info: Main contributor(s): Wessel Valkenburg, Year: 2019

#include <sstream>
#include <algorithm>
#include <iomanip>

#include "TempLat/lattice/algebra/helpers/getfloattype.h"

namespace TempLat
{
  template <typename T> struct RadialProjectionSingleDatum {
    using floatType = typename GetFloatType<T>::type;

    RadialProjectionSingleDatum()
        : multiplicity(0), average(0), sampleVariance(0), minVal(std::numeric_limits<T>::max()),
          maxVal(std::numeric_limits<T>::min())
    {
    }

    RadialProjectionSingleDatum(T sum, T sumOfSquares, T inputMinVal, T inputMaxVal, floatType inputMultiplicity)
        : multiplicity(inputMultiplicity), average(multiplicity > 0 ? sum / multiplicity : 0.),
          sampleVariance(multiplicity > 0. ? sumOfSquares / multiplicity - average * average : 0.), minVal(inputMinVal),
          maxVal(inputMaxVal)
    {
    }

    template <typename U>
    RadialProjectionSingleDatum(const RadialProjectionSingleDatum<U> &o)
        : multiplicity(static_cast<floatType>(o.multiplicity)), average(static_cast<T>(o.average)),
          sampleVariance(static_cast<T>(o.sampleVariance)), minVal(static_cast<T>(o.minVal)),
          maxVal(static_cast<T>(o.maxVal))
    {
    }

    floatType multiplicity;
    T average;
    T sampleVariance;
    T minVal;
    T maxVal;

    std::string getHeader(device::Idx start, std::string prefix, bool withMultiplicity, int verbosity = 0) const
    {
      return std::to_string(start) + ":" + prefix + "Average" +
             (verbosity == 2
                  ? " " + std::to_string(start + 1) + ":" + prefix + "SampleVariance " + std::to_string(start + 2) +
                        ":" + prefix + "Minimum " + std::to_string(start + 3) + ":" + prefix + "Maximum" +
                        (withMultiplicity ? (" " + std::to_string(start + 4) + ":multiplicity") : "")
                  : (withMultiplicity ? (" " + std::to_string(start + 1) + ":multiplicity") : ""));
    }

    std::string toString(bool withMultiplicity = false, int verbosity = 0, bool fourierMult = true) const
    {
      std::stringstream sstream;
      switch (verbosity) {
      case 0:
      case 1: {
        sstream << std::setprecision(16) << average;
        break;
      }
      case 2: {
        sstream << std::setprecision(16) << average << " " << sampleVariance << " " << minVal << " " << maxVal;
        break;
      }
      }
      if (withMultiplicity) sstream << " " << (fourierMult ? 2 * multiplicity : multiplicity);
      return sstream.str();
    }

    friend std::ostream &operator<<(std::ostream &ostream, const RadialProjectionSingleDatum &dp)
    {
      ostream << dp.toString(true);
      return ostream;
    }

    RadialProjectionSingleDatum<T> &operator*=(floatType value)
    {
      average *= value;
      sampleVariance *= value * value;
      minVal *= value;
      maxVal *= value;
      return *this;
    }

    RadialProjectionSingleDatum<T> &sumInsteadOfAverage()
    {
      floatType intMultiplicity = 2 * multiplicity; // *2 is to get the full number of modes, against original design
      return (*this) *= intMultiplicity;
    }

    friend RadialProjectionSingleDatum<T> combine(const RadialProjectionSingleDatum<T> &a,
                                                  const RadialProjectionSingleDatum<T> &b)
    {
      T a_sumOfSquares = (a.sampleVariance + a.average * a.average) * a.multiplicity;
      T b_sumOfSquares = (b.sampleVariance + b.average * b.average) * b.multiplicity;
      T a_sum = a.average * a.multiplicity;
      T b_sum = b.average * b.multiplicity;

      return RadialProjectionSingleDatum<T>(a_sum + b_sum, a_sumOfSquares + b_sumOfSquares,
                                            std::min(a.minVal, b.minVal), std::max(a.maxVal, b.maxVal),
                                            a.multiplicity + b.multiplicity);
    }
  };
} // namespace TempLat

#endif