feat: romer model
This commit is contained in:
parent
b6b3e08886
commit
71a959708d
7 changed files with 515 additions and 31 deletions
1
aggieland.txt
Normal file
1
aggieland.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
the 12th man
|
||||||
1
compile_flags.txt
Normal file
1
compile_flags.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
-std=c++20
|
||||||
5
filename.txt
Normal file
5
filename.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
This is an example text file.
|
||||||
|
This file contains several words, some of which are repeated.
|
||||||
|
For example, the word "this" appears multiple times in this file.
|
||||||
|
We can use a shell command to find the most frequent words.
|
||||||
|
Let's see how many times each word appears in this example text file.
|
||||||
10
map.cc
Normal file
10
map.cc
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::ifstream ifs{"aggieland.txt"};
|
||||||
|
std::string read1;
|
||||||
|
int read2;
|
||||||
|
ifs >> read1 >> read2;
|
||||||
|
std::cout << read1 << read2;
|
||||||
|
}
|
||||||
|
|
@ -147,7 +147,7 @@
|
||||||
type="range"
|
type="range"
|
||||||
id="sliderD"
|
id="sliderD"
|
||||||
min="0.01"
|
min="0.01"
|
||||||
max="1"
|
max="0.99"
|
||||||
step="0.01"
|
step="0.01"
|
||||||
value="0.50"
|
value="0.50"
|
||||||
/>
|
/>
|
||||||
|
|
@ -165,7 +165,7 @@
|
||||||
type="range"
|
type="range"
|
||||||
id="sliderS"
|
id="sliderS"
|
||||||
min="0.01"
|
min="0.01"
|
||||||
max="1"
|
max="0.99"
|
||||||
step="0.01"
|
step="0.01"
|
||||||
value="0.50"
|
value="0.50"
|
||||||
/>
|
/>
|
||||||
|
|
@ -179,7 +179,7 @@
|
||||||
type="range"
|
type="range"
|
||||||
id="sliderAlpha"
|
id="sliderAlpha"
|
||||||
min="0.01"
|
min="0.01"
|
||||||
max="1"
|
max="0.99"
|
||||||
step="0.01"
|
step="0.01"
|
||||||
value="0.33"
|
value="0.33"
|
||||||
/>
|
/>
|
||||||
|
|
@ -213,8 +213,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="fold">
|
<div class="fold">
|
||||||
<h3>analysis</h3>
|
<h3>analysis</h3>
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
<p>
|
||||||
Using both mathematical intuition and manipulating the
|
Using both mathematical intuition and manipulating the
|
||||||
visualization above, we find that:
|
visualization above, we find that:
|
||||||
|
|
@ -262,10 +260,250 @@
|
||||||
alter the most important predictor of output, TFP.
|
alter the most important predictor of output, TFP.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<h2>romer</h2>
|
<!-- Solow TODO -->
|
||||||
<!-- TODO: transition talking about "Romer model does, though" -->
|
|
||||||
<!-- TODO: say the romer model provides avenue for LR growth -->
|
|
||||||
<!-- TODO: dynamics?????? -->
|
<!-- TODO: dynamics?????? -->
|
||||||
|
<!-- TODO: K_0 -->
|
||||||
|
<h2>romer</h2>
|
||||||
|
<div class="fold"><h3>introduction</h3></div>
|
||||||
|
<div>
|
||||||
|
<p>How, then, can we address these shortcomings?</p>
|
||||||
|
<p>
|
||||||
|
The Romer Model provides an answer by both modeling ideas \(A_t\)
|
||||||
|
(analagous to TFP in the Solow model) endogenously and utilizing
|
||||||
|
them to provide a justification for sustained long-run growth.
|
||||||
|
</p>
|
||||||
|
<p>The Model divides the world into two parts:</p>
|
||||||
|
<ul style="list-style: unset">
|
||||||
|
<li>
|
||||||
|
<u>Objects</u>: finite resources, like capital and labor in the
|
||||||
|
Solow Model
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<u>Ideas</u>: infinite,
|
||||||
|
<a
|
||||||
|
target="blank"
|
||||||
|
href="https://en.wikipedia.org/wiki/Rivalry_(economics)"
|
||||||
|
>non-rivalrous</a
|
||||||
|
>
|
||||||
|
items leveraged in production (note that ideas may be
|
||||||
|
<a href="blank" href="https://www.wikiwand.com/en/Excludability"
|
||||||
|
>excludable</a
|
||||||
|
>, though)
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
The Romer Models' production function can be modelled as:
|
||||||
|
\[Y_t=F(A_t,L_{yt})=A_tL_{yt}\] With:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>\(A_t\): the amount of ideas \(A\) in period \(t\)</li>
|
||||||
|
<li>
|
||||||
|
\(L_{yt}\): the population working on production-facing
|
||||||
|
(output-driving) tasks
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Assuming \(L_t=\bar{L}\) people work in the economy, a proportion
|
||||||
|
\(\bar{l}\) of the population focuses on making ideas:
|
||||||
|
\(L_{at}=\bar{l}\bar{L}\rightarrow L_{yt}=(1-\bar{l})\bar{L}\).
|
||||||
|
</p>
|
||||||
|
<!-- TODO: footnotes - dynamic JS? -->
|
||||||
|
<p>
|
||||||
|
Further, this economy garners ideas with time at rate
|
||||||
|
<u>\(\bar{z}\)</u>: the "speed of ideas". Now, we can
|
||||||
|
describe the quantity of ideas tomorrow as function of those of
|
||||||
|
today: the <u>Law of Ideal Motion</u> (I made that up).
|
||||||
|
\[A_{t+1}=A_t+\bar{z}A_tL_{at}\leftrightarrow\Delta
|
||||||
|
A_{t+1}=\bar{z}A_tL_{at}\]
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Analagously to capital in the solow model, ideas begin in the
|
||||||
|
economy with some \(\bar{A}_0\gt0\) and grow at an
|
||||||
|
<i>exponential</i> rate. At its core, this is because ideas are
|
||||||
|
non-rivalrous; more ideas bring about more ideas.
|
||||||
|
</p>
|
||||||
|
<p>Finally, we have a model:</p>
|
||||||
|
<div style="display: flex; justify-content: center">
|
||||||
|
<div style="padding-right: 50px">
|
||||||
|
<ol>
|
||||||
|
<li>\(Y_t=A_tL_{yt}\)</li>
|
||||||
|
<li>\(\Delta A_{t+1} = \bar{z}A_tL_{at}\)</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
<div style="padding-left: 50px">
|
||||||
|
<ol start="3">
|
||||||
|
<li>\(L_{yt}+L_{at}=\bar{L}\)</li>
|
||||||
|
<li>\(L_{at}=\bar{l}\bar{L}\)</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
A visualization of the Romer Model shows that the economy grows
|
||||||
|
exponentially—production knows no bounds (<a
|
||||||
|
target="blank"
|
||||||
|
href="https://en.wikipedia.org/wiki/Ceteris_paribus"
|
||||||
|
><i>ceteris parbibus</i></a
|
||||||
|
>, of course). A graph of \(log_{10}(Y_t)\) can be seen below:
|
||||||
|
</p>
|
||||||
|
<div class="graph">
|
||||||
|
<div id="romer-visualization"></div>
|
||||||
|
</div>
|
||||||
|
<div class="sliders">
|
||||||
|
<div style="padding-right: 20px">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="slider">
|
||||||
|
<label for="sliderZ">\(\bar{z}:\)</label>
|
||||||
|
<span id="outputZ">0.50</span>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
id="sliderZ"
|
||||||
|
min="0.1"
|
||||||
|
max="0.99"
|
||||||
|
step="0.01"
|
||||||
|
value="0.50"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="slider">
|
||||||
|
<label for="sliderL">\(\bar{L}:\)</label>
|
||||||
|
<span id="outputL">505</span>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
id="sliderL"
|
||||||
|
min="10"
|
||||||
|
max="1000"
|
||||||
|
step="19"
|
||||||
|
value="505"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div style="padding-left: 20px">
|
||||||
|
<ul start="3">
|
||||||
|
<li>
|
||||||
|
<div class="slider">
|
||||||
|
<label for="sliderl">\(\bar{l}:\)</label>
|
||||||
|
<span id="outputl">0.50</span>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
id="sliderl"
|
||||||
|
min="0.01"
|
||||||
|
max="0.99"
|
||||||
|
step="0.01"
|
||||||
|
value="0.50"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="slider">
|
||||||
|
<label for="sliderA0">\(\bar{A}_0:\)</label>
|
||||||
|
<span id="outputA0">5000</span>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
id="sliderA0"
|
||||||
|
min="1"
|
||||||
|
max="10000"
|
||||||
|
step="100"
|
||||||
|
value="5000"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Playing with the sliders, this graph may seem underwhelming in
|
||||||
|
comparison to the Solow Model. However, on a logarithmic scale,
|
||||||
|
small changes in the parameters lead to massive changes in the
|
||||||
|
growth rate of ideas and economices:
|
||||||
|
</p>
|
||||||
|
<div class="romer-table-container">
|
||||||
|
<table id="romer-table">
|
||||||
|
<thead>
|
||||||
|
<tr id="romer-table-header"></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr id="row-A_t"></tr>
|
||||||
|
<tr id="row-Y_t"></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="fold"><h3>solving the model</h3></div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
To find the output in terms of exogenous parameters, first note
|
||||||
|
that \[L_t=\bar{L}\rightarrow L_{yt}=(1-\bar{l})\bar{L}\]
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Now, all that remains is to find ideas \(A_t\). It is assumed that
|
||||||
|
ideas grow at some rate \(g_A\): \[A_t=A_0(1+g_A)^t\]
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Using the growth rate formula, we find: \[g_A=\frac{\Delta
|
||||||
|
A_{t+1}-A_t}{A_t}=\frac{A_t+\bar{z}A_tL_{at}-A_t}{A_t}=\bar{z}L_{at}=\bar{z}\bar{l}\bar{L}\]
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Thus, ideas \(A_t=A_0(1+\bar{z}\bar{l}\bar{L})^t\). Finally,
|
||||||
|
output can be solved the production function: \[Y_t=A_t
|
||||||
|
L_{yt}=A_0(1+\bar{z}\bar{l}\bar{L})(1-\bar{l})\bar{L}\]
|
||||||
|
</p>
|
||||||
|
<!-- <p> -->
|
||||||
|
<!-- It follows that the intensive form can be written as: -->
|
||||||
|
<!-- \[y_t=\frac{Y_t}{\bar{L}}=A_0(1+\bar{z}\bar{l}\bar{L})(1-\bar{l})\]. -->
|
||||||
|
<!-- </p> -->
|
||||||
|
</div>
|
||||||
|
<div class="fold"><h3>analysis</h3></div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
We see the Romer model exhibits long-run growth because ideas have
|
||||||
|
non-diminishing returns due to their nonrival nature. In this
|
||||||
|
model, capital and income eventually slow but ideas continue to
|
||||||
|
yield increasing, unrestricted returns.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Further, all economy continually and perpetually grow along a
|
||||||
|
"Balanced Growth Path" as previously defined by \(Y_t\) as a
|
||||||
|
function of the endogenous variables. This directly contrasts the
|
||||||
|
Solow model, in which an economy converges to a steady-state with
|
||||||
|
transition dynamics.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Changes in the growth rate of ideas, then, alter the growth rate
|
||||||
|
of output itself—in this case, parameters \(\bar{l},
|
||||||
|
\bar{z}\), and \(\bar{L}\). This is best exemplified by comparing
|
||||||
|
the growth rate before and and after a parameter changes. In the
|
||||||
|
below example, a larger \(\bar{l}\) initially drops output due to
|
||||||
|
less workers being allocated to production. Soon after, though,
|
||||||
|
output recovers along a "higher" Balanced Growth Path.
|
||||||
|
</p>
|
||||||
|
<div class="graph">
|
||||||
|
<div id="romer-lchange-visualization"></div>
|
||||||
|
</div>
|
||||||
|
<div class="sliders">
|
||||||
|
<div style="padding-right: 20px">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="slider">
|
||||||
|
<label for="sliderlChange">\(\bar{l}:\)</label>
|
||||||
|
<span id="outputlChange">0.50</span>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
id="sliderlChange"
|
||||||
|
min="0.1"
|
||||||
|
max="0.99"
|
||||||
|
step="0.01"
|
||||||
|
value="0.50"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<h2>romer-solow</h2>
|
<h2>romer-solow</h2>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ function drawSolowGraph() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const A = document.getElementById("outputA").textContent,
|
const A = parseFloat(document.getElementById("outputA").textContent),
|
||||||
D = document.getElementById("outputD").textContent,
|
D = parseFloat(document.getElementById("outputD").textContent),
|
||||||
S = document.getElementById("outputS").textContent,
|
S = parseFloat(document.getElementById("outputS").textContent),
|
||||||
alpha = document.getElementById("outputAlpha").textContent;
|
alpha = parseFloat(document.getElementById("outputAlpha").textContent);
|
||||||
const solowOutput = (K) => A * Math.pow(K, alpha) * Math.pow(L, 1 - alpha);
|
const solowOutput = (K) => A * Math.pow(K, alpha) * Math.pow(L, 1 - alpha);
|
||||||
const solowDepreciation = (K) => D * K;
|
const solowDepreciation = (K) => D * K;
|
||||||
const solowInvestment = (Y) => S * Y;
|
const solowInvestment = (Y) => S * Y;
|
||||||
|
|
@ -34,12 +34,10 @@ function drawSolowGraph() {
|
||||||
.attr("transform", `translate(${margin.left}, ${margin.top})`);
|
.attr("transform", `translate(${margin.left}, ${margin.top})`);
|
||||||
|
|
||||||
const x = d3.scaleLinear().domain([0, K_MAX]).range([0, width]);
|
const x = d3.scaleLinear().domain([0, K_MAX]).range([0, width]);
|
||||||
const xAxis = svg
|
svg
|
||||||
.append("g")
|
.append("g")
|
||||||
.attr("transform", `translate(0, ${height})`)
|
.attr("transform", `translate(0, ${height})`)
|
||||||
.call(d3.axisBottom(x));
|
.call(d3.axisBottom(x))
|
||||||
|
|
||||||
xAxis
|
|
||||||
.append("text")
|
.append("text")
|
||||||
.attr("fill", "#000")
|
.attr("fill", "#000")
|
||||||
.attr("x", width + 10)
|
.attr("x", width + 10)
|
||||||
|
|
@ -50,9 +48,9 @@ function drawSolowGraph() {
|
||||||
|
|
||||||
const Y_MAX = solowOutput(K_MAX) + K_MAX / 10;
|
const Y_MAX = solowOutput(K_MAX) + K_MAX / 10;
|
||||||
const y = d3.scaleLinear().domain([0, Y_MAX]).range([height, 0]);
|
const y = d3.scaleLinear().domain([0, Y_MAX]).range([height, 0]);
|
||||||
const yAxis = svg.append("g").call(d3.axisLeft(y));
|
svg
|
||||||
|
.append("g")
|
||||||
yAxis
|
.call(d3.axisLeft(y))
|
||||||
.append("text")
|
.append("text")
|
||||||
.attr("fill", "#000")
|
.attr("fill", "#000")
|
||||||
.attr("x", 0)
|
.attr("x", 0)
|
||||||
|
|
@ -87,9 +85,7 @@ function drawSolowGraph() {
|
||||||
.append("xhtml:body")
|
.append("xhtml:body")
|
||||||
.style("font-size", "0.75em")
|
.style("font-size", "0.75em")
|
||||||
.html(`<div class="solow-visualization-y"></div>`);
|
.html(`<div class="solow-visualization-y"></div>`);
|
||||||
katex.render("Y", document.querySelector(".solow-visualization-y"), {
|
katex.render("Y", document.querySelector(".solow-visualization-y"));
|
||||||
throwOnError: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const depreciationData = Array.from({ length: K_MAX }, (_, k) => ({
|
const depreciationData = Array.from({ length: K_MAX }, (_, k) => ({
|
||||||
K: k,
|
K: k,
|
||||||
|
|
@ -118,9 +114,7 @@ function drawSolowGraph() {
|
||||||
.append("xhtml:body")
|
.append("xhtml:body")
|
||||||
.style("font-size", "0.75em")
|
.style("font-size", "0.75em")
|
||||||
.html(`<div class="solow-visualization-d"></div>`);
|
.html(`<div class="solow-visualization-d"></div>`);
|
||||||
katex.render("\\bar{d}K", document.querySelector(".solow-visualization-d"), {
|
katex.render("\\bar{d}K", document.querySelector(".solow-visualization-d"));
|
||||||
throwOnError: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const investmentData = outputData.map((d) => ({
|
const investmentData = outputData.map((d) => ({
|
||||||
K: d.K,
|
K: d.K,
|
||||||
|
|
@ -149,9 +143,7 @@ function drawSolowGraph() {
|
||||||
.append("xhtml:body")
|
.append("xhtml:body")
|
||||||
.style("font-size", "0.75em")
|
.style("font-size", "0.75em")
|
||||||
.html(`<div class="solow-visualization-i"></div>`);
|
.html(`<div class="solow-visualization-i"></div>`);
|
||||||
katex.render("I", document.querySelector(".solow-visualization-i"), {
|
katex.render("I", document.querySelector(".solow-visualization-i"));
|
||||||
throwOnError: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const k_star = L * Math.pow((S * A) / D, 1 / (1 - alpha));
|
const k_star = L * Math.pow((S * A) / D, 1 / (1 - alpha));
|
||||||
svg
|
svg
|
||||||
|
|
@ -177,13 +169,230 @@ function drawSolowGraph() {
|
||||||
katex.render(
|
katex.render(
|
||||||
`(K^*,Y^*)=(${k_star.toFixed(0)},${y_star.toFixed(0)})`,
|
`(K^*,Y^*)=(${k_star.toFixed(0)},${y_star.toFixed(0)})`,
|
||||||
document.querySelector(".solow-visualization-eq"),
|
document.querySelector(".solow-visualization-eq"),
|
||||||
{
|
|
||||||
throwOnError: false,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formatNumber = (num) => {
|
||||||
|
return `~${num.toExponential(0)}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalFont = `style="font-weight: normal"`;
|
||||||
|
|
||||||
|
const updateRomerTable = (romerData) => {
|
||||||
|
const tableHeader = document.getElementById("romer-table-header");
|
||||||
|
const rowA_t = document.getElementById("row-A_t");
|
||||||
|
const rowY_t = document.getElementById("row-Y_t");
|
||||||
|
|
||||||
|
tableHeader.innerHTML = `<th ${normalFont}><div class="romer-table-time"></th>`;
|
||||||
|
katex.render(`t`, document.querySelector(".romer-table-time"));
|
||||||
|
rowA_t.innerHTML = `<td class="romer-table-at"></td>`;
|
||||||
|
rowY_t.innerHTML = `<td class="romer-table-yt"></td>`;
|
||||||
|
katex.render("A_t", document.querySelector(".romer-table-at"));
|
||||||
|
katex.render("Y_t", document.querySelector(".romer-table-yt"));
|
||||||
|
|
||||||
|
romerData.forEach((d) => {
|
||||||
|
if (d.year % 20 === 0 || d.year === 1) {
|
||||||
|
tableHeader.innerHTML += `<th ${normalFont}>${d.year}</th>`;
|
||||||
|
rowA_t.innerHTML += `<td>${formatNumber(d.A)}</td>`;
|
||||||
|
rowY_t.innerHTML += `<td>${formatNumber(d.Y)}</td>`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function drawRomerGraph() {
|
||||||
|
const T_MAX = 100;
|
||||||
|
margin = { top: 20, right: 100, bottom: 20, left: 50 };
|
||||||
|
|
||||||
|
["Z", "L", "l", "A0"].forEach((param) => {
|
||||||
|
const slider = document.getElementById(`slider${param}`);
|
||||||
|
slider.oninput = function () {
|
||||||
|
slider.previousElementSibling.innerText = this.value;
|
||||||
|
drawRomerGraph();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const z = parseFloat(document.getElementById("outputZ").textContent),
|
||||||
|
L = parseFloat(document.getElementById("outputL").textContent),
|
||||||
|
l = parseFloat(document.getElementById("outputl").textContent),
|
||||||
|
A0 = parseFloat(document.getElementById("outputA0").textContent);
|
||||||
|
|
||||||
|
const container = document.getElementById("romer-visualization");
|
||||||
|
const width = container.clientWidth - margin.left - margin.right;
|
||||||
|
const height = container.clientHeight - margin.top - margin.bottom;
|
||||||
|
|
||||||
|
container.innerHTML = "";
|
||||||
|
|
||||||
|
const svg = d3
|
||||||
|
.select("#romer-visualization")
|
||||||
|
.append("svg")
|
||||||
|
.attr("width", width + margin.left + margin.right)
|
||||||
|
.attr("height", height + margin.top + margin.bottom)
|
||||||
|
.append("g")
|
||||||
|
.attr("transform", `translate(${margin.left}, ${margin.top})`);
|
||||||
|
|
||||||
|
let A = A0;
|
||||||
|
const romerData = [];
|
||||||
|
|
||||||
|
for (let t = 1; t <= T_MAX; ++t) {
|
||||||
|
const A_t = A * (1 + z * l * L);
|
||||||
|
const Y_t = A_t * (1 - l) * L;
|
||||||
|
romerData.push({ year: t, A: A_t, Y: Math.log10(Y_t) });
|
||||||
|
A = A_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
const x = d3.scaleLinear().domain([1, T_MAX]).range([0, width]);
|
||||||
|
svg
|
||||||
|
.append("g")
|
||||||
|
.attr("transform", `translate(0, ${height})`)
|
||||||
|
.call(d3.axisBottom(x))
|
||||||
|
.append("text")
|
||||||
|
.attr("fill", "#000")
|
||||||
|
.attr("x", width + 10)
|
||||||
|
.attr("y", -10)
|
||||||
|
.style("text-anchor", "end")
|
||||||
|
.style("font-size", "1.5em")
|
||||||
|
.text("t");
|
||||||
|
|
||||||
|
const y = d3
|
||||||
|
.scaleLinear()
|
||||||
|
.domain([0, romerData[romerData.length - 1].Y])
|
||||||
|
.range([height, 0]);
|
||||||
|
svg
|
||||||
|
.append("g")
|
||||||
|
.call(d3.axisLeft(y).ticks(10, d3.format(".1s")))
|
||||||
|
.append("text")
|
||||||
|
.attr("fill", "#000")
|
||||||
|
.attr("x", 0)
|
||||||
|
.attr("y", -10)
|
||||||
|
.style("text-anchor", "start")
|
||||||
|
.style("font-size", "1.5em")
|
||||||
|
.text("log(Y)");
|
||||||
|
|
||||||
|
svg
|
||||||
|
.append("path")
|
||||||
|
.datum(romerData)
|
||||||
|
.attr("fill", "none")
|
||||||
|
.attr("stroke", getTopicColor(urlToTopic()))
|
||||||
|
.attr("stroke-width", 2)
|
||||||
|
.attr(
|
||||||
|
"d",
|
||||||
|
d3
|
||||||
|
.line()
|
||||||
|
.x((d) => x(d.year))
|
||||||
|
.y((d) => y(d.Y)),
|
||||||
|
);
|
||||||
|
|
||||||
|
svg
|
||||||
|
.append("foreignObject")
|
||||||
|
.attr("width", "4em")
|
||||||
|
.attr("height", "2em")
|
||||||
|
.attr("x", x(T_MAX))
|
||||||
|
.attr("y", y(romerData[T_MAX - 1].Y))
|
||||||
|
.append("xhtml:body")
|
||||||
|
.style("font-size", "0.75em")
|
||||||
|
.html(`<div class="romer-visualization-y"></div>`);
|
||||||
|
katex.render("log_{10}Y", document.querySelector(".romer-visualization-y"));
|
||||||
|
|
||||||
|
updateRomerTable(romerData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawRomerlGraph() {
|
||||||
|
const T_MAX = 100,
|
||||||
|
z = 0.01,
|
||||||
|
L = 50,
|
||||||
|
A0 = 50;
|
||||||
|
margin = { top: 20, right: 100, bottom: 20, left: 50 };
|
||||||
|
|
||||||
|
const slider = document.getElementById(`sliderlChange`);
|
||||||
|
slider.oninput = function () {
|
||||||
|
slider.previousElementSibling.innerText = this.value;
|
||||||
|
drawRomerlGraph();
|
||||||
|
};
|
||||||
|
|
||||||
|
const l = parseFloat(document.getElementById("outputlChange").textContent);
|
||||||
|
|
||||||
|
const container = document.getElementById("romer-lchange-visualization");
|
||||||
|
const width = container.clientWidth - margin.left - margin.right;
|
||||||
|
const height = container.clientHeight - margin.top - margin.bottom;
|
||||||
|
|
||||||
|
container.innerHTML = "";
|
||||||
|
|
||||||
|
const svg = d3
|
||||||
|
.select("#romer-lchange-visualization")
|
||||||
|
.append("svg")
|
||||||
|
.attr("width", width + margin.left + margin.right)
|
||||||
|
.attr("height", height + margin.top + margin.bottom)
|
||||||
|
.append("g")
|
||||||
|
.attr("transform", `translate(${margin.left}, ${margin.top})`);
|
||||||
|
|
||||||
|
let A = A0,
|
||||||
|
l_ = 0.1;
|
||||||
|
const romerData = [];
|
||||||
|
|
||||||
|
for (let t = 1; t <= Math.floor(T_MAX / 2) - 1; ++t) {
|
||||||
|
const A_t = A * (1 + z * l_ * L);
|
||||||
|
const Y_t = A_t * (1 - l_) * L;
|
||||||
|
romerData.push({ year: t, A: A_t, Y: Math.log10(Y_t) });
|
||||||
|
A = A_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let t = Math.floor(T_MAX / 2); t <= T_MAX; ++t) {
|
||||||
|
const A_t = A * (1 + z * l * L);
|
||||||
|
const Y_t = A_t * (1 - l) * L;
|
||||||
|
romerData.push({ year: t, A: A_t, Y: Math.log10(Y_t) });
|
||||||
|
A = A_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
const x = d3.scaleLinear().domain([1, T_MAX]).range([0, width]);
|
||||||
|
svg
|
||||||
|
.append("g")
|
||||||
|
.attr("transform", `translate(0, ${height})`)
|
||||||
|
.call(d3.axisBottom(x))
|
||||||
|
.append("text")
|
||||||
|
.attr("fill", "#000")
|
||||||
|
.attr("x", width + 10)
|
||||||
|
.attr("y", -10)
|
||||||
|
.style("text-anchor", "end")
|
||||||
|
.style("font-size", "1.5em")
|
||||||
|
.text("t");
|
||||||
|
|
||||||
|
const y = d3
|
||||||
|
.scaleLinear()
|
||||||
|
.domain([0, romerData[romerData.length - 1].Y])
|
||||||
|
.range([height, 0]);
|
||||||
|
svg
|
||||||
|
.append("g")
|
||||||
|
.call(d3.axisLeft(y).ticks(10, d3.format(".1s")))
|
||||||
|
.append("text")
|
||||||
|
.attr("fill", "#000")
|
||||||
|
.attr("x", 0)
|
||||||
|
.attr("y", -10)
|
||||||
|
.style("text-anchor", "start")
|
||||||
|
.style("font-size", "1.5em")
|
||||||
|
.text("log(Y)");
|
||||||
|
|
||||||
|
svg
|
||||||
|
.append("path")
|
||||||
|
.datum(romerData)
|
||||||
|
.attr("fill", "none")
|
||||||
|
.attr("stroke", getTopicColor(urlToTopic()))
|
||||||
|
.attr("stroke-width", 2)
|
||||||
|
.attr(
|
||||||
|
"d",
|
||||||
|
d3
|
||||||
|
.line()
|
||||||
|
.x((d) => x(d.year))
|
||||||
|
.y((d) => y(d.Y)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
drawSolowGraph();
|
drawSolowGraph();
|
||||||
window.onresize = drawSolowGraph;
|
window.onresize = drawSolowGraph;
|
||||||
|
|
||||||
|
drawRomerGraph();
|
||||||
|
window.onresize = drawRomerGraph;
|
||||||
|
|
||||||
|
drawRomerlGraph();
|
||||||
|
window.onresize = drawRomerlGraph;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -68,3 +68,23 @@ ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.romer-table-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
#romer-table {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.8em;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
#romer-table th,
|
||||||
|
#romer-table td {
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue