[SciPy-user] Help with array functions

eric jones eric at enthought.com
Tue May 4 10:03:18 CDT 2004


Bob.Cowdery at CGI-Europe.com wrote:

> Hi all,
>  
> Can anyone help me convert this loop to an array function. I can't 
> have loops in my signal processing as they take far too much 
> processing power. This is a fragment from a speech processor using 
> Ferkins formula. Essentially the gain array (m_procGain) which is 2048 
> long (m_sampl_sz) needs its nth element processing into it's (n-1)th 
> element. This is eventually used to multiply the samples in 
> m_complexout, the first 2048 elements of this are used. Attack is a 
> scaler currently 0.4.
>
>                 peak = 
> abs(self.m_complexout[argmax(abs(self.m_complexout[:self.m_sampl_sz]))])
>                 i = arange(1,self.m_sampl_sz)
>                 for x in i:
>                     if abs(self.m_complexout[x-1]) > 0:
>                        self.m_procGain[x] = ( (self.m_procGain[x-1] * 
> (1 - attack)) + ((attack * peak) / abs(self.m_complexout[x-1])) )        
>                        if self.m_procGain[x] > level:
>                            self.m_procGain[x] = level
>                     else:
>                        self.m_procGain[x] = 1
>
The general ideas of uisng Numeric in Python is to avoid loops, even at 
the expense of sometimes doing extra computations.  In this case, the 
signal processing calculations can be done for every entry in the array 
(except the first).  The conditions checked for in the "if" statements 
can then be filtered out in subsequent array processing steps.


Here is some (totally untested) code that should give you some ideas:

    gain = self.m_procGain
    abs_complexout = abs(self.m_complexout)

    # Do singal processing calculation for all elements in array
    gain[1:] = ( (gain[:-1] * (1 - attack)) +
                 ((attack * peak) / abs_complexout[:-1]) )

    # clip the upper values to some level.
    gain = choose(gain > level, (gain, level))

    # if complexout is less than 0, set gain to 1.
    gain = choose(abs_complexout < 0, (gain, 1))

    self.m_procGain = gain

With numarray I think it would look something like this (some numarray 
user correct me if I'm wrong):

    gain = self.m_procGain
    abs_complexout = abs(self.m_complexout)

    # Do singal processing calculation for all elements in array
    gain[1:] = ( (gain[:-1] * (1 - attack)) +
                 ((attack * peak) / abs_complexout[:-1]) )

    # clip the upper values to some level.
    gain[gain > level] = level

    # if complexout is less than 0, set gain to 1.
    gain[abs_complexout < 0] = 1

    # unnecessary because it is a reference to the same array and all 
operations are done using
    # indexing on the LHS.
    self.m_procGain = gain

The numarray code is easier to read.  It also should be more efficient 
(if not now, then eventually).  I really like the arrays as indices to 
arrays...

eric

> Thanks for any assistance.
>  
> Bob
>  
>  
> Bob Cowdery
> CGI Senior Technical Architect
> +44(0)1438 791517
> Mobile: +44(0)7771 532138
> bob.cowdery at cgi-europe.com <mailto:bob.cowdery at cgi-europe.com>
>  
>  
>  
>
> **** Confidentiality Notice **** Proprietary/Confidential
> Information belonging to CGI Group Inc. and its affiliates
> may be contained in this message. If you are not a recipient
> indicated or intended in this message (or responsible for
> delivery of this message to such person), or you think for
> any reason that this message may have been addressed to you
> in error, you may not use or copy or deliver this message
> to anyone else.  In such case, you should destroy this
> message and are asked to notify the sender by reply email.
>
>------------------------------------------------------------------------
>
>_______________________________________________
>SciPy-user mailing list
>SciPy-user at scipy.net
>http://www.scipy.net/mailman/listinfo/scipy-user
>  
>




More information about the SciPy-user mailing list