function.h 3.56 KB
Newer Older
1 2
/* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions

3
   Copyright (C) 2013, 2014, 2016 Inria
4 5 6 7 8 9 10

   This file is part of ALTA.

   This Source Code Form is subject to the terms of the Mozilla Public
   License, v. 2.0.  If a copy of the MPL was not distributed with this
   file, You can obtain one at http://mozilla.org/MPL/2.0/.  */

11 12 13 14 15 16 17 18 19 20 21 22 23
#pragma once

// Include STL
#include <vector>
#include <string>

// Interface
#include <core/function.h>
#include <core/rational_function.h>
#include <core/data.h>
#include <core/fitter.h>
#include <core/args.h>
#include <core/common.h>
24
#include <core/params.h>
25

26 27
using namespace alta;

28
//#define ADAPT_TO_PARAM
29 30
//#define FIT_DIFFUSE

Laurent Belcour's avatar
Laurent Belcour committed
31 32 33
/*! 
 *  \ingroup functions
 *  \brief A lafortune lobe class. It is provided for testing with the nonlinear
34 35 36 37 38 39
 *  fitting algorithms.
 *
 *  \details
 *  A lafortune lobe is defined as \f$k_d + (L^T M V)^n\f$. We fit the restricted
 *  version where the M matrix is diagonal of coefficients \f$(Cx, Cy, Cz)\f$
 *  \todo Fitting the diffuse part is not stable
40
 *
41
 *  \author Laurent Belcour \<laurent.belcour@umontreal.ca\>
42
 */
43
class lafortune_function : public nonlinear_function
44 45 46 47
{

	public: // methods

48
        lafortune_function(const alta::parameters& params);
49

50
        // Overload the function operator
51 52
		virtual vec operator()(const vec& x) const ;
		virtual vec value(const vec& x) const ;
53
		virtual vec value(const vec& x, const vec& p);
54 55

		//! \brief Load function specific files
56
        virtual bool load(std::istream& in) ;
57

58 59 60 61
        // Save functions
        void save_body(std::ostream& out, const arguments& args) const;
        void save_call(std::ostream& out, const arguments& args) const;

62
		//! \brief Boostrap the function by defining the diffuse term
63
		virtual void bootstrap(const ptr<data> d, const arguments& args);
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106

		//! \brief Number of parameters to this non-linear function
		virtual int nbParameters() const ;

		//! \brief Get the vector of parameters for the function
		virtual vec parameters() const ;

		//! \brief Update the vector of parameters for the function
		virtual void setParameters(const vec& p) ;

		//! \brief Obtain the derivatives of the function with respect to the
		//! parameters. 
		virtual vec parametersJacobian(const vec& x) const ;

		//! \brief Provide the parametrization of the input space of the function.
		//! For this one, we fix that the parametrization is in THETAD_PHID
		virtual params::input parametrization() const
		{
#ifdef ADAPT_TO_PARAM
			return _in_param;
#else
			return params::CARTESIAN ;
#endif
		}
		virtual void setParametrization(params::input new_param)
		{
#ifdef ADAPT_TO_PARAM
			_in_param = new_param;
#else
			std::cerr << "<<ERROR>> Cannot change the ouput parametrization " << __FILE__ << ":" << __LINE__ << std::endl;
			throw;
#endif
		}

        //! \brief Set the number of lobes to be used in the fit
        void setNbLobes(int N);

	private: // methods

		//! \brief Provide the coefficient of the monochromatic lobe number
		//! n for the color channel number c.
		void getCurrentLobe(int n, int c, double& Cx, double& Cy, double& Cz, double& N) const 
		{
107
            const int _nY = _parameters.dimY();
108 109 110 111 112 113 114 115 116 117 118 119
			if(_isotropic)
			{
				Cx = _C[(n*_nY + c)*2 + 0];
				Cy = Cx;
				Cz = _C[(n*_nY + c)*2 + 1];
			}
			else
			{
				Cx = _C[(n*_nY + c)*3 + 0];
				Cy = _C[(n*_nY + c)*3 + 1];
				Cz = _C[(n*_nY + c)*3 + 2];
			}
120 121 122 123 124 125 126 127 128 129
			N  = _N[n*_nY + c];
		}


	private: // data

		//! \brief The lafortune lobe data
		int _n; // Number of lobes
		vec _N, _C; // Lobes data
		vec _kd; // Diffuse term
130 131 132

		//!\brief Flags to get an isotropic lobe
		bool _isotropic;
133 134
} ;