3333#include < assert.h>
3434#include < time.h>
3535#include < chrono>
36-
36+ #include < typeinfo>
37+ #include < type_traits>
3738// command line
3839#include < tclap/CmdLine.h>
3940
4243#include < hydra/device/System.h>
4344#include < hydra/Lambda.h>
4445#include < hydra/Parameter.h>
45- #include < hydra/detail/Compose.h>
46- #include < hydra/detail/Divide.h>
47- #include < hydra/detail/Minus.h>
48- #include < hydra/detail/Multiply.h>
49- #include < hydra/detail/Sum.h>
46+ #include < hydra/FunctorArithmetic.h>
5047#include < hydra/functions/Gaussian.h>
5148
5249
6562
6663using namespace hydra ::arguments;
6764
68- declarg (xvar, double )
69- declarg(yvar, double )
65+ declarg (_u, double )
66+ declarg(_v, double )
67+ declarg(_x, double )
68+ declarg(_y, double )
69+
7070
7171int main(int argv, char ** argc)
7272{
@@ -91,41 +91,59 @@ int main(int argv, char** argc)
9191
9292 auto data = hydra::device::vector< double >(10 , .0 );
9393
94- // Parameters
95- auto mean1 = hydra::Parameter::Create (" mean1" ).Value (-1.0 );
96- auto mean2 = hydra::Parameter::Create (" mean2" ).Value ( 1.0 );
97- auto sigma = hydra::Parameter::Create (" sigma" ).Value (1.0 );
98- auto factor = hydra::Parameter::Create (" factor" ).Value (1.0 );
99-
100- // Gaussian distribution
101- auto gauss1 = hydra::Gaussian<xvar>(mean1, sigma);
102- // LogNormal distribution
103- auto gauss2 = hydra::Gaussian<yvar>(mean2, sigma);
104- //
105-
106- auto combiner = hydra::wrap_lambda ( [] __hydra_dual__ (unsigned int npar, const hydra::Parameter* params, double x, double y) {
107-
108- printf (" Gauss1 %f , Gauss2 %f\n " , x, y );
109- return x + params[0 ]*y;
110- }, factor);
111-
112- auto fcomposed = hydra::compose ( combiner, gauss1, gauss2);
113- auto fdivided = hydra::divide ( gauss1, gauss2 );
114- auto fminus = hydra::minus ( gauss1, gauss2 );
115- auto fmultiply = hydra::multiply ( gauss1, gauss2 , gauss2 );
116- auto fsum = hydra::sum ( gauss1, gauss2 , gauss2 );
117-
118- for (size_t i=0 ; i< data.size (); ++i)
119- {
120- std::cout << " fcomposed: " << fcomposed (xvar (-1.0 ), yvar (1.0 )) << std::endl;
121- std::cout << " fdivided: " << fdivided (xvar (-1.0 ), yvar (1.0 )) << std::endl;
122- std::cout << " fminus: " << fminus (xvar (-1.0 ), yvar (1.0 )) << std::endl;
123- std::cout << " fmultiply: " << fmultiply (xvar (-1.0 ), yvar (1.0 )) << std::endl;
124- std::cout << " fsum: " << fsum (xvar (-1.0 ), yvar (1.0 )) << std::endl;
125-
126- }
127-
12894
95+ // Parameters
96+ auto mean_x = hydra::Parameter::Create (" mean_x" ).Value (-0.5 );
97+ auto mean_y = hydra::Parameter::Create (" mean_y" ).Value (0.6 );
98+ auto mean_u = hydra::Parameter::Create (" mean_u" ).Value (-0.5 );
99+ auto mean_v = hydra::Parameter::Create (" mean_v" ).Value (0.6 );
100+ auto sigma = hydra::Parameter::Create (" sigma" ).Value (1.0 );
101+ auto exponent = hydra::Parameter::Create (" exponent" ).Value (2.0 );
102+
103+ // build the expression
104+ // [ ( G(x)-G(y) ) / ( G(x) + G(y) ) + ( G(u)-G(v) ) / ( G(u) + G(v) ) ]^z
105+ // using symbolic mathematics
106+
107+ // Gaussian distributions
108+ auto Gx = hydra::Gaussian<_x>(mean_x, sigma);
109+ auto Gy = hydra::Gaussian<_y>(mean_y, sigma);
110+ auto Gu = hydra::Gaussian<_u>(mean_u, sigma);
111+ auto Gv = hydra::Gaussian<_v>(mean_v, sigma);
112+
113+ auto Axy = (Gx - Gy)/(Gx + Gy);
114+ auto Auv = (Gu - Gv)/(Gu + Gv);
115+ auto A = Axy + Auv;
116+
117+ auto powerz = hydra::wrap_lambda ( [] __hydra_dual__ (unsigned int npar, const hydra::Parameter* params, double x )
118+ {
119+
120+ return ::pow (x, params[0 ]);
121+
122+ }, exponent );
123+
124+ auto Total = hydra::compose (powerz, A );
125+
126+ // print parameters
127+ Total.PrintRegisteredParameters ();
128+
129+ // evaluate using named function arguments
130+ std::cout << Total ( _x (1.0 ), _y (-1.0 ), _v (1.0 ), _u (-1.0 )) << std::endl;
131+ // evaluate using named function arguments (changed order)
132+ std::cout << Total ( _y (-1.0 ), _x (1.0 ), _u (-1.0 ), _v (1.0 )) << std::endl;
133+ // evaluate using tuple of unamed arguments (risky!!!)
134+ std::cout << Total ( hydra::make_tuple (1.0 , -1.0 , 1.0 , -1.0 )) << std::endl;
135+ // evaluate using tuple of unamed arguments (risky!!!)
136+ std::cout << Total ( hydra::make_tuple (-1.0 , 1.0 , -1.0 , 1.0 )) << std::endl;
137+ // evaluate using tuple of unamed arguments (risky!!!)
138+ std::cout << Total ( hydra::make_tuple (1.0 , -1.0 , -1.0 , 1.0 )) << std::endl;
139+ // evaluate using tuple of named arguments ()
140+ std::cout << Total ( hydra::make_tuple ( _x (1.0 ), _y (-1.0 ), _v (1.0 ), _u (-1.0 ))) << std::endl;
141+
142+
143+ // What is the type of the natural signature of Total?
144+ // uncomment this
145+ // typename decltype(Total)::argument_type test{};
146+ // std::cout << test.dummy << '\n';
129147
130148 return 0 ;
131149}
0 commit comments