playing devil's advocate I'd say use Algorithmic Differentiation
instead of finite differences ;)
that would probably speed things up quite a lot.



On Tue, May 4, 2010 at 11:36 PM, Davide Lasagna <lasagnadav...@gmail.com> wrote:
> If your x data are equispaced I would do something like this
> def derive( func, x):
> """
>         Approximate the first derivative of  function func at points x.
> """
> # compute the values of y = func(x)
> y = func(x)
> # compute the step
> dx = x[1] - x[0]
> # kernel array for second order accuracy centered first derivative
> kc = np.array([-1.0, +0.0, +1.0]) / 2 / dx
> # kernel array for second order accuracy left and right first derivative
> kl = np.array([-3.0, +4.0, -1.0]) / 2 / dx
> kr = np.array([+1.0, -4.0, +3.0]) / 2 / dx
> # correlate it with the original array,
> # note that only the valid computation are performed
> derivs_c = np.correlate( y, kc, mode='valid'  )
> derivs_r = np.correlate( y[-3:], kr, mode='valid'  )
> derivs_l = np.correlate( y[:+3], kl, mode='valid'  )
> return np.r_[derivs_l, derivs_c, derivs_r]
> This is actually quite fast: on my machine (1.7GHz) i have this.
>>>>:x = np.linspace(0,2*np.pi, 1e6)
>>>>:func = lambda x: np.sin(x)
>>>>:timeit derive(func, x)
> 10 loops, best of 3: 177 ms per loop
> I'm curious if someone comes up with something faster.
>
> Regards,
> Davide
>
> On 4 May 2010 22:17, <josef.p...@gmail.com> wrote:
>>
>> On Tue, May 4, 2010 at 4:06 PM, gerardob <gberbeg...@gmail.com> wrote:
>> >
>> > Hello, I have written a very simple code that computes the gradient by
>> > finite
>> > differences of any general function. Keeping the same idea, I would like
>> > modify the code using numpy to make it faster.
>> > Any ideas?
>> > Thanks.
>> >
>> >       def grad_finite_dif(self,x,user_data = None):
>> >                assert len(x) == self.number_variables
>> >                points=[]
>> >                for j in range(self.number_variables):
>> >                        points.append(x.copy())
>> >
>> >  points[len(points)-1][j]=points[len(points)-1][j]+0.0000001
>> >                delta_f = []
>> >                counter=0
>> >                for j in range(self.number_variables):
>> >
>> >  delta_f.append((self.eval(points[counter])-self.eval(x))/0.0000001)
>>
>> it looks like your are evaluating the same point several times
>> self.eval(x)
>>
>> >                        counter = counter + 1
>> >                return array(delta_f)
>>
>> That's what I used as a pattern for a gradient function
>>
>> #from scipy.optimize
>> def approx_fprime(xk,f,epsilon,*args):
>>    f0 = f(*((xk,)+args))
>>    grad = np.zeros((len(xk),), float)
>>    ei = np.zeros((len(xk),), float)
>>    for k in range(len(xk)):
>>        ei[k] = epsilon
>>        grad[k] = (f(*((xk+ei,)+args)) - f0)/epsilon
>>        ei[k] = 0.0
>>    return grad
>>
>> Josef
>>
>> > --
>> > View this message in context:
>> > http://old.nabble.com/Improvement-of-performance-tp28452458p28452458.html
>> > Sent from the Numpy-discussion mailing list archive at Nabble.com.
>> >
>> > _______________________________________________
>> > NumPy-Discussion mailing list
>> > NumPy-Discussion@scipy.org
>> > http://mail.scipy.org/mailman/listinfo/numpy-discussion
>> >
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion@scipy.org
>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
>
_______________________________________________
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion

Reply via email to