; the following program is written to simulate elections as per requested by ; JZ ;;; ; The output matrix stores all the "election" results and has the following ; columns: ;1. District Number 2. Year 3. Incumbent Z score 4. Challenger Z score 5. ; Who won? 6. number of PREVIOUS terms ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; some notes about the code ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; UTILITIES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; the following function generates a random number from the upper tail of a ;normal ; distribution. (defun normal-tail (zlim) (let* ( (cdfz (normal-cdf zlim)) (range (- 1 cdfz))) (select (normal-quant (+ (* range (uniform-rand 1)) cdfz)) 0))) ;Check the shape of the distribution (defun checkit (zlim n) (let ((h (histogram (list (normal-tail 2) (normal-tail 2) (normal-tail 2) (normal-tail 2))))) (send h :adjust-to-data) (dotimes (i n) (send h :add-points (list (normal-tail 2) (normal-tail 2)))))) ;luck-factor (defun luck-factor (year lucky redistrict) (let* ( (y2 (- year (* 10 (truncate (/ year 10))))) (redist (if (or (eql 4 y2) (eql 9 y2)) redistrict 1))) (select (* redist (* lucky (normal-rand 1))) 0))) ;open-seat (defun primary (zlim) (max (normal-tail zlim) (normal-tail zlim))) ;Write initial value to the output matrix (defun write-initial-values (row1 district II IC lucky-open) (let* ( (luck (luck-factor 2 lucky-open 1)) (winner (if (< (+ II luck) IC) 0 1))) (setf (select output row1 0) district) (setf (select output row1 1) 0) (setf (select output row1 2) II) (setf (select output row1 3) IC) (setf (select output row1 4) winner) (setf (select output row1 5) 0) (setf (select output row1 6) 1) (setf (select output row1 7) luck) )) ;run-the-election (defun run-the-election (row year zlim district retire lucky redistrict lucky-open) (let* ( (rt (- retire 1)) (nterms (select output (- row 1) 5)) (wonlast (select output (- row 1) 4)) (open-seat (if (and (eql 1 wonlast) (eql rt nterms)) t nil)) (luck (if open-seat (luck-factor year lucky-open 1) (luck-factor year lucky redistrict))) (incumb (if open-seat (primary zlim) (if (eql 1 wonlast) (select output (- row 1) 2) (select output (- row 1) 3)))) (challenger (if open-seat (primary zlim) (normal-tail zlim))) (winner (if (> (+ incumb luck) challenger) 1 0)) (open (if open-seat 1 0)) (terms (if (or open-seat (eql 0 winner)) 0 (+ 1 (select output (- row 1) 5)))) ) (setf (select output row 0) district) (setf (select output row 1) year) (setf (select output row 2) incumb) (setf (select output row 3) challenger) (setf (select output row 4) winner) (setf (select output row 5) terms) (setf (select output row 6) open) (setf (select output row 7) (+ incumb luck)))) ;;;;;;;;;;;;;;;;;;;;;;;; ; MAIN LOOP ;;;;;;;;;;;;;;;;;;;;;;;; (defun simulate (districts years zlim retire lucky redistrict lucky-open) (let ( (rows (* districts years)) (luck-open (luck-factor 2 lucky-open 1))) (def output (make-array (list rows 8))) (dotimes (i districts) (let ( (row1 (* i years)) (II (primary zlim)) (IC (primary zlim)) ) (write-initial-values row1 i II IC lucky-open) ; Run the Elections (dotimes (j (- years 1)) (let ( (rowc (+ row1 j 1)) (year (+ 1 j)) ) (run-the-election rowc year zlim i retire lucky redistrict lucky-open))))) (print-matrix output))) (print "To implement a simulation, type:") (print "(simulate #districts #years Zcutoff #years to retire lucky redist(1 or 0)") (simulate 7 5 2 3 .01 1 0)