Advertisement
Guest User

marriage-age-gap-simulation.lsp

a guest
Dec 16th, 2016
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/newlisp -n
  2.  
  3. ;;; marriage-age-gap-simulation.lsp Copyright (c) 2016 TheMost
  4. ;;;
  5. ;;; Permission to use, copy, modify, and/or distribute this software for
  6. ;;; any purpose with or without fee is hereby granted, provided that the
  7. ;;; above copyright notice and this permission notice appear in all
  8. ;;; copies.
  9. ;;;
  10. ;;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11. ;;; WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12. ;;; WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  13. ;;; AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  14. ;;; DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
  15. ;;; OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  16. ;;; TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  17. ;;; PERFORMANCE OF THIS SOFTWARE.
  18. ;;;
  19. ;;; to run:
  20. ;;; Windows: newlisp.exe marriage-age-gap-simulation.lsp
  21. ;;; Mac OSX: newlisp ./marriage-age-gap-simulation.lsp
  22. ;;; Linux:   newlisp ./marriage-age-gap-simulation.lsp
  23. ;;;
  24. ;;; The polygamy problem: If some men have more than one wife, other men will
  25. ;;; have to go without!  Is this problem real?  Or does it depend on false
  26. ;;; assumptions?
  27. ;;;
  28. ;;; Assuming an age gap between the age at which men and women marry, how many
  29. ;;; men can have 2 wives?
  30. ;;;
  31. ;;; Assuming every man has a certain number of wives, what age gap is required?
  32. ;;; Also, how many times will a woman marry, compared to a man?
  33. ;;;
  34. ;;; First model:
  35. ;;;   * everyone lives their full lifespan
  36. ;;;   * every is sufficiently healthy and attractive to mate
  37. ;;;   * no abortions, miscarriages, murders
  38. ;;;   * marriage is for life, no divorce
  39. ;;; Future models: include hypergamy, SMV, more realistic death
  40. ;;; model.
  41.  
  42. (define def define)
  43. (define defm define-macro)
  44.  
  45. (def total-years 2000)        ; number of years to run the simulation
  46. (def max-population 1000000L) ; end simulation when this number of people is reached
  47. (def num-wives 2)             ; number of wives per man
  48. (def average-number-of-children-per-woman 8)
  49. (def male-age-of-death       72)
  50. (def female-age-of-death     79)
  51. (def male-age-of-majority    18)
  52. (def female-age-of-majority  16)
  53. (def female-age-of-menopause 48)
  54. ;(def female-age-of-widowhood 60)
  55. (def female-age-of-widowhood 34) ; women don't remarry after this age
  56. (def birth-odds (div average-number-of-children-per-woman
  57.                   (sub female-age-of-menopause female-age-of-majority)))
  58.  
  59. ;; source for information about sex ratio by fathers age:
  60. ;; https://www.psychologytoday.com/blog/the-scientific-fundamentalist/201104/why-are-older-parents-more-likely-have-daughters
  61. ;; by Satoshi Kanazawa, posted April 18, 2011
  62. (def male-birth-ratio-by-fathers-age
  63.   (list
  64.      (list 20 0.5329)
  65.      (list 25 0.5121)
  66.      (list 30 0.4840)
  67.      (list 35 0.5224)
  68.      (list 40 0.5256)
  69.      (list male-age-of-death 0.3592)))
  70.  
  71. (def male-birth-ratio
  72.   (lambda (x)
  73.     (let (a (- yr ((males (husband-of x)) 0))) ; a is the father's age
  74.       (catch
  75.         (dolist (b male-birth-ratio-by-fathers-age)
  76.           (if (< a (b 0))
  77.             (throw (b 1))))))))
  78.  
  79. (def init-years female-age-of-widowhood) ; number of years to generate people ex nihilo
  80.  
  81. (def max-32bit-int 4294967295) ; in binary, 0b11111111111111111111111111111111
  82. (def fd            (open "/dev/urandom" "read"))
  83. (seed (time-of-day)) ; initialize random number generator
  84. (def /dev/urandom
  85.   (if (= ostype "Windows")
  86.       random ; fallback to builtin RNG on Windows
  87.     (lambda ()
  88.       (read fd buf 4)
  89.       (div (first (unpack "lu" buf)) max-32bit-int))))
  90.  
  91. (def males (array (+ 1 max-population)))   ; (birthyear (current-wives) nwives ...)
  92. (def females (array (+ 1 max-population))) ; (birthyear current-husband nhusbands ...)
  93. (def oldest-man 0)
  94. (def youngest-male 0)
  95. (def youngest-man 0)  ; a man can marry and sire children
  96. (def oldest-woman 0)
  97. (def youngest-female 0)
  98. (def youngest-woman 0) ; a woman can marry and bear children
  99.  
  100. (def wives-of   (lambda (x) ((males x) 1)))
  101. (def husband-of (lambda (x) ((females x) 1)))
  102. (def married?   (lambda (x) (husband-of x)))
  103.  
  104. ;; yearly stats
  105. (def mdeaths 0) ; male deaths
  106. (def fdeaths 0) ; female deaths
  107. (def mbirths 0) ; male births
  108. (def fbirths 0) ; female births
  109. (def mages 0)   ; used to calculate average male age at marriage
  110. (def fages 0)   ; used to calculate average female age at marriage
  111. (def nmarriages 0) ; number of marriages
  112.  
  113. ;; advances indexes into the arrays of people
  114. ;; this let's us convert some iteration into simple arithmetic
  115. ;; and thereby avoids memory accesses and cache misses/flushes
  116. (def advance-age-status
  117.   (lambda (yr)
  118.     ;; youngest-male and youngest-female are updated in do-births
  119.     ;; oldest-man and oldest-woman are updated in do-deaths
  120.     (let (y (- yr male-age-of-majority))    (while (> y ((males youngest-man) 0))          (++ youngest-man)))
  121.     (let (y (- yr female-age-of-majority))  (while (> y ((females youngest-woman) 0))      (++ youngest-woman)))
  122.     (let (y (- yr female-age-of-menopause)) (while (> y ((females oldest-fertile) 0))      (++ oldest-fertile)))
  123.     (let (y (- yr female-age-of-widowhood)) (while (> y ((females oldest-marriageable) 0)) (++ oldest-marriageable)))
  124.   ))
  125.  
  126. (def initialize-population
  127.   (lambda ()
  128.     (dotimes (yr init-years)
  129.       (setf (males yr)   (list yr '()))
  130.       (setf (females yr) (list yr nil)))
  131.     (setf youngest-male   (- init-years 1)
  132.           youngest-female (- init-years 1)
  133.           youngest-man        0
  134.           youngest-woman      0
  135.           oldest-man          0
  136.           oldest-woman        0
  137.           oldest-fertile      0
  138.           oldest-marriageable 0)))
  139.  
  140. (def (do-births yr)
  141.   (let (i oldest-fertile yf youngest-female ym youngest-male)
  142.     (while (<= i youngest-woman)
  143.       (when (and (married? i) (< (/dev/urandom) birth-odds))
  144.         (when (>= (max youngest-female youngest-male) max-population)
  145.           (println "Ran out of memory. Stopping now.")
  146.           (exit))
  147.         (if (< (/dev/urandom) (male-birth-ratio i))
  148.           (begin (setf   (males (++ youngest-male))   (list yr '())))
  149.           (begin (setf (females (++ youngest-female)) (list yr nil)))))
  150.       (++ i))
  151.     (set 'fbirths (- youngest-female yf))
  152.     (set 'mbirths (- youngest-male ym))))
  153.  
  154. (def (do-deaths yr)
  155.   (let (af (- yr female-age-of-death)
  156.         am (- yr male-age-of-death)
  157.         om oldest-man
  158.         ow oldest-woman)
  159.     (while (> af ((females oldest-woman) 0))
  160.       (when (married? oldest-woman)
  161.         (setf ((males (husband-of oldest-woman)) 1)
  162.               (clean (fn (x) (= x oldest-woman)) (wives-of (husband-of oldest-woman)))))
  163.       (++ oldest-woman))
  164.     (while (> am ((males oldest-man) 0))
  165.       (dolist (wife (wives-of oldest-man))
  166.         (setf ((females wife) 1) nil))
  167.       (++ oldest-man))
  168.     (++ fdeaths (- oldest-woman ow))
  169.     (++ mdeaths (- oldest-man om))))
  170.  
  171. ;; a man will only marry one woman per year
  172. (def (do-marriages yr)
  173.   (let (i oldest-man k youngest-woman)
  174.     (while (and (<= i youngest-man) (>= k oldest-marriageable))
  175.       (when (< (length ((males i) 1)) num-wives) ; man doesn't have his full complement of wives
  176.         (while (and ((females k) 1) (>= k oldest-marriageable))
  177.           (-- k))
  178.         (unless (married? k) ; found a single woman, marry her off.
  179.           (setf ((females k) 1) i)
  180.           (push k ((males i) 1))
  181.           (++ fages (- yr ((females k) 0)))
  182.           (++ mages (- yr ((males i) 0)))
  183.           (++ nmarriages)))
  184.       (++ i))))
  185.  
  186. (def (print-year yr)
  187.   (let (num-men (- youngest-male oldest-man -1) num-women (- youngest-female oldest-woman -1))
  188.     (println (format
  189.       "Year %d. population %d (%.2f) %d births (%.2f) %d deaths (%.2f) %d marriages (m: %d f: %d)"
  190.       yr
  191.       (+ num-men num-women) (div num-men (add num-men num-women))
  192.       (+ mbirths fbirths) (div mbirths (add mbirths fbirths))
  193.       (+ mdeaths fdeaths) (div mdeaths (add mdeaths fdeaths))
  194.       nmarriages (round (div mages nmarriages)) (round (div fages nmarriages)))))
  195.   (set 'mdeaths 0 'fdeaths 0 'mbirths 0 'fbirths 0 'mages 0 'fages 0 'nmarriages 0))
  196.  
  197. (initialize-population)
  198. (def (do-year yr)
  199.   (when (and (> youngest-male oldest-man) (> youngest-female oldest-woman)) ; while there are living people
  200.       (advance-age-status yr)
  201.       (do-births yr)
  202.       (do-deaths yr)
  203.       (do-marriages yr)
  204.       (print-year yr)))
  205.  
  206. (for (yr (+ 1 init-years) (+ init-years total-years))
  207.   (do-year yr)))
  208.  
  209. (exit)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement