/**
 * Fills in a column for each active hermite polynomial, starting at the given
 * index
 * @param cmatrix InOut matrix whose columns should be set to the mass profile
 * for each active hermite polynomial
 * @param start Index of the column to start on
 * @param errors Data errors array
 * @returns The number of columns filled
 */
size_t GramCharlierComptonProfile::fillConstraintMatrix(
    Kernel::DblMatrix &cmatrix, const size_t start,
    const std::vector<double> &errors) const {
  std::vector<double> profile(NFINE_Y, 0.0);
  const size_t nData(ySpace().size());
  std::vector<double> result(nData, 0.0);

  // If the FSE term is fixed by user then it's contribution is convoluted with
  // Voigt and summed with the first column
  // otherwise it gets a column of it's own at the end.
  // Either way it needs to be computed, so do this first

  std::vector<double> fse(NFINE_Y, 0.0);
  std::vector<double> convolvedFSE(nData, 0.0);
  addFSETerm(fse);
  convoluteVoigt(convolvedFSE.data(), nData, fse);

  size_t col(0);
  for (unsigned int i = 0; i < m_hermite.size(); ++i) {
    if (m_hermite[i] == 0)
      continue;

    const unsigned int npoly = 2 * i;
    addMassProfile(profile.data(), npoly);
    convoluteVoigt(result.data(), nData, profile);
    if (i == 0 && m_userFixedFSE) {
      std::transform(result.begin(), result.end(), convolvedFSE.begin(),
                     result.begin(), std::plus<double>());
    }
    std::transform(result.begin(), result.end(), errors.begin(), result.begin(),
                   std::divides<double>());
    cmatrix.setColumn(start + col, result);

    std::fill_n(profile.begin(), NFINE_Y, 0.0);
    std::fill_n(result.begin(), nData, 0.0);
    ++col;
  }

  if (!m_userFixedFSE) // Extra column for He3
  {
    std::transform(convolvedFSE.begin(), convolvedFSE.end(), errors.begin(),
                   convolvedFSE.begin(), std::divides<double>());
    cmatrix.setColumn(start + col, convolvedFSE);
    ++col;
  }
  return col;
}
/**
 * Fills in a column of the matrix with this mass profile, starting at the given
 * index
 * @param cmatrix InOut matrix whose column should be set to the mass profile
 *                for each active hermite polynomial
 * @param start Index of the column to start on
 * @param errors The data errors
 * @returns The number of columns filled
 */
size_t MultivariateGaussianComptonProfile::fillConstraintMatrix(
    Kernel::DblMatrix &cmatrix, const size_t start,
    const std::vector<double> &errors) const {
  std::vector<double> result(ySpace().size());
  this->massProfile(result.data(), ySpace().size());
  std::transform(result.begin(), result.end(), errors.begin(), result.begin(),
                 std::divides<double>());
  cmatrix.setColumn(start, result);
  return 1;
}