This document presents the Julia codes used to obtain the computational results included in the paper "Exploring the Effects on the Electoral College of National and Regional Popular Vote Interstate Compact: An Electoral Engineering Perspective".
The function phi_IC computes the value of $\Phi_{IC}(K,L)$ (formula given in section 3.1) for given integers $K$ and $L$:
function phi_IC(L, K)
Q = round(Int64, (K+1)/2)
H = K-L
cste = lgammavect[H+1] - H*log(2)
res = 0.0
if L > Q
res = 1/sqrt(pi*L)
else
for i=(Q-L):(Q-1)
res = res + exp(cste - lgammavect[i+1] - lgammavect[H-i+1])
end
res = res/sqrt(pi*L)
end
end
The function psi_IC computes the value of $\Psi_{IC}(K,L)$ (formula given in section 3.2) for given integers $K$ and $L$:
function psi_IC(L, K)
Q = round(Int64, (K+1)/2)
H = K-L
res = exp(lgammavect[H] - lgammavect[Q] -
lgammavect[H-Q+1] - log(sqrt(pi)) - (H-1)*log(2))
end
We will compute $\Delta_{IC}(K,L)$ thanks to phi_IC and psi_IC (see formula in section 3.3).
# choose a value of K
K = 51
# compute the values of loggamma needed
lgammavect = lgamma(1:(K+1))
# initialization
Q = round(Int64, (K+1)/2)
inside_IC = zeros(Float64, K)
outside_IC = zeros(Float64, K)
total_IC = zeros(Float64, K)
# computation of phi, psi and delta from 1 to Q
for i=1:(Q-1)
inside_IC[i] = phi_IC(i, K)
outside_IC[i] = psi_IC(i, K)
total_IC[i] = (K-i)*outside_IC[i] + i*inside_IC[i]
end
# computation of phi, psi and delta from Q to K
for i=Q:K
inside_IC[i] = sqrt(1/(i*pi))
total_IC[i] = i*inside_IC[i]
end
using PyPlot
# The values of L
L = round(Int64, linspace(1, K, K))
# plot the figure with total_IC
figure(figsize = (8, 10))
subplot(2, 1, 1)
plot(L, total_IC, linewidth = 2.0, linestyle = "-", label = "total",
color = "red")
scatter(L[indmin(total_IC)], minimum(total_IC), 35, color = "red")
plot([0; indmax(total_IC.>total_IC[1])],
[minimum(total_IC[total_IC.>total_IC[1]]); minimum(total_IC[total_IC.>total_IC[1]])],
linewidth = 2.0, color = "red", linestyle = "--")
plot([indmax(total_IC.>total_IC[1]); indmax(total_IC.>total_IC[1])], [0; minimum(total_IC[total_IC.>total_IC[1]])],
linewidth = 2.0, color = "red", linestyle = "--")
plot([indmin(total_IC) ; indmin(total_IC)], [0; minimum(total_IC)], color = "red",
linewidth = 2.0, linestyle = "--")
# legend
title(L"\Delta_{IC}(51,L)")
ax = gca()
ax[:set_xlim]([0, K])
ax[:set_ylim]([0, maximum(total_IC)])
grid("on")
Mx = matplotlib[:ticker][:MultipleLocator](5) # Define interval of major ticks
ax[:xaxis][:set_major_locator](Mx) # Set interval of major ticks
mx = matplotlib[:ticker][:MultipleLocator](1) # Define interval of minor ticks
ax[:xaxis][:set_minor_locator](mx) # Set interval of minor ticks
legend(loc="upper right", fancybox="true")
# plot the figure with inside_IC and outside_IC
subplot(2,1,2)
plot(L, inside_IC, linewidth = 2.0, linestyle = "-", label = "inside",
color = "magenta")
plot(L, outside_IC, linewidth = 2.0, linestyle = "-", label = "outside",
color = "cyan")
scatter(L[indmax(inside_IC)], maximum(inside_IC), 35, color = "magenta")
scatter(L[26], 0, 35, color = "cyan")
plot([indmax(inside_IC); indmax(inside_IC)], [-0.01; maximum(inside_IC)],
color = "magenta", linestyle = "--")
plot([0; indmax(inside_IC)], [maximum(inside_IC); maximum(inside_IC)],
color = "magenta", linestyle = "--")
plot([26; 26], [-0.01; 0], color = "cyan", linestyle = "--")
# legend
title(L"$\Phi_{IC}(51,L)$ and $\Psi_{IC}(51,L)$")
ax = gca()
ax[:set_xlim]([0, K])
ax[:set_ylim]([-0.01, maximum(inside_IC) + 0.01])
grid("on")
Mx = matplotlib[:ticker][:MultipleLocator](5) # Define interval of major ticks
ax[:xaxis][:set_major_locator](Mx) # Set interval of major ticks
mx = matplotlib[:ticker][:MultipleLocator](1) # Define interval of minor ticks
ax[:xaxis][:set_minor_locator](mx) # Set interval of minor ticks
legend(loc = "upper right", fancybox = "true")
ax = gca()
xlabel("Number of states inside the coalition, L")
To compute $c_L$ (see section 4.1), we use the formula given in Le Breton et al. (2016) :
$$c_L=\displaystyle\sum_{m=0}^{\frac{L-1}{2}}(-1)^m \exp((L+1)\ln(L)-(L-1)\ln(2L)-\ln\Gamma(L-m+1) -\ln\Gamma(m+1) + (L-1)\ln(L-2m))$$To compute $c_L$ for $L=1,...,1001$, we need to increase the precision machine with Julia until $mantissa=1024$.
Lmax = 1001
# here we give the number of the mantrix
setprecision(1024)
# if BigFloat
lgammavectBF = ones(BigFloat, Lmax+1)
@time for k in 1:(Lmax+1)
lgammavectBF[k] = lgamma(BigFloat(k))
end
cL = zeros(BigFloat, Lmax)
cLFloat64 = zeros(Float64, Lmax)
for K=1:Lmax
if(isodd(K))
loopmax = round(Int64, (K-1)/2)
else
loopmax = round(Int64, K/2)
end
cste = (K+1)*log(BigFloat(K)) - (K-1)*log(BigFloat(2*K))
powerm = ones(Int64, loopmax+1)
for i=1:(loopmax)
powerm[i+1] = powerm[i]*(-1)
end
for m=0:loopmax
cL[K] = cL[K] + powerm[m+1]*exp(cste - lgammavectBF[K-m+1] -
lgammavectBF[m+1] + (K-1)*log(BigFloat(K-2*m)))
cLFloat64[K] = convert(Float64, cL[K])
end
end
The function phi_IAC_star computes the value of $\Phi_{IAC*}(K,L)$ (formula given in section 4.1) for given integers $K$ and $L$:
function phi_IAC_star(L, K)
Q = round(Int64, (K+1)/2)
H = K-L
cste = lgammavect[H+1] - H*log(2)
res = 0.0
for i=(Q-L):(Q-1)
res = res + exp(cste - lgammavect[i+1] - lgammavect[H-i+1])
end
res = cLFloat64[L]/L*res
end
$\Psi_{IAC*}$ is the same that $\Psi_{IC}$ case up to the multiplicative factor $\frac{1}{2r+1}$.
$\Delta_{IAC*}(K,L)$ is computed thanks $\Phi_{IAC*}$ and $\Psi_{IAC*}$.
# choose a value of K
K = 51;
# compute the vector of loggamma
lgammavect = lgamma(1:(K+1))
#initialization
Q = round(Int64, (K+1)/2)
inside_IACstar = zeros(Float64, K)
outside_IACstar = zeros(Float64, K)
total_IACstar = zeros(Float64, K)
# computation from 1 to Q
for i=1:(Q-1)
inside_IACstar[i] = phi_IAC_star(i, K);
outside_IACstar[i] = sqrt(pi)*psi_IC(i, K);
total_IACstar[i] = (K-i)*outside_IACstar[i] + i*inside_IACstar[i]
end
# computation from Q to K
for i=Q:K
inside_IACstar[i] = cL[i]/i
total_IACstar[i] = i*inside_IACstar[i]
end
# values of L
L = round(Int64, linspace(1, K, K))
# plot of total_IACstar
figure(figsize=(8,10))
subplot(2,1,1)
plot(L, total_IACstar, linewidth = 2.0, linestyle = "-",
label = "total", color = "red")
scatter(L[indmin(total_IACstar)], minimum(total_IACstar), color="red")
plot([indmin(total_IACstar) ; indmin(total_IACstar)], [0; minimum(total_IACstar)],
color = "red", linestyle = "--", linewidth = 2.0)
# legend
title(L"\Delta_{IAC*}(51,L)")
ax = gca()
ax[:set_xlim]([0, K])
ax[:set_ylim]([0, maximum(total_IACstar)])
grid("on")
Mx = matplotlib[:ticker][:MultipleLocator](5) # Define interval of major ticks
ax[:xaxis][:set_major_locator](Mx) # Set interval of major ticks
mx = matplotlib[:ticker][:MultipleLocator](1) # Define interval of minor ticks
ax[:xaxis][:set_minor_locator](mx) # Set interval of minor ticks
legend(loc = "upper right", fancybox = "true")
# plot of inside_IACstar and outside_IACstar
subplot(2,1,2)
plot(L, inside_IACstar, linewidth = 2.0, linestyle = "-",
label = "inside", color = "magenta")
plot(L, outside_IACstar, linewidth = 2.0, linestyle = "-",
label = "outside", color = "cyan")
scatter(L[indmax(inside_IACstar)], maximum(inside_IACstar), 35, color = "magenta")
scatter(L[26], 0, 35, color = "cyan")
plot([indmax(inside_IACstar); indmax(inside_IACstar)], [-0.02; maximum(inside_IACstar)],
color = "magenta", linestyle = "--")
plot([0; indmax(inside_IACstar)], [maximum(inside_IACstar); maximum(inside_IACstar)],
color = "magenta", linestyle = "--")
plot([26; 26], [-0.02; 0], color = "cyan", linestyle = "--")
title(L"$\Phi_{IAC*}(51,L)$ and $\Psi_{IAC*}(51,L)$")
# legend
ax = gca()
ax[:set_xlim]([0, K])
ax[:set_ylim]([-0.02, maximum(inside_IACstar)+0.01])
legend(loc = "upper right", fancybox = "true")
ax = gca()
xlabel(L"D")
xlabel("Number of states inside the coalition, L")
grid("on")
Mx = matplotlib[:ticker][:MultipleLocator](5) # Define interval of major ticks
ax[:xaxis][:set_major_locator](Mx) # Set interval of major ticks
mx = matplotlib[:ticker][:MultipleLocator](1) # Define interval of minor ticks
ax[:xaxis][:set_minor_locator](mx); # Set interval of minor ticks