// Created with MonoDevelop
//
//    Copyright (C) 2017 Hiperscan GmbH Dresden, Germany
//
//    This program 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.
//
//    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

using System;

using MathNet.Numerics.LinearAlgebra.Double;


namespace Hiperscan.Spectroscopy.Math
{

    public partial class LevenbergMarquardt
    {

        public abstract class BaseFit
        {

            protected BaseFit(DataSet fit_data, double direction)
            {
                this.FitData = fit_data;
                this.RefData = null;
                this.Direction = direction;
            }

            protected BaseFit(DataSet fit_data, DataSet ref_data, double direction)
            {
                this.FitData = fit_data;
                this.RefData = ref_data;
                this.Direction = direction;
            }

            public abstract void NormalizeFitData();

            public abstract double[] UnNormalizeCoefficients(double[] coeff);

            public abstract Vector FunctionVector(double[] coeff);

            public virtual Vector ObjectiveFunc(double[] coeff)
            {
                Vector fvec = this.FunctionVector(coeff);
                Vector fitvec;

                if (RefData != null)
                    fitvec = new DenseVector(this.RefData.Y.ToArray());
                else
                    fitvec = new DenseVector(this.FitData.Y.ToArray());

                return (Vector)(fvec - fitvec);
            }

            public double[] InitCoefficients { set; get; }

            public DataSet FitData  { get; set; }
            public DataSet RefData  { get; set; }
            public double Direction { get; set; }

            public double XShift { get; set; }
            public double YShift { get; set; }
            public double XScale { get; set; }
            public double YScale { get; set; }
        }
    }
}

