Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

[Python] Optimization: determining gradient with variable window size

  1. Nov 21, 2012 #1
    Hi all, I'm not quite sure if this is the right place to post my question, so forgive me if its not...

    I've written a program in Python that analyses data that I got from a compression experiment (mechanical testing of rocks and such), and I've written a piece of code that estimates the gradient of a given quantity. It seems to work fine, but it is very slow. Whereas the rest of the program does its job in about 10 seconds, this little piece of code takes about 4 minutes to execute.

    Code (Text):

    # written in Python
    while not done:
       i += 10
       start = n-i
       end = n+i
       if n-i < 0:
          start = 0
          end = n+2*i
       if n+i > len(data)-1:
          end = len(data)-1
          start = n-i
          if start < 0:
             start = 0
       if absolute(data[start] - data[end]) >= std/0.05:
          done = True
          windows[n] = end - start
    Note that this is an excerpt that takes up almost 100% of the function's computation time, so I left out the rest. What does this piece do? It starts with a window of size 10, then checks if the values of the first and last datapoint in this window differ more than a given value (so that the difference is significant). If they do, the window size is correct, if they don't, the window size grows by 20 and check again, etc. The if statements in there are to make sure the window does not fall outside the data.

    So I know this method works, but I realize this is horribly inefficient, since most window sizes are about 400 in width, some even up to 2000. Having about 500,000 datapoints to process, this loop occurs about 10,000,000 times for the entire dataset. My mathematical basis for these kind of things is not too good, but do you guys perhaps know a more elegant method? Or do you have any other optimization tips?

  2. jcsd
  3. Nov 21, 2012 #2


    User Avatar
    Science Advisor

    Re: Optimization: determining gradient with variable window size

    Your approach is rather sensitive to noise - a single outlier can give you unexpectedly narrow windows at ten-pixel intervals on either side of it. Also, you are handling the ends of the array differently. You either need to change end=n+2*i to just end=n+i in the first if, or start=n-i to start=n-2*i in the second.

    If you're not wedded to this idea, I can offer an alternative:
    - Smooth your function using a Gaussian blur
    - Calculate the gradient of that smoothed function

    It turns out that you can do this by populating an array with the first derivative of a Gaussian function, Fourier transforming it, Fourier transforming your data, multiplying the arrays point-by-point, and inverse Fourier transforming the product. If you can install the numpy library, that will do 99.9% of the hard work for you - happy to help.
  4. Nov 22, 2012 #3
    Re: Optimization: determining gradient with variable window size

    Thanks for the suggestions. What I did not include into this post is that the slope will be calculated using OLS over the number of datapoints that are required to make the slope significant, i.e. the difference between the starting and end point being 20x standard deviation of the noise.

    I've tried smoothing the signal and calculating the gradient using central differences, but that still resulted into very noisy results. More smoothing would result into 'cutting corners' off my data...

    So again, thanks for your suggestions, but I've been there already.
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook