1 /**************************************************************************/
2 /*  Copyright 2012 Tim Day                                                */
3 /*                                                                        */
4 /*  This file is part of Evolvotron                                       */
5 /*                                                                        */
6 /*  Evolvotron is free software: you can redistribute it and/or modify    */
7 /*  it under the terms of the GNU General Public License as published by  */
8 /*  the Free Software Foundation, either version 3 of the License, or     */
9 /*  (at your option) any later version.                                   */
10 /*                                                                        */
11 /*  Evolvotron is distributed in the hope that it will be useful,         */
12 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
13 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
14 /*  GNU General Public License for more details.                          */
15 /*                                                                        */
16 /*  You should have received a copy of the GNU General Public License     */
17 /*  along with Evolvotron.  If not, see <http://www.gnu.org/licenses/>.   */
18 /**************************************************************************/
19 
20 /*! \file
21   \brief Interfaces and implementation for specific Function classes.
22   As much as possible of the implementation should be pushed into the FunctionBoilerplate template.
23 */
24 
25 #ifndef _functions_arithmetic_h_
26 #define _functions_arithmetic_h_
27 
28 #include "common.h"
29 
30 #include "function_boilerplate.h"
31 
32 //------------------------------------------------------------------------------------------
33 
34 FUNCTION_BEGIN(FunctionAdd,0,2,false,0)
35 
36   //! Evaluate function.
evaluate(const XYZ & p)37   virtual const XYZ evaluate(const XYZ& p) const
38     {
39       return arg(0)(p)+arg(1)(p);
40     }
41 
42 FUNCTION_END(FunctionAdd)
43 
44 //------------------------------------------------------------------------------------------
45 
46 FUNCTION_BEGIN(FunctionMultiply,0,2,false,0)
47 
48   //! Evaluate function.
evaluate(const XYZ & p)49   virtual const XYZ evaluate(const XYZ& p) const
50     {
51       const XYZ v0(arg(0)(p));
52       const XYZ v1(arg(1)(p));
53       // NB Don't use v0*v1 as it would be cross-product.
54       return XYZ(v0.x()*v1.x(),v0.y()*v1.y(),v0.z()*v1.z());
55     }
56 
57 FUNCTION_END(FunctionMultiply)
58 
59 //------------------------------------------------------------------------------------------
60 
61 FUNCTION_BEGIN(FunctionDivide,0,2,false,0)
62 
63   //! Evaluate function.
evaluate(const XYZ & p)64   virtual const XYZ evaluate(const XYZ& p) const
65     {
66       const XYZ v0(arg(0)(p));
67       const XYZ v1(arg(1)(p));
68 
69       return XYZ(
70 		 (v1.x()==0.0 ? 0.0 : v0.x()/v1.x()),
71 		 (v1.y()==0.0 ? 0.0 : v0.y()/v1.y()),
72 		 (v1.z()==0.0 ? 0.0 : v0.z()/v1.z())
73 		 );
74 
75     }
76 
77 FUNCTION_END(FunctionDivide)
78 
79 //------------------------------------------------------------------------------------------
80 
81 FUNCTION_BEGIN(FunctionMax,0,2,false,0)
82 
83   //! Evaluate function.
evaluate(const XYZ & p)84   virtual const XYZ evaluate(const XYZ& p) const
85     {
86       const XYZ v0(arg(0)(p));
87       const XYZ v1(arg(1)(p));
88       return XYZ(
89 		 std::max(v0.x(),v1.x()),
90 		 std::max(v0.y(),v1.y()),
91 		 std::max(v0.z(),v1.z())
92 		 );
93     }
94 
95 FUNCTION_END(FunctionMax)
96 
97 //------------------------------------------------------------------------------------------
98 
99 FUNCTION_BEGIN(FunctionMin,0,2,false,0)
100 
101   //! Evaluate function.
evaluate(const XYZ & p)102   virtual const XYZ evaluate(const XYZ& p) const
103     {
104       const XYZ v0(arg(0)(p));
105       const XYZ v1(arg(1)(p));
106       return XYZ(
107 		 std::min(v0.x(),v1.x()),
108 		 std::min(v0.y(),v1.y()),
109 		 std::min(v0.z(),v1.z())
110 		 );
111     }
112 
113 FUNCTION_END(FunctionMin)
114 
115 //------------------------------------------------------------------------------------------
116 
117 //! Function returning components of one function modulus thos of another.
118 /*! Sane always-positive modulus used to avoid funny business at zero.
119  */
120 FUNCTION_BEGIN(FunctionModulus,0,2,false,0)
121 
122   //! Evaluate function.
evaluate(const XYZ & p)123   virtual const XYZ evaluate(const XYZ& p) const
124     {
125       const XYZ v0(arg(0)(p));
126       const XYZ v1(arg(1)(p));
127       return XYZ(
128 		 modulusf(v0.x(),fabs(v1.x())),
129 		 modulusf(v0.y(),fabs(v1.y())),
130 		 modulusf(v0.z(),fabs(v1.z()))
131 		 );
132     }
133 
134 FUNCTION_END(FunctionModulus)
135 
136 //------------------------------------------------------------------------------------------
137 
138 FUNCTION_BEGIN(FunctionExp,0,0,false,0)
139 
140   //! Evaluate function.
evaluate(const XYZ & p)141   virtual const XYZ evaluate(const XYZ& p) const
142     {
143       return XYZ(exp(p.x()),exp(p.y()),exp(p.z()));
144     }
145 
146 FUNCTION_END(FunctionExp)
147 
148 //------------------------------------------------------------------------------------------
149 
150 FUNCTION_BEGIN(FunctionSin,0,0,false,0)
151 
152   //! Evaluate function.
evaluate(const XYZ & p)153   virtual const XYZ evaluate(const XYZ& p) const
154     {
155       return XYZ(sin(p.x()),sin(p.y()),sin(p.z()));
156     }
157 
158 FUNCTION_END(FunctionSin)
159 
160 //------------------------------------------------------------------------------------------
161 
162 FUNCTION_BEGIN(FunctionCos,0,0,false,0)
163 
164   //! Evaluate function.
evaluate(const XYZ & p)165   virtual const XYZ evaluate(const XYZ& p) const
166     {
167       return XYZ(cos(p.x()),cos(p.y()),cos(p.z()));
168     }
169 
170 FUNCTION_END(FunctionCos)
171 
172 //------------------------------------------------------------------------------------------
173 
174 #endif
175