#ifndef PM_SUBTRACTION_EQUATION_H
#define PM_SUBTRACTION_EQUATION_H

#include "pmSubtractionStamps.h"
#include "pmSubtractionKernels.h"

/// Calculate the least-squares equation to match the image quality
bool pmSubtractionCalculateEquation(pmSubtractionStampList *stamps, ///< Stamps
                                    const pmSubtractionKernels *kernels ///< Kernel parameters
                                    );

/// Solve the least-squares equation to match the image quality
bool pmSubtractionSolveEquation(pmSubtractionKernels *kernels, ///< Kernel parameters
                                const pmSubtractionStampList *stamps ///< Stamps
    );

/// Calculate deviations
psVector *pmSubtractionCalculateDeviations(pmSubtractionStampList *stamps, ///< Stamps
                                           const pmSubtractionKernels *kernels ///< Kernel parameters
    );

/// Calculate the value of a polynomial, specified by coefficients and polynomial values
inline double p_pmSubtractionCalculatePolynomial(const psVector *coeff, ///< Coefficients
                                                 const psImage *polyValues, ///< Polynomial values
                                                 int order, ///< Order of polynomials
                                                 int index, ///< Index at which to begin
                                                 int step ///< Step between subsequent indices
    );

/// Return the specified coefficient in the solution
inline double p_pmSubtractionSolutionCoeff(const pmSubtractionKernels *kernels, ///< Kernel parameters
                                           const psImage *polyValues, ///< Polynomial values
                                           int index, ///< Coefficient index to calculate
                                           bool wantDual ///< Calculate the coefficient for the dual solution?
    );

/// Return the normalisation in the solution
inline double p_pmSubtractionSolutionNorm(const pmSubtractionKernels *kernels ///< Kernel parameters
    );

/// Return the background (difference) in the solution
inline double p_pmSubtractionSolutionBackground(const pmSubtractionKernels *kernels, ///< Kernel parameters
                                                const psImage *polyValues ///< Polynomial values
    );

#endif
