age_structured.mws

MTH 455  A DISCRETE LINEAR AGE-STRUCTURED MODEL
JR 2/1/2005  age_structured.mws

See Haberman, Section 35, p138.

> # SET UP THE MATRIX A
restart:

with(LinearAlgebra):

M:=3;

b:=[0,1.7,0.5,0];       # birth rates

d:=[0.2,0.1,0.6,0.9]; # death rates

A:=[seq([seq(0,col=0..M)],row=0..M)]:  #fill A with zeros

for col from 0 to M-1 do

  A[1,col+1]:=b[col+1];

  A[col+2,col+1]:=1-d[col+1];

end do:

evalm(A);

M := 3

b := [0, 1.7, .5, 0]

d := [.2, .1, .6, .9]

matrix([[0, 1.7, .5, 0], [.8, 0, 0, 0], [0, .9, 0, 0], [0, 0, .4, 0]])

> # SOME USEFUL PROCEDURES

# MUTLIPLY VECTOR N BY MATRIX A

apply_A:=(A,N)->convert(evalm(A&*N),list):


# NORMALIZE A VECTOR

normaliz:=proc(N)

  local tot,i,Nlocal;

  Nlocal:=N;

  tot:=0;

  for i from 1 to nops(N) do tot:=tot+abs(N[i]); end do:

  unassign('i'):

  for i from 1 to nops(N) do Nlocal[i]:=N[i]/tot; end do:

#   for i from 1 to nops(N) do Nlocal[i]:=N[i]/N[1]; end do:

  return Nlocal;

end proc:


# MAKE A HISTOGRAM OF A VECTOR

my_histogram:=proc(N)

  local n,i,r;

  n:=nops(N);

  for i from 0 to n-1 do

    r[i]:=plottools[rectangle]([i,N[i+1]],[i+1,0],color=pink);

  end do:

  return plots[display](seq(r[i],i=0..n-1));

end proc:

> N:=[1,0,0,0];    # WHAT HAPPENS IF WE START WITH JUST BABIES?
for t from 1 to 30 do

  N:=apply_A(A,N);

end do;

N := [1, 0, 0, 0]

N := [0., .8, 0., 0.]

N := [1.36, 0., .72, 0.]

N := [.360, 1.088, 0., .288]

N := [1.8496, .2880, .9792, 0.]

N := [.97920, 1.47968, .25920, .39168]

N := [2.645056, .783360, 1.331712, .103680]

N := [1.9975680, 2.1160448, .7050240, .5326848]

N := [3.94978816, 1.59805440, 1.90444032, .28200960]

N := [3.668912640, 3.159830528, 1.438248960, .761776128]

N := [6.090836378, 2.935130112, 2.843847475, .5752995840]

N := [6.411644928, 4.872669102, 2.641617101, 1.137538990]

N := [9.604346023, 5.129315942, 4.385402192, 1.056646840]

N := [10.91253820, 7.683476818, 4.616384348, 1.754160877]

N := [15.37010276, 8.730030560, 6.915129136, 1.846553739]

N := [18.29861652, 12.29608221, 7.857027504, 2.766051654]

N := [24.83185351, 14.63889322, 11.06647399, 3.142811002]

N := [30.41935546, 19.86548281, 13.17500390, 4.426589596]

N := [40.35882273, 24.33548437, 17.87893453, 5.270001560]

N := [50.30979070, 32.28705818, 21.90193593, 7.151573812]

N := [65.83896687, 40.24783256, 29.05835236, 8.760774372]

N := [82.95049153, 52.67117350, 36.22304930, 11.62334094]

N := [107.6525196, 66.36039322, 47.40405615, 14.48921972]

N := [136.5146966, 86.12201568, 59.72435390, 18.96162246]

N := [176.2696036, 109.2117573, 77.50981411, 23.88974156]

N := [224.4148945, 141.0156829, 98.29058157, 31.00392564]

N := [288.8719517, 179.5319156, 126.9141146, 39.31623263]

N := [368.6613138, 231.0975614, 161.5787240, 50.76564584]

N := [473.6552164, 294.9290510, 207.9878053, 64.63148960]

N := [605.3732893, 378.9241731, 265.4361459, 83.19512212]

N := [776.8891673, 484.2986314, 341.0317558, 106.1744584]

> # SAME EXPERIMENT, BUT MAKE AN ANIMATED HISTOGRAM THIS TIME
N:=[1,0,0,0];

histo[0]:=my_histogram(convert(N,list)):

for t from 1 to 30 do

  N:=apply_A(A,N);

  histo[t]:=my_histogram(convert(N,list)):

end do: unassign('t'):

plots[display]( seq( histo[t], t=0..30 ), insequence=true );

N := [1, 0, 0, 0]

[Plot]

