Improving a piece of code with arrays and for-loops - Idl-pvwave

This is a discussion on Improving a piece of code with arrays and for-loops - Idl-pvwave ; Hello I have been looking at my same piece of IDL-code for quite a while now and I have yet not found any good method to improve it. I want to improve the speed and rid the code of the ...

+ Reply to Thread
Results 1 to 7 of 7

Improving a piece of code with arrays and for-loops

  1. Default Improving a piece of code with arrays and for-loops

    Hello

    I have been looking at my same piece of IDL-code for quite a while now
    and I have yet not found any good method to improve it. I want to
    improve the speed and rid the code of the nested for-loops. Maybe
    there is someone here who has good ideas and is willing to point me in
    the right direction?

    The problematic code is below. It is a part of a method to estimate
    wind gusts in output from an atmospheric model. The i and j
    dimensions are the x- and y-locations of the model-points in the
    horizontal and s are the model level heights in the vertical (starting
    from the model top and growing towards the surface).

    The code works in the vertical, starting from the surface (largest
    value of s) and works upwards (towards smaller s) to where the value
    of the variable tke is less than tkelvl or tke_diff is less than a
    very small number. The code has to do the following three things:

    1. Choose the greatest value of wsp (windspeed) where the value of
    int_diff exceeds 0.
    2. Choose the greatest value of wsp where the value of int_diffver
    exceeds 0.
    3. Choose the greatest value of wsp.

    This has to be repeated for every grid-point in the horizontal (I have
    to assume that I have very little a priori knowledge of the behaviour
    of any of my variables at any gridpoint and model height).

    Any ideas on improving this?

    Thanks in advance,
    Halfdan

    ps. The problematic code:

    for i=1,ni-2 do begin
    for j=1, nj-2 do begin
    s = ns-1
    REPEAT BEGIN
    if int_diff(i,j,s) GE 0. AND wsp(i,j,s) GT fgtmp(i,j,
    0) then $
    fgtmp(i,j,0) = wsp(i,j,s)
    if wsp(i,j,s) GT fgtmp(i,j,1) then $
    fgtmp(i,j,1) = wsp(i,j,s)
    if int_diffver(i,j,s) GE 0. AND wsp(i,j,s) GT
    fgtmp(i,j,2) then $
    fgtmp(i,j,2) = wsp(i,j,s)
    s=s-1
    ENDREP UNTIL tke(i,j,s) LT tkelvl(i,j) OR
    tke_diff(i,j,s) LT eps
    endfor
    endfor


  2. Default Re: Improving a piece of code with arrays and for-loops

    On Feb 8, 7:23 am, "Halfdan" <halfd...@gmail.com> wrote:
    > Hello
    >
    > I have been looking at my same piece of IDL-code for quite a while now
    > and I have yet not found any good method to improve it. I want to
    > improve the speed and rid the code of the nested for-loops. Maybe
    > there is someone here who has good ideas and is willing to point me in
    > the right direction?
    >
    > The problematic code is below. It is a part of a method to estimate
    > wind gusts in output from an atmospheric model. The i and j
    > dimensions are the x- and y-locations of the model-points in the
    > horizontal and s are the model level heights in the vertical (starting
    > from the model top and growing towards the surface).
    >
    > The code works in the vertical, starting from the surface (largest
    > value of s) and works upwards (towards smaller s) to where the value
    > of the variable tke is less than tkelvl or tke_diff is less than a
    > very small number. The code has to do the following three things:
    >
    > 1. Choose the greatest value of wsp (windspeed) where the value of
    > int_diff exceeds 0.
    > 2. Choose the greatest value of wsp where the value of int_diffver
    > exceeds 0.
    > 3. Choose the greatest value of wsp.
    >
    > This has to be repeated for every grid-point in the horizontal (I have
    > to assume that I have very little a priori knowledge of the behaviour
    > of any of my variables at any gridpoint and model height).
    >
    > Any ideas on improving this?
    >
    > Thanks in advance,
    > Halfdan
    >
    > ps. The problematic code:
    >
    > for i=1,ni-2 do begin
    > for j=1, nj-2 do begin
    > s = ns-1
    > REPEAT BEGIN
    > if int_diff(i,j,s) GE 0. AND wsp(i,j,s) GT fgtmp(i,j,
    > 0) then $
    > fgtmp(i,j,0) = wsp(i,j,s)
    > if wsp(i,j,s) GT fgtmp(i,j,1) then $
    > fgtmp(i,j,1) = wsp(i,j,s)
    > if int_diffver(i,j,s) GE 0. AND wsp(i,j,s) GT
    > fgtmp(i,j,2) then $
    > fgtmp(i,j,2) = wsp(i,j,s)
    > s=s-1
    > ENDREP UNTIL tke(i,j,s) LT tkelvl(i,j) OR
    > tke_diff(i,j,s) LT eps
    > endfor
    > endfor


    First thing that comes to mind is the invert the loop order. Granted
    I've spent about 30 s looking at this, though.


  3. Default Re: Improving a piece of code with arrays and for-loops

    On Feb 8, 11:53 am, "hradilv" <hrad...@yahoo.com> wrote:
    > On Feb 8, 7:23 am, "Halfdan" <halfd...@gmail.com> wrote:
    >
    >
    >
    > > Hello

    >
    > > I have been looking at my same piece of IDL-code for quite a while now
    > > and I have yet not found any good method to improve it. I want to
    > > improve the speed and rid the code of the nested for-loops. Maybe
    > > there is someone here who has good ideas and is willing to point me in
    > > the right direction?

    >
    > > The problematic code is below. It is a part of a method to estimate
    > > wind gusts in output from an atmospheric model. The i and j
    > > dimensions are the x- and y-locations of the model-points in the
    > > horizontal and s are the model level heights in the vertical (starting
    > > from the model top and growing towards the surface).

    >
    > > The code works in the vertical, starting from the surface (largest
    > > value of s) and works upwards (towards smaller s) to where the value
    > > of the variable tke is less than tkelvl or tke_diff is less than a
    > > very small number. The code has to do the following three things:

    >
    > > 1. Choose the greatest value of wsp (windspeed) where the value of
    > > int_diff exceeds 0.
    > > 2. Choose the greatest value of wsp where the value of int_diffver
    > > exceeds 0.
    > > 3. Choose the greatest value of wsp.

    >
    > > This has to be repeated for every grid-point in the horizontal (I have
    > > to assume that I have very little a priori knowledge of the behaviour
    > > of any of my variables at any gridpoint and model height).

    >
    > > Any ideas on improving this?

    >
    > > Thanks in advance,
    > > Halfdan

    >
    > > ps. The problematic code:

    >
    > > for i=1,ni-2 do begin
    > > for j=1, nj-2 do begin
    > > s = ns-1
    > > REPEAT BEGIN
    > > if int_diff(i,j,s) GE 0. AND wsp(i,j,s) GT fgtmp(i,j,
    > > 0) then $
    > > fgtmp(i,j,0) = wsp(i,j,s)
    > > if wsp(i,j,s) GT fgtmp(i,j,1) then $
    > > fgtmp(i,j,1) = wsp(i,j,s)
    > > if int_diffver(i,j,s) GE 0. AND wsp(i,j,s) GT
    > > fgtmp(i,j,2) then $
    > > fgtmp(i,j,2) = wsp(i,j,s)
    > > s=s-1
    > > ENDREP UNTIL tke(i,j,s) LT tkelvl(i,j) OR
    > > tke_diff(i,j,s) LT eps
    > > endfor
    > > endfor

    >
    > First thing that comes to mind is the invert the loop order. Granted
    > I've spent about 30 s looking at this, though.


    Another thing that comes to mind is trying to make a "mask" of the of
    the layers and applying that mask:

    instead of if int_diff[i,j,s] gt 0, use id_mask = int_diff[*,*,s] > 0
    then idx = where(id_mask gt 0, count) - then change only those idx
    points.


  4. Default Re: Improving a piece of code with arrays and for-loops

    Thank you for the advice.

    I always manage to mix up the order of the indices in
    the for loops. No matter how often I write them.

    I will try the "mask"-method. I had thought of something
    in this direction but never managed to get the method
    and the code right

    ha


  5. Default Re: Improving a piece of code with arrays and for-loops

    How about this:

    ; indsetmin (s never goes there)
    indsetmin=where((tke lt rebin(tkelvl,ni,nj,ns)) or (tke_diff lt eps))

    ; Set windspeeds to the minimum value (you can also take 0,
    ; if these speeds never go below zero, which seems logical ;-))
    wspmin=min(wsp)
    wsp[indsetmin]=wspmin

    ; Maximum wsp
    fgtmp[*,*,2]=max(wsp, DIMENSION=3)

    ; Maximum wsp where (int_diff ge 0)
    wsptmp=wsp
    wsptmp[where(int_diff lt 0)]=wspmin
    fgtmp[*,*,0]=max(wsptmp, DIMENSION=3)

    ; Maximum wsp where (int_diffver ge 0)
    wsp[where(int_diffver lt 0)]=wspmin
    fgtmp[*,*,2]=max(wsp, DIMENSION=3)



    On 8 Feb 2007 05:23:53 -0800, "Halfdan" <halfdana@gmail.com> wrote:

    > for i=1,ni-2 do begin
    > for j=1, nj-2 do begin
    > s = ns-1
    > REPEAT BEGIN
    > if int_diff(i,j,s) GE 0. AND wsp(i,j,s) GT fgtmp(i,j,
    >0) then $
    > fgtmp(i,j,0) = wsp(i,j,s)
    > if wsp(i,j,s) GT fgtmp(i,j,1) then $
    > fgtmp(i,j,1) = wsp(i,j,s)
    > if int_diffver(i,j,s) GE 0. AND wsp(i,j,s) GT
    >fgtmp(i,j,2) then $
    > fgtmp(i,j,2) = wsp(i,j,s)
    > s=s-1
    > ENDREP UNTIL tke(i,j,s) LT tkelvl(i,j) OR
    >tke_diff(i,j,s) LT eps
    > endfor
    > endfor



  6. Default Re: Improving a piece of code with arrays and for-loops

    On Fri, 09 Feb 2007 13:55:38 +0100, Wox <nomail@hotmail.com> wrote:

    <snip>

    >; Maximum wsp where (int_diffver ge 0)
    >wsp[where(int_diffver lt 0)]=wspmin
    >fgtmp[*,*,2]=max(wsp, DIMENSION=3)


    must be fgtmp[*,*,1]

  7. Default Re: Improving a piece of code with arrays and for-loops

    I got the method to work correctly with slight modifications. It
    might be a bit late but her goes.

    I realized that my possible s-levels were not continous, i.e. there
    could be "valid" s-levels away from the surface with "illegal" levels
    in between. I therefore had to put a more stringent conditions on the
    possible s-values as I only want the continous stretch of "valid"
    levels near the surface.

    I also choose some sensible values for wsp when the method would
    otherwise give 0.




    ; What s-values are not possible?
    idx = intarr(ni,nj,ns)
    idx[where( tke LT rebin(tkelvl,ni,nj,ns) or tke_diff LT eps)] =
    1
    idx = reverse ( total( reverse(idx, 3), 3, /cumulative), 3)

    ; What s-values are not possible?
    indsetmin=where( idx NE 0 )

    ; Zero value for the wind
    wsptmp=wsp
    wspmin=0.
    wsptmp[indsetmin]=wspmin

    ; Max wsp
    fgtmp[*,*,1]=max(wsptmp, DIMENSION=3) > wsp[*,*,ns-1]

    ; Max wsp where(int_diff lt 0.)
    wsptmp[where(int_diff lt 0.)]=wspmin
    fgtmp[*,*,0]=max(wsptmp, DIMENSION=3) > wsp[*,*,ns-1]

    ; max wsp where (int_diffver lt 0)
    wsptmp[where(int_diffver lt 0.)]=wspmin
    fgtmp[*,*,2]=max(wsptmp, DIMENSION=3) > wsp[*,*,ns-1]


+ Reply to Thread

Similar Threads

  1. Setting up object arrays - loops not loopng enough times
    By Application Development in forum Java
    Replies: 9
    Last Post: 10-20-2007, 08:23 PM
  2. Could you help me to explain this piece of code
    By Application Development in forum lisp
    Replies: 10
    Last Post: 07-19-2007, 10:47 AM
  3. Get the piece of code in perl
    By Application Development in forum Perl
    Replies: 4
    Last Post: 06-20-2007, 01:35 PM
  4. Need hint to use FOR loops using 3-D arrays
    By Application Development in forum Idl-pvwave
    Replies: 2
    Last Post: 06-12-2007, 05:43 AM
  5. Is it really more efficient to work with arrays than FOR loops?
    By Application Development in forum Idl-pvwave
    Replies: 4
    Last Post: 11-24-2006, 05:34 AM