-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathactor.cpp
More file actions
97 lines (85 loc) · 2.69 KB
/
Copy pathactor.cpp
File metadata and controls
97 lines (85 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include "actor.hpp"
#include "misc.hpp"
#include "market.hpp"
using namespace opec;
RoundVector Actor::value(const RoundVector& quantity, const RoundVector& prices) const {
RoundVector v;
double res = reserves;
for (int r = 0; r < NumRounds; r++) {
auto q = quantity(r);
assert(q <= 1.01 * capacity);
assert(q <= 1.01 * res);
v(r) = prices(r) * q - supply(r).integrate(q);
res -= q;
}
v(NumRounds) = quantity(NumRounds) * SellOffPrice;
v = Market::inflate(v);
return v;
}
void Actor::update(Solution& solution, RowRoundVectorRef quantities) {
// renormalize quantities to reserves
quantities *= reserves / quantities.sum();
}
void Actor::isConstrained(const RoundVector& quantity) const {
for (int r = 0; r < NumRounds; r++) {
bool satisfied = 0. <= quantity(r) && quantity(r) <= capacity;
if (!satisfied) {
std::cerr << 0. << " < " << quantity(r) << " < " << capacity << std::endl;
// << "round: " << r << ", step: " << step(r) << ", constraint: " << constraints(r) << std::endl;
assert(false);
}
}
if (!approx<double>(quantity.sum(), reserves, 1000)) {
std::cerr << quantity.sum() << " != " << reserves << std::endl;
assert(false);
}
}
// Marginal cost is trivial read off the supply function.
//
RoundVector Actor::marginalCost(const RoundVector& quantity) const {
RoundVector mc;
for (int r = 0; r <= NumRounds; r++) {
mc(r) = supply(r).evaluate(quantity(r));
}
return mc;
}
// Compute the marginal revenue over all rounds for this actor, given
// some prices, the actor's quantity, the market demand, and total
// (OPEC) production in each round.
//
// Revenue for country 1 in any given round is:
//
// R1 = p q1
//
// Where p(q) = p(q1 + q1 + ... qN) is a function of total production.
//
// Therefore country 1's marginal revenue is given by:
//
// dR1 dp dq1 dp
// --- = --- q1 + p --- = --- q1 + p
// dq1 dq1 dq1 dq1
//
// And by the chain rule
//
// dp dp dq dp d(q1+q2+...+qN) dp
// --- = -- x --- = -- x --------------- = --
// dq1 dq dq1 dq dq1 dq
//
// Finally
//
// dR1 dp
// --- = -- q1 + p
// dq1 dq
//
bool debug;
RoundVector Actor::marginalRevenue(const RoundVector& prices,
const RoundVector& quantity,
const Market& market,
const RoundVector& production) const {
RoundVector mr;
for (int r = 0; r <= NumRounds; r++) {
mr(r) = prices(r) + quantity(r) * market.dPrice(r, production(r));
}
return mr;
}