https://github.com/ElsevierSoftwareX/SOFTX_2019_219
Raw File
Tip revision: 99932db9e71d31a76425d68eef7d5859523ca0e4 authored by Konrad Werys on 04 November 2019, 09:33:32 UTC
doc: changes in the documentation
Tip revision: 99932db
OxFunctionsT1.h
/*!
 * \file OxFunctionsT1.h
 * \author Konrad Werys
 * \date 2018/07/29
 */

#ifndef Tomato_OXFUNCTIONST1_H
#define Tomato_OXFUNCTIONST1_H

#include "KWUtil.h"
#include <iostream>

namespace Ox {

    /**
     * \class FunctionsT1
     * \brief Container for a model function, cost function and Least-Squares function. And derivatives.
     * \details Here model function is defined - calcModelValue(). Fitting algorithms based on optimisation need a cost
     * function - calcCostValue(). Fitting algorithms based on least squares need a residuals calculation -
     * calcLSResiduals(). Some fitting algorithms use derivatives, hence calcLSJacobian() and calcCostDerivative().
     * The memeber variables are pointers to c-arrays, we need to know how many samples we want to process. Thats the
     * nSamples defined in the constructor.
     * @tparam MeasureType
     */
    template< typename MeasureType >
    class FunctionsT1{

    public:

        /**
         * calcModelValue the most important function of this class
         * @param time
         * @return model(time)
         */
        virtual MeasureType calcModelValue(const MeasureType* parameters, MeasureType time) = 0;

        /**
         * calcLSResiduals the most important function of this class
         * @param residuals
         */
        virtual void calcLSResiduals(const MeasureType* parameters, MeasureType* residuals) = 0;

        /**
         * calcCostValue the most important function of this class
         * @return
         */
        virtual MeasureType calcCostValue(const MeasureType* parameters) = 0;

        /**
         * calcCostDerivative the most important function of this class
         * @param derivative
         */
        virtual void calcCostDerivative(const MeasureType* parameters, MeasureType* derivative) = 0;

        /**
         * calcLSJacobian the most important function of this class
         * @param jacobian - 2d matrix stored as 1d array
         */
        virtual void calcLSJacobian(const MeasureType* parameters, MeasureType* jacobian) = 0;

        // getters
        virtual int getNSamples() { return _nSamples; }
        virtual const MeasureType *getInvTimes() const { return _InvTimes; }
        virtual const MeasureType *getEchoTimes() const { return _EchoTimes; }
        virtual const MeasureType *getRepTimes() const { return _RepTimes; }
        virtual const MeasureType *getRelAcqTimes() const { return _RelAcqTimes; }
        virtual const MeasureType *getSignal() const { return _Signal; }
        virtual int getNDims() { return _nDims; }

        // setters
        void setNSamples(int _nSamples) {
            FunctionsT1::_nSamples = _nSamples;
            _Residuals = new MeasureType[_nSamples];
        }
        virtual void setInvTimes(const MeasureType *_InvTimes) { FunctionsT1::_InvTimes = _InvTimes; }
        virtual void setEchoTimes(const MeasureType *_EchoTimes) { FunctionsT1::_EchoTimes = _EchoTimes; }
        virtual void setRepTimes(const MeasureType *_RepTimes) { FunctionsT1::_RepTimes = _RepTimes; }
        virtual void setRelAcqTimes(const MeasureType *_RelAcqTimes) { FunctionsT1::_RelAcqTimes = _RelAcqTimes; }
        virtual void setSignal(const MeasureType *_Signal) {FunctionsT1::_Signal = _Signal; }

        /**
         * \brief show me your FunctionsT1
         */
        virtual void disp(){
            int nSamples = this->getNSamples();
            std::cout << "\nYou called disp() on a FunctionsT1 object " << this << " with nSamples: " << getNSamples();
            KWUtil::printArray((bool)_InvTimes, nSamples, _InvTimes,       (char*)"\nInvTimes:    ");
            KWUtil::printArray((bool)_EchoTimes, nSamples, _EchoTimes,       (char*)"\nEchoTimes:    ");
            KWUtil::printArray((bool)_RepTimes, nSamples, _RepTimes,       (char*)"\nRepTimes:    ");
            KWUtil::printArray((bool)_RelAcqTimes, nSamples, _RelAcqTimes, (char*)"\nRelAcqTimes: ");
            KWUtil::printArray((bool)_Signal, nSamples, _Signal,           (char*)"\nSignal:      ");
            std::cout << std::endl;
        }

        /**
         * \brief set all the pointers to zero
         */
        void setAllPointersToNull(){
            _InvTimes = 0;
            _EchoTimes = 0;
            _RepTimes = 0;
            _RelAcqTimes = 0;
            _Signal = 0;
        }

        /**
         * \brief constructor
         */
        FunctionsT1(){
            //std::cout << "FunctionsT1 constructor" << std::endl;

            _nSamples = 0;
            _nDims = 0;

            _Residuals = 0; // pointer
            setAllPointersToNull();
        };

        /**
         * \brief copy constructor keeps only _nSamples and _nDims
         * @param old
         */
        FunctionsT1(const FunctionsT1 &old) {
            //std::cout<<"FunctionsT1 copy constructor "<<std::endl;

            _nSamples = old._nSamples;
            _nDims = old._nDims;

            _Residuals = new MeasureType[_nSamples];
            setAllPointersToNull();
        }

        /**
         * cloning
         * @return
         */
        virtual FunctionsT1<MeasureType> *newByCloning() = 0;

        /**
         * \brief do not forget about the virtual destructor, see
         * https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors
         */
        virtual ~FunctionsT1(){
            delete [] _Residuals;
        };

    protected:

        const MeasureType* _InvTimes;
        const MeasureType* _EchoTimes;
        const MeasureType* _RepTimes;
        const MeasureType* _RelAcqTimes;
        const MeasureType* _Signal;
        int _nSamples;
        int _nDims;

        // helper variables
        MeasureType* _Residuals;
    };
} //namespace Ox

#endif //Tomato_OXFUNCTIONST1_H
back to top