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

Reply via email to