2 # Copyright (C) 2012-2015 CEA/DEN, EDF R&D
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 def __init__(self, **kwargs):
26 def function(self, x, **kwargs):
27 # This should be implemented in a derived class
28 raise Runtime("function is not implemented yet")
30 def __call__(self, x):
31 # The argument can be a scalar or a list, we have to check
36 y = self.function(x, **self.kwargs)
41 This returns True if the parameter is an iterable, a list or an
42 array, or any collection object.
51 # =====================================================
52 # Implementation of standard functions. All function are normalized
53 # function: the xrange is [0,1], the yrange is [0,1]
55 from scipy.constants import pi
57 # Note that in this situation, the create another constructor because
58 # the parameters can be deduced from one single parameter xlimit. The
59 # constructor must create a kwargs dictionary that map the arguments
60 # of the method "function"
61 class FuncConique(Function):
62 def __init__(self,xlimit):
63 a = 1./(xlimit*xlimit-2*xlimit+1)
67 # We call the super constructor to redefine the kwarg
68 # attribute, so that it fits with the arguments of the method
70 Function.__init__(self,xlimit=xlimit,a=a,b=b,c=c,d=d)
71 # NOTE: Instead of calling the super constructor, we could
72 # redefine directly the kwargs attribute:
73 #self.kwargs = {"xlimit":xlimit,
77 def function(self,x,xlimit,a,b,c,d):
85 class FuncChapeau(Function):
86 def function(self,x,xlimit):
93 class FuncStiffExp(Function):
95 xlimit : the x position of the top of the function
96 stiffness : the higher it is, the stiffer the function is
98 def function(self,x,xlimit,stiffness):
100 y=numpy.exp(stiffness*(x-xlimit))
102 y=numpy.exp(-stiffness*(x-xlimit))
105 class FuncCosinus(Function):
106 def __init__(self,nbPeriods):
107 # The pulsation w must be choosen so that w*xmax=n*2pi where
108 # xmax=1 and n is an integer that corresponds to the number of
109 # oscilations on the xrange [0,xmax].
111 Function.__init__(self,w=w)
113 def function(self,x,w):
117 class FuncStiffPulse(Function):
118 def __init__(self,xlimit, stiffness, nbPeriods):
119 self.stiffexp=FuncStiffExp(xlimit=xlimit,stiffness=stiffness)
120 self.cosinus=FuncCosinus(nbPeriods=nbPeriods)
121 Function.__init__(self)
123 def function(self,x):
124 y=self.stiffexp(x)*numpy.abs(self.cosinus(x))
127 class FuncHeaviside(Function):
128 def function(self,x,xlimit):
135 class FuncPorte(Function):
136 def function(self,x,xinf,xsup):
144 class FuncLagrange(Function):
145 def __init__(self,points):
147 @points : a dictionary whose keys are x values and values are
148 y values to be considered as fixed points for interpolation.
150 Function.__init__(self)
151 self.polynom = lagrange.lagrange(points)
153 def function(self,x):
154 return self.polynom(x)
157 # =====================================================
158 # Unit tests functions
159 # =====================================================
161 class MyFunction(Function):
162 def function(self,x,a,b):
167 # The parameters of the constructor of MyFunction must be
168 # consistent with the kwargs parameters of the method function of
169 # the class MyFunction (it must map exactly).
170 f=MyFunction(a=3.,b=7.)
182 def TEST_Function_withIterable():
183 f=MyFunction(a=3.,b=1.)
185 arrX = [0., 1., 2., 3.]
188 arrY_ref = [1., 4., 7., 10.]
189 print "arrY res =%s"%arrY
190 print "arrY ref =%s"%arrY_ref
192 def TEST_FuncConique():
193 f=FuncConique(xlimit=0.3)
194 from plotter import plot
197 def TEST_FuncChapeau():
198 f=FuncChapeau(xlimit=0.3)
199 from plotter import plot
202 def TEST_FuncStiffExp():
203 f=FuncStiffExp(xlimit=0.3,stiffness=20.)
204 from plotter import plot
207 def TEST_FuncCosinus():
208 f=FuncCosinus(nbPeriods=20)
209 from plotter import plot
212 def TEST_FuncStiffPulse():
213 f=FuncStiffPulse(xlimit=0.3,stiffness=50,nbPeriods=15)
214 from plotter import plot
217 def TEST_FuncHeaviside():
218 f=FuncHeaviside(xlimit=0.3)
219 from plotter import plot
222 def TEST_FuncPorte():
223 f=FuncPorte(xinf=0.3,xsup=0.4)
224 from plotter import plot
227 def TEST_customize_01():
228 f=FuncStiffPulse(xlimit=0.3,stiffness=40,nbPeriods=20)
230 # One can customize the final function as follow (in this example,
231 # a linear transform)
236 from plotter import plot
237 plot(myfunc, step=0.001)
239 def TEST_customize_02():
240 f=FuncHeaviside(xlimit=0.3)
242 # One can customize the final function as follow (in this example,
243 # reverse of heaviside)
248 from plotter import plot
251 def TEST_FuncLagrange():
252 points = {0.:5, 0.2:10, 0.9:10, 0.6:21, 1:8}
253 f=FuncLagrange(points)
254 from plotter import plot
257 if __name__ == "__main__":
259 TEST_Function_withIterable()
264 #TEST_FuncStiffPulse()
265 #TEST_FuncHeaviside()