@@ -3,28 +3,60 @@ using LinearAlgebra
33
44const Polymatrix = Dict{Tuple{Player, Player}, Matrix{Float64}}
55
6- " Compute the component of the payoff that doesn't depend on other players."
7- function compute_self_payoff (p:: Player , x_p:: PureStrategy )
8- var_assignments_p = build_var_assignments (p, x_p)
96
10- self_linear_payoff = sum ( get (p . Π . aff . terms, v, 0 ) * var_assignments_p[v] for v in all_variables (p . X))
7+ function compute_self_payoff (Π :: AffExpr , v_bar :: AssignmentDict ) :: Float64
118 # note the get() may be necessary as there may not be terms for all variables
12- self_affine_payoff = p. Π. aff. constant + self_linear_payoff
9+ self_linear_payoff = sum (get (Π. terms, ref, 0 ) * val for (ref, val) in v_bar)
10+
11+ # constant is here by convention (inherited from NormalGames.jl)
12+ return Π. constant + self_linear_payoff
13+ end
14+
15+ function compute_self_payoff (Π:: QuadExpr , v_bar:: AssignmentDict ):: Float64
1316 # TODO : maybe Dict{VariableRef, Number} should be the standard for assignments
14- self_quad_payoff = sum (get (p. Π. terms, UnorderedPair (v,v), 0 ) * var_assignments_p[v]^ 2 for v in all_variables (p. X))
17+ self_quad_payoff = sum (get (Π. terms, UnorderedPair (ref,ref), 0 ) * val^ 2 for (ref, val) in v_bar)
18+
19+ return self_quad_payoff + compute_self_payoff (Π. aff, v_bar)
20+ end
21+
22+ " Compute the component of the payoff that doesn't depend on other players."
23+ function compute_self_payoff (p:: Player , x_p:: PureStrategy )
24+ v_bar = Assignment (p, x_p)
1525
16- return self_affine_payoff + self_quad_payoff
26+ return compute_self_payoff (p. Π, v_bar)
27+ end
28+
29+ " Compute player p's payoff component from some *other* player playing v_bar_k."
30+ function compute_others_payoff (Π:: AffExpr , v_bar_k:: AssignmentDict ):: Float64
31+ # TODO : identical to compute_self_payoff(::AffExpr, ::AssignmentDict), except for the constant. I could refactor
32+ return sum ( # terms of the form q_j * xk_j, where xk_j belongs to player k
33+ get (Π. terms, ref, 0 ) * val for (ref, val) in v_bar_k
34+ )
35+ end
36+
37+ " Compute player p's payoff component from her playing v_bar_p and some *other* player playing v_bar_k."
38+ function compute_bilateral_payoff (Π:: QuadExpr , v_bar_p:: AssignmentDict , v_bar_k:: AssignmentDict ):: Float64
39+ mixed_components = sum ( # terms of the form q_ij * xp_i * xk_j, where xp_i belongs to player p and xk_j belongs to player k
40+ get (Π. terms, UnorderedPair (ref_i,ref_j), 0 ) * val_i * val_j
41+ for (ref_i, val_i) in v_bar_p
42+ for (ref_j, val_j) in v_bar_k
43+ )
44+ other_components = sum ( # terms of the form q_ij * xk_i * xk_j, where xk_i,xk_j belong to player k
45+ get (Π. terms, UnorderedPair (ref_i,ref_j), 0 ) * val_i * val_j
46+ for (ref_i, val_i) in v_bar_k
47+ for (ref_j, val_j) in v_bar_k
48+ )
49+ other_components = other_components / 2 # I'm iterating over al possible unordered pairs twice!
50+
51+ return mixed_components + other_components + compute_others_payoff (Π. aff, v_bar_k)
1752end
1853
1954function compute_bilateral_payoff (p:: Player , x_p:: PureStrategy , k:: Player , x_k:: PureStrategy )
20- var_assignments_k = build_var_assignments (k, x_k)
21- var_assignments_p = build_var_assignments (p, x_p) # TODO : this could be cached.
2255 # In fact, +1 for having Dict{VariableRef, Number} as the standard for assignments
56+ v_bar_p = Assignment (p, x_p) # TODO : this could be cached.
57+ v_bar_k = _internalize_assignment (p, Assignment (k, x_k))
2358
24- return sum (
25- get (p. Π. terms, UnorderedPair (vp,vk), 0 ) * var_assignments_p[vp] * var_assignments_k[vk]
26- for vp in all_variables (p. X), vk in all_variables (k. X)
27- )
59+ return compute_bilateral_payoff (p. Π, v_bar_p, v_bar_k)
2860end
2961
3062" Compute polymatrix for normal form game from sample of strategies."
0 commit comments