> # SAME EXPERIMENT, BUT THIS TIME NORMALIZE POPULATION
# IN ORDER TO SEE BETTER WHAT'S HAPPENING TO THE AGE-DISTRIBUTION

N:=[1,0,0,0];

histo[0]:=my_histogram(convert(N,list)):

for t from 1 to 30 do

  N:=apply_A(A,N);

  N:=normaliz(N);

  print(N);    

  histo[t]:=my_histogram(convert(N,list)):

end do: unassign('t'):

plots[display]( seq( histo[t], t=0..30 ), insequence=true );

N := [1, 0, 0, 0]

[0., 1.000000000, 0., 0.]

[.6538461538, 0., .3461538462, 0.]

[.2073732719, .6267281105, 0., .1658986176]

[.5934291581, 0.9240246406e-1, .3141683778, 0.]

[.3148796048, .4758180696, 0.8335048363e-1, .1259518419]

[.5438240983, .1610589891, .2738002816, 0.2131663092e-1]

[.3732849843, .3954247115, .1317476415, 0.9954266247e-1]

[.5106851299, .2066193389, .2462332948, 0.3646223628e-1]

[.4063580476, .3499735999, .1592962538, 0.8437209894e-1]

[.4894158941, .2358459888, .2285111713, 0.4622694531e-1]

[.4256419585, .3234758698, .1753657741, 0.7551639698e-1]

[.4760350714, .2542322272, .2173604783, 0.5237222322e-1]

[.4370861702, .3077507172, .1849026980, 0.7026041474e-1]

[.4677192116, .2656587970, .2104305220, 0.5619146939e-1]

[.4439496125, .2983198718, .1906222972, 0.6710821876e-1]

[.4625901424, .2727064934, .2061562491, 0.5854711522e-1]

[.4480918303, .2926281776, .1940741847, 0.6520580742e-1]

[.4594414011, .2770330818, .2035322682, 0.5999324898e-1]

[.4506012459, .2891800669, .1961653881, 0.6405329906e-1]

[.4575139372, .2796815505, .2019260300, 0.6087848226e-1]

[.4521249838, .2870863455, .1974351842, 0.6335348641e-1]

[.4563361400, .2812999249, .2009445212, 0.6141941331e-1]

[.4530515019, .2858132461, .1982072913, 0.6292796128e-1]

[.4556172094, .2822877855, .2003454055, 0.6174959922e-1]

[.4536153541, .2850384735, .1986771736, 0.6266899865e-1]

[.4551786608, .2828903824, .1999799441, 0.6195101324e-1]

[.4539586758, .2845667256, .1989632783, 0.6251132004e-1]

[.4549112524, .2832578200, .1997571012, 0.6207382685e-1]

[.4541677856, .2842793951, .1991375383, 0.6241528167e-1]

[.4547482380, .2834818128, .1996212544, 0.6214869498e-1]

[Plot]

THE RELEVANCE OF THE EIGENDATA OF MATRIX A

> Am:=convert(A,Matrix); # "Eigenvectors" needs input of type "Matrix"
#Eigenvalues(Am);

(vals,vecs):=Eigenvectors(Am):

eigvals:=vals;

eigvecs:=evalm(vecs);

Am := Matrix([[0, 1.7, .5, 0], [.8, 0, 0, 0], [0, .9, 0, 0], [0, 0, .4, 0]])

eigvals := Vector[column]([[1.28102496759066553+0.*I], [-.99999999999999944+0.*I], [-.281024967590665364+0.*I], [0.216769394122265754e-17+0.*I]])

eigvecs := matrix([[.7902556456+0.*I, -.6679527490+0.*I, 0.6194478282e-1+0.*I, -0.1191336664e-15+0.*I], [.4935145937+0.*I, .5343621992+0.*I, -.1763395853+0.*I, -0.2698502069e-16+0.*I], [.3467248068+0....

> C1:=Column(vecs,1);  # THE DOMINANT EIGENVECTOR
# COMPARE WITH SIMULATION (SCALE SO FIRST ELEMENT IS 1)

C1/C1[1];

N/N[1]; # N STORES THE POPULATION AT THE END OF OUR SIMULATION

C1 := Vector[column]([[.790255645579807986+0.*I], [.493514593749791064+0.*I], [.346724806785138617+0.*I], [.108264808432970413+0.*I]])

Vector[column]([[1.00000000036549720+0.*I], [.624499928207509547+0.*I], [.438750180212220675+0.*I], [.136999727971708895+0.*I]])

[1.000000000, .6233818829, .4389709244, .1366661590]

OBSERVE THAT THE AGE DISTRIBUTION OF THE POPULATION IS SETTLING INTO THAT
GIVEN BY THE DOMINANT EIGENVECTOR OF MATRIX A.

> ?Matrix

> ?Vector

> ?Column

>