Public
Edited
Jun 30, 2024
1 fork
7 stars
Also listed in…
Math
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// // Symbolic solution is gone since server has been shut down.
//
// symbolic_display = {
// let display = d3.create("div");
// display.append("h3").text("Symbolic solution");
// let text = "Fetching symbolic solution...";
// let temp_display = display.append("div").attr("class", "temp").text(text);
// let interval_id = setInterval(function () {
// text = text + ".";
// temp_display.text(text);
// }, 800);

// let f = f_text;
// let L = LL;
// let fEncoded = encodeURIComponent(f);
// let LEncoded = encodeURIComponent(L);
// let base_url = "https://cgi.marksmath.org/cgi-bin/fourier_series.py?";
// let query = `f=${fEncoded}&L=${LEncoded}&type=${type}`;
// let url = base_url + query;
// fetch(url).then(async function (r) {
// let result = await r.json();
// if (result.success) {
// let type_text, lower_bound;
// if (type == "full") {
// type_text = "full Fourier";
// lower_bound = `-${result.L}`;
// } else if (type == "sine") {
// type_text = "Fourier sine";
// lower_bound = "0";
// } else if (type == "cosine") {
// type_text = "Fourier cosine";
// lower_bound = "0";
// }
// clearInterval(interval_id);
// display.select(".temp").remove();
// let container = display.append("div").attr("class", "container");
// container.append("div").text("The function,");
// container.append(() => tex.block`f(x) = ${result.f}`);
// let comment = container.append("div");
// comment
// .append("span")
// .text(`has the following ${type_text} series over `);
// comment.append(() => tex`[${lower_bound},${result.L}]`);
// comment.append("span").text(":");
// container.append(() => tex.block`f(x) \sim ${result.s}.`);
// } else {
// clearInterval(interval_id);
// display.select(".temp").remove();
// let container = display.append("div").attr("class", "container");
// if (result.error == "timeout") {
// container.html("Computation timed out.");
// } else {
// container.html(
// "There's been a problem computing the symbolic solution."
// );
// }
// }
// });
// return display.node();
// }
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Compile the function specified in the input
f = {
let f_compiled = math.compile(f_text);
return x => f_compiled.evaluate({ x: x });
}
Insert cell
// Maximum number of terms
N = 100
Insert cell
// Numeric length
mutable L = math.evaluate(LL)
Insert cell
// Aproximate max for plotting purposes
fmax = {
let xmin;
if (type == 'full') {
xmin = -L;
} else {
xmin = 0;
}
let fmax = d3.max(
d3
.range(xmin, L, L / 5)
.map(function(x) {
return minimize(x => -f(x), {
lowerBound: x,
upperBound: x + L / 5
});
})
.map(f)
);
return fmax;
}
Insert cell
// Aproximate min for plotting purposes
fmin = {
let xmin;
if (type == 'full') {
xmin = -L;
} else {
xmin = 0;
}
let fmin = d3.min(
d3
.range(xmin, L, L / 5)
.map(function(x) {
return minimize(x => f(x), {
lowerBound: x,
upperBound: x + L / 5
});
})
.map(f)
);
return fmin;
}
Insert cell
Insert cell
function fourier_series(x, n) {
let sine_portion = d3.sum(
d3
.range(n)
.map(k => fc.sine_coefficients[k] * Math.sin((k * Math.PI * x) / L))
);
let cosine_portion = d3.sum(
d3
.range(n)
.map(k => fc.cosine_coefficients[k] * Math.cos((k * Math.PI * x) / L))
);
return sine_portion + cosine_portion;
}
Insert cell
fc = fourier_coefficients(f)
Insert cell
function fourier_coefficients(f) {
let sine_coefficients;
let cosine_coefficients;
if (type == 'full') {
sine_coefficients = d3
.range(N)
.map(
n =>
int(
x => f(x) * Math.sin((n * Math.PI * x) / L),
-L,
L,
1e-10,
10,
5
) / L
);
cosine_coefficients = d3
.range(N)
.map(
n =>
int(
x => f(x) * Math.cos((n * Math.PI * x) / L),
-L,
L,
1e-10,
10,
5
) / L
);
cosine_coefficients[0] = cosine_coefficients[0] / 2;
} else if (type == 'sine') {
sine_coefficients = d3
.range(N)
.map(
n =>
int(
x => 2 * f(x) * Math.sin((n * Math.PI * x) / L),
0,
L,
1e-10,
10,
5
) / L
);
cosine_coefficients = Array.from({ length: N }, x => 0);
} else if (type == 'cosine') {
cosine_coefficients = d3
.range(N)
.map(
n =>
int(
x => 2 * f(x) * Math.cos((n * Math.PI * x) / L),
0,
L,
1e-10,
10,
5
) / L
);
cosine_coefficients[0] = cosine_coefficients[0] / 2;
sine_coefficients = Array.from({ length: N }, x => 0);
}

return {
sine_coefficients: sine_coefficients,
cosine_coefficients: cosine_coefficients
};
}
Insert cell
graph_style = html`<style>
g.graph > path {
stroke-width: 3px;
stroke: path
}
</style>`
Insert cell
Insert cell
d3 = require('d3-selection@2', 'd3-array@2')
Insert cell
import { adaptiveSimpson as int } from '@rreusser/integration'
Insert cell
import { text, radio, select } from "@jashkenas/inputs"
Insert cell
import { Range, Text, Button, Toggle } from "@observablehq/inputs"
Insert cell
functionPlot = require("function-plot@1/dist/function-plot")
Insert cell
math = require('mathjs@9')
Insert cell
minimize = require('https://bundle.run/minimize-golden-section-1d@3.0.0')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more