Not very much faster but more elegant, replacing the for-loop:

   10 ts 'loop test 55'
0.057558227 16816768

   10 ts 'outf test 55'
0.052024896 20978048

   (outf test 55)-:loop test 55
1

with 

   'rotate oblique loop outf' =: i.4

and 

ProjOutf=: 3 : 0
    'pop new srv'=:y
 new=. 1 0 2 |: new NB. it makes it easy to loop on the first dimention
 p=.  pop,"3 4(new,"1(0)),"0 1"2 3(0,"2 srv)
 q=.(*(-1 1)|.!.1 "1 2 ])/\.&.|. p
1 0 2 3 |:}:"1}:"2 q
)


R.E. Boss


-----Oorspronkelijk bericht-----
Van: [email protected]
[mailto:[email protected]] Namens Robert Cyr
Verzonden: zaterdag 21 maart 2009 15:55
Aan: Programming forum
Onderwerp: Re: [Jprogramming] Oblique can be slow

In this case, the simple looping solution is 20 times faster than the
oblique solution, as it avoids some unnecessary calculations and
manipulation of data.  It is also makes for easier reading and maintenance

Noting that the population data is basically triangular(age service) where
age-service >= 0 is of little use as we cannot easily create create and use
a triangular matrix.

try these:

'rotate oblique loop' =. i.3

   ts 'rotate test 55'
0.203641 9.71485e7

   ts 'oblique test 55'
0.854339 6.29294e7

----------------------------------------
and the winner is...
----------------------------------------
   ts 'loop test 55'
0.0385865 1.68559e7
----------------------------------------

test=: 3 : 0
NB. x: 0 for projection, 1 for rotation
NB. y: number of age and service
:
    POP=:((>:/)~i.y)*"2 (1000*i.2)+/(100*i.y)+/1+i.y NB. SERVICE AGE
    QR=: ((>:/)~i.y)*"2 (0.0001* (1000*i.2)+/(100*i.-y)+/1+i.-y) NB. SERVICE
AGE
    NV=: (2, y+4,0) $,10000+(100*i.y+4)+/i.y NB. ANS AGE
    projrotate`projoblique`[email protected] POP;NV;QR
 )

ProjLoop=: 3 : 0
    'pop new srv'=.y
 new=. 1 0 2 |: new NB. it makes it easy to loop on the first dimention
 p=.  pop,"3 4(new,"1(0)),"0 1"2 3(0,"2 srv)
    for_t. i._1+#p do.
        p=.(((t+1){p)*(-1 1)|.!.1 "1 2 t{p)(t+1)}p
    end.
1 0 2 3 |:}:"1}:"2 p
)

ProjRotate=: 3 : 0
NB. Population projection using rotation
NB. result by sex year age service will allow us to determine the probable
aging of our population.
NB. pop: number of active employees by sex(2), age(55=16 to 70), service(55
= 0 to 54)
NB. new: number of new employees by sex(2), year of employment(50=years of
projection), age(55)
NB. srv: probability of survival (not dying,quitting or retiring) by
sex(2),age(55),service(55)
    'pop new srv'=.y
    p=. pop,"2 3 (new,"1 (0)),"0 1"1 2 (0,"2 srv) NB. setup a matrix :
sex,year of projection, age,service
    'a n'=. (1 0)+ 1}.$new
    r=. (,.)~i.a         NB. to shift each slice to the left and to the top
by 1 for each year of projection
    t=.-(0,0,a,a)+$p     NB. to make space for our rotation
    f=.2,a,1+n,n         NB. to return to the original size
    }:"2}:"1(-f){.(-r)|.!.0"1 2"2 3 */\"3 r |.!.1"1 2"2 3 t{.!.1 p
)


ProjOblique=: 3 : 0
    'pop new srv'=.y
    p=. pop,"2 3 (new,"1 (0)),"0 1"1 2 (0,"2 srv)
    'a n'=. (1 0)+ 1}.$new
    r=.  |."1|."2*//./.\"3|."2|."1 p     NB. this is the 3d oblique
cumulative product, by year of projection
    b=. (1+i.a)|."0 1 ((a,n)#0 1)        NB. eliminate the unused rows of
the oblique
    s=.|:n-(i.n)<./i.a                    NB. a rotation will position the
required results
    n{."1 s|."0 1 " 2 3 b#"1 2"2 3 r     NB. we retain the correct number of
columns
)
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to