用 JavaScript 实现改变世界的 17 个方程式

banner

数学作为一种通用语言,塑造了人类文明,推动了技术进步,揭开了宇宙的神秘面纱。

伊恩-斯图尔特(Ian Stewart)在《改变世界的 17 个方程式(17 Equations That Changed The World)》一书中概述了有助于塑造现代世界的 17 个基本方程式。本文探讨了如何用 JavaScript 来编写这些数学公式,目的是使这些复杂的概念更易于理解。

目录

  1. 勾股定理 The Pythagorean Theorem
  2. 对数 Logarithms
  3. 微积分 Calculus
  4. 牛顿万有引力定律 Newton's universal law of gravitation
  5. 复数 Complex numbers
  6. 欧拉多面体公式 Euler's formula for polyhedra
  7. 正态分布 The normal distribution
  8. 波方程 The wave equation
  9. 傅立叶变换 The Fourier transform
  10. 纳维-斯托克斯方程 The Navier-Stokes equations
  11. 麦克斯韦方程 Maxwell's equations
  12. 热力学第二定律 Second law of thermodynamics
  13. 爱因斯坦相对论 Einstein's theory of relativity
  14. 薛定谔方程 Schrödinger equation
  15. 香农信息论 Shannon's information theory
  16. 人口增长的逻辑模型 Logistic model for population growth
  17. 布莱克-斯科尔斯模型 Black–Scholes model

勾股定理 The Pythagorean Theorem

c 2 = a 2 + b 2 c^2 = a^2 + b^2

勾股定理是数学中的一个基本原理,它指出直角三角形斜边的平方等于其他两边的平方和。它在建筑、工程、物理和计算机科学等领域都有实际应用。该定理的重要性超出了其数学实用性,它为逻辑推理和解决问题奠定了基础,影响了数百年的科学思想和技术进步。

在上式中、 c c 是斜边的长度,而 a a b b 是其他两条边的长度。

在 JavaScript 中,您可以编写这样一个函数,在给定 a a b b 的情况下计算斜边的长度:

function calculateHypotenuse(a, b) {
return Math.sqrt(a * a + b * b);
}
// Example usage:
const a = 3;
const b = 4;
const hypotenuse = calculateHypotenuse(a, b);
console.log(`Hypotenuse: ${hypotenuse}`);

对数 Logarithms

log ( x y ) = log ( x ) + log ( y ) \log(xy) = \log(x) + \log(y)

对数是指数的倒数,有助于解决涉及指数增长的方程。在科学和工程领域,对数对于处理变化范围较大的数量至关重要。对数还通过简化对大数的处理,在现代计算中发挥着关键作用。

要在 JavaScript 中重写这个等式,可以使用 Math.log() 函数,它可以计算自然对数(底数为 e e ) 。下面是用 JavaScript 表示这个等式的方法:

// Assuming x and y are positive numbers
const x = /* some positive value */;
const y = /* some positive value */;
const logxy = Math.log(x * y);
const logx_plus_logy = Math.log(x) + Math.log(y);
// Now logxy should be equal to logx_plus_logy
console.log(logxy === logx_plus_logy); // This will log true if both sides are equal

在本例中,将 xy 分别设为正数,计算并比较等式的两边。这将告诉你,由于对数的性质,log(xy) 确实等于 log(x) + log(y)


微积分 Calculus

f ( x ) = lim h 0 f ( x + h ) f ( x ) h f'(x) = \lim_{h \to 0} \frac{f(x + h) - f(x)}{h}

微积分是现代数学的基础分支,包括微分和积分。微分学测量函数在输入变化时如何变化,而积分学则处理数量的累积。微积分可以解决仅靠代数无法解决的问题,在物理学、工程学、经济学和医学等各个领域都有应用。通过微积分,我们可以预测行星轨迹、设计结构和了解人口增长。

上式称为导数定义方程。下面的代码使用 JavaScript 直接实现了该方程。此示例通过计算经过函数上两点的正割直线的斜率来近似计算函数在给定点上的导数,而这两点非常接近。

function derivative(f, x, h = 1e-5) {
return (f(x + h) - f(x)) / h;
}
// Example usage:
// Define a function, for example, f(x) = x^2
function square(x) {
return x * x;
}
// Calculate the derivative of f(x) = x^2 at x = 3
const x = 3;
const derivativeAtX = derivative(square, x);
console.log(
`Derivative of f(x) = x^2 at x = ${x} is approx: ${derivativeAtX}`
);

导函数近似计算函数 f f x x 点的导数,方法是取一小步 h h ,计算函数交于 x x x + h x + h 的正割直线的斜率。

该脚本的输出结果是 f ( x ) = x 2 f(x) = x^2 x = 3 x = 3 处的切线斜率,即 f f 在该点的导数。对于 x 2 x^2 在任意点 x x 的精确导数为 2 x 2x ,因此在 x = 3 x = 3 时,导数应为 6。JavaScript 函数给出的结果应该与此非常接近,这既证明了数值导数近似的强大功能,也说明了它的局限性。


牛顿万有引力定律 Newton's universal law of gravitation

F = G m 1 m 2 r 2 F = G \frac{m_1 m_2}{r^2}

牛顿的万有引力定律由艾萨克-牛顿爵士在 17 世纪提出,它指出宇宙中的每一个物质粒子都会吸引其他每一个粒子,这个力与它们的质量乘积成正比,与它们的中心距离的平方成反比。这个优雅的等式解释了天体和坠落的苹果的运动,将天体力学和地球力学统一在一个定律之下。牛顿的万有引力定律为爱因斯坦的广义相对论铺平了道路,至今仍是预测物体间引力相互作用的基础,揭示了自然界潜在的简单性和统一性。

这一定律在数学上可以用上式表示,其中

  • F F 是两个质量之间的引力大小
  • G G 是引力常量 ( 6.674 × 1 0 11 Nm 2 / kg 2 6.674 \times 10^{-11} \, \text{Nm}^2/\text{kg}^2 )
  • m 1 m_1 m 2 m_2 是两个物体的质量
  • r r 是两个质量中心之间的距离

下面是如何在 JavaScript 中实现这一功能的方法:

function calculateGravitationalForce(m1, m2, r) {
const G = 6.674e-11; // Gravitational constant in N(m^2)/(kg^2)
return (G * (m1 * m2)) / (r * r);
}
// Example usage:
const m1 = 5.972e24; // Mass of Earth in kg
const m2 = 7.348e22; // Mass of the Moon in kg
const r = 384400e3; // Distance between Earth and Moon in meters
const force = calculateGravitationalForce(m1, m2, r);
console.log(
`The gravitational force between Earth and Moon is ${force} N`
);

这个函数 calculateGravitationalForce 将两个物体的质量和它们中心之间的距离作为输入,并返回它们之间的引力。示例根据地球和月球的质量以及它们之间的平均距离计算了它们之间的引力。

本示例演示了如何使用 JavaScript 应用牛顿万有引力定律,从而可以根据任意两个质量的质量和它们之间的距离计算出它们之间的引力。这在与物理学相关的教育软件、模拟和科学计算中非常有用。


复数 Complex numbers

i 2 = 1 i^2 = -1

复数由实部和虚部组成,它将一维数列的概念扩展到二维,从而给数学带来了革命性的变化。复数的引入是为了解决没有实数解的方程,如 x 2 = 1 x^2 = -1 复数是表达解决各种数学问题的基本方法。复数的重要性不仅在于求解多项式方程(虚数单位 1 \sqrt{-1} 在其中发挥了关键作用),还在于其在科学和工程学各个领域的应用。复数简化了电路分析,促进了量子力学的描述,在信号处理(包括滤波器、振荡器的设计和分析)以及信号转换的分析和实际应用中都举足轻重。复数的魅力在于,它提供了一个全面的框架,可以解决原本难以解决的问题,因此在理论数学和应用数学中都是不可或缺的。

在 JavaScript 中实现复数需要创建一个结构来处理复数的实部和虚部,因为 JavaScript 本身并不支持复数。对于上面的等式 i i 是虚数单位,即-1 的平方根。

下面是 JavaScript 中表示复数和实现乘法等运算的基本类,你可以用它来演示一下 i 2 = 1 i^2 = -1 .

class Complex {
constructor(real, imaginary) {
this.real = real;
this.imaginary = imaginary;
}
// Add another complex number to this one
add(other) {
return new Complex(
this.real + other.real,
this.imaginary + other.imaginary
);
}
// Multiply this complex number by another complex number
multiply(other) {
// (a + bi) * (c + di) = (ac - bd) + (ad + bc)i
const realPart =
this.real * other.real - this.imaginary * other.imaginary;
const imaginaryPart =
this.real * other.imaginary + this.imaginary * other.real;
return new Complex(realPart, imaginaryPart);
}
// Display complex number in a readable format
toString() {
return `${this.real} + ${this.imaginary}i`;
}
}
// Demonstrating i^2 = -1
const i = new Complex(0, 1); // Representing the imaginary unit i
const iSquared = i.multiply(i); // Calculating i^2
console.log(`i^2 = ${iSquared}`); // Should output: i^2 = -1 + 0i

这个 Complex 类提供了在 JavaScript 中处理复数的直接方法,包括复数的加法和乘法。multiply 方法实现了两个复数的乘法公式。

示例演示了将虚数单位 i i 创建为实部为 0、虚部为 1 的复数,然后用 i i 乘以它自己,以显示 i 2 i^2 的结果是-1(加上虚数单位的 0 倍,当虚数单位等于 0 时通常会省略)。


多面体的欧拉公式 Euler's formula for polyhedra

V E + F = 2 V - E + F = 2

欧拉多面体公式(其中 V V 代表顶点数, E E 代表边数, F F 代表面数)是莱昂哈德-欧拉在 18 世纪发现的一个简单而强大的关系。这个公式适用于包括五个柏拉图实体在内的所有凸多面体,并揭示了几何结构的一个基本特征。它的重要性在于能够将各种形状的特性统一在一个框架内,为三维空间拓扑学提供了深刻的见解。欧拉公式是几何学和拓扑学领域的基础,为数学家和科学家探索网络和图形等更复杂结构的特性提供了重要工具。

您可以编写一个 JavaScript 函数,像这样检查给定的顶点、边和面集是否满足欧拉公式:

function satisfiesEulersFormula(vertices, edges, faces) {
return vertices - edges + faces === 2;
}
// Example usage:
const vertices = 8; // For a cube
const edges = 12; // For a cube
const faces = 6; // For a cube
console.log(
`Does the given polyhedron satisfy Euler's formula? ${satisfiesEulersFormula(
vertices,
edges,
faces
)}`
);

此函数只需将多面体的顶点、边和面的数量作为输入,并检查它们是否满足欧拉公式。通过改变 verticesedges和 faces 变量,您可以使用此函数验证各种多面体的公式。


正态分布 The normal distribution

f ( x ) = 1 σ 2 π e 1 2 ( x μ σ ) 2 f(x) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{1}{2} \left(\frac{x - \mu}{\sigma}\right)^2}

正态分布是统计学和概率论的基础概念。它描述了数据在均值附近的分布。它在各种情况下自然出现,并因中心极限定理而具有重要意义。该定理指出,许多独立随机变量之和近似服从正态分布。正态分布是推断统计中的重要工具,可用于建立置信区间和假设检验。它对统计建模和预测至关重要。

上式表示正态分布的概率密度函数(PDF),其中

  • x x 是变量
  • μ \mu 是分布的平均值
  • σ \sigma 是分布的标准差
  • e e 是自然对数的底数 ( 2.71828 \approx 2.71828 )
  • π \pi 是圆周率Pi (约 3.14159)

在 JavaScript 中,您可以编写一个函数,对给定的 x x , μ \mu (均值)和 σ \sigma (标准差)计算正态分布的 PDF,如下所示:

function normalDistributionPDF(x, mu, sigma) {
const sqrtTwoPi = Math.sqrt(2 * Math.PI);
const exponent = -0.5 * ((x - mu) / sigma) ** 2;
return (1 / (sigma * sqrtTwoPi)) * Math.exp(exponent);
}
// Example usage:
const mu = 0; // Mean
const sigma = 1; // Standard deviation (for a standard normal distribution)
const x = 1; // Value to evaluate the PDF at
const pdfValue = normalDistributionPDF(x, mu, sigma);
console.log(`PDF value at x = ${x}: ${pdfValue}`);

该函数在给定正态分布的均值 ( μ \mu ) 和标准差 ( σ \sigma ) 的情况下,计算特定点 x x 处的正态分布概率密度函数(PDF)值。该函数适用于统计分析,包括概率和统计应用、数据分析和机器学习算法,其中正态分布起着至关重要的作用。


波方程 The wave equation

2 u t 2 = c 2 2 u x 2 \frac{\partial^2 u}{\partial t^2} = c^2 \frac{\partial^2 u}{\partial x^2}

波方程是描述声波、光波和水波等波在各种介质中传播的基本偏微分方程。它在物理学和工程学的众多领域都至关重要,因为它以数学上精确的形式捕捉到了波行为的本质。波方程的重要性在于它的多功能性和通用性;它可以模拟池塘涟漪的扩散、光在真空中的传播以及地震波在地球上的传播。科学家和工程师通过理解和求解波方程,可以预测波的行为、设计通信系统、分析结构对振动的响应,并通过光学和声学的视角探索宇宙,这表明波方程对技术和我们对自然世界的理解有着深远的影响。

上式表示沿 x 轴 x x 运动的一维波,其中

  • u ( x , t ) u(x, t) 是波在位置 x x 和时间 t t 处的位移
  • c c 是波在介质中的速度
  • 2 u t 2 \frac{\partial^2 u}{\partial t^2} u u 相对于时间的二次偏导数,表示加速度
  • 2 u x 2 \frac{\partial^2 u}{\partial x^2} u u 相对于位置的二次偏导数,表示波的曲率

在 JavaScript 中模拟或求解波方程需要数值方法,因为只有在特定的初始条件和边界条件下才能得到解析解。数值求解该方程的一个简单方法是使用有限差分法(FDM),对时间和空间进行离散化。下面是一个基本的实现思路:

function simulateWaveEquation(c, length, duration, dx, dt) {
// c: wave speed
// length: length of the medium
// duration: total time of simulation
// dx: space step
// dt: time step
// Calculate the number of points in space and time
const nx = Math.floor(length / dx) + 1;
const nt = Math.floor(duration / dt) + 1;
// Stability condition (Courant condition)
const courantCondition = ((c * dt) / dx) ** 2;
if (courantCondition > 1) {
throw new Error(
"Simulation may be unstable. Try adjusting dt or dx."
);
}
// Initialize wave at t=0 and t=1 (assuming initial condition and first time derivative)
let u = new Array(nx).fill(0); // Initial displacement
let uPrev = [...u]; // Copy of the initial displacement
let uNext = new Array(nx).fill(0); // Next time step
// Example: A simple initial condition (e.g., a peak in the middle)
u[Math.floor(nx / 2)] = 1;
for (let i = 1; i < nt; i++) {
for (let j = 1; j < nx - 1; j++) {
// Implementing the finite difference method for the wave equation
uNext[j] =
2 * u[j] -
uPrev[j] +
courantCondition * (u[j - 1] - 2 * u[j] + u[j + 1]);
}
// Update the previous and current solutions
uPrev = [...u];
u = [...uNext];
}
// Return the final state (for the sake of demonstration)
return u;
}
// Example parameters
const c = 1; // Wave speed
const length = 10; // Length of the medium
const duration = 2; // Total time of simulation
const dx = 0.1; // Space step
const dt = 0.01; // Time step
const finalWaveState = simulateWaveEquation(
c,
length,
duration,
dx,
dt
);
console.log(finalWaveState);

这段代码为在非常简化的条件下模拟波方程建立了一个基本结构。它假定波的两端是固定的(波在端点处无法移动),这一点通过不更新 uNext[0]uNext[nx-1](第一点和最后一点)得以体现。模拟使用的初始条件是介质中间有一个波峰,然后根据波方程进行演变。

本示例使用的是非常基本的初始条件,并没有考虑更复杂的情况或边界条件。在实际应用中,您需要调整初始化和可能的更新循环,以反映您的特定需求,包括不同的初始条件、边界条件和更复杂的数值方法,以确保稳定性和准确性。


傅立叶变换 The Fourier transform

X k = n = 0 N 1 x n e 2 π i N k n X_k = \sum_{n=0}^{N-1} x_n \cdot e^{-\frac{2\pi i}{N} kn}

傅立叶变换是将函数、信号或波形分解为其组成频率的重要数学工具,就像将和弦分解为单个音符一样。这种从时域到频域的变换为分析和理解各领域的复杂系统提供了一种强大的方法。

由于快速傅里叶变换(FFT)--一种计算 DFT 的更高效算法--对于本示例来说过于复杂,因此这里的实现是针对离散傅里叶变换(DFT)的。

上述公式可描述如下

  • X k X_k 是变换后信号的第 k k 个分量
  • x n x_n 是原始信号的第 n n 个样本
  • N N 是样本总数
  • e e 是自然对数的底数
  • i i 是虚数单位 ( 1 \sqrt{-1} )

下面是用 JavaScript 编写的计算信号 DFT 的函数:

function discreteFourierTransform(signal) {
const N = signal.length;
let X = new Array(N);
for (let k = 0; k < N; k++) {
let sum = 0;
for (let n = 0; n < N; n++) {
const phi = (2 * Math.PI * k * n) / N;
sum += signal[n] * (Math.cos(phi) - Math.sin(phi) * 1j);
}
X[k] = sum;
}
return X;
}
// Example usage:
const signal = [0, 1, 2, 3, 4, 5, 6, 7]; // An example signal
const DFT = discreteFourierTransform(signal);
console.log(DFT);

不过,JavaScript 本身并不支持复数(如代码中的 1j),因此需要实现或使用复数运算库。下面是处理复数并相应调整 DFT 函数的基本方法:

class Complex {
constructor(re, im = 0) {
this.re = re;
this.im = im;
}
add(other) {
return new Complex(this.re + other.re, this.im + other.im);
}
multiply(other) {
return new Complex(
this.re * other.re - this.im * other.im,
this.re * other.im + this.im * other.re
);
}
static exp(phi) {
return new Complex(Math.cos(phi), Math.sin(phi));
}
}
function discreteFourierTransform(signal) {
const N = signal.length;
let X = new Array(N).fill(null).map(() => new Complex(0));
for (let k = 0; k < N; k++) {
let sum = new Complex(0, 0);
for (let n = 0; n < N; n++) {
const phi = (-2 * Math.PI * k * n) / N;
const c = Complex.exp(phi);
sum = sum.add(c.multiply(new Complex(signal[n])));
}
X[k] = sum;
}
return X;
}
// Example usage:
const signal = [0, 1, 2, 3, 4, 5, 6, 7]; // An example signal
const DFT = discreteFourierTransform(signal).map(
(c) => `${c.re.toFixed(2)}, ${c.im.toFixed(2)}`
);
console.log(DFT);

此调整版本使用 Complex 类来处理复数及其算术运算,从而使 DFT 计算正常运行。DFT 输出是一个 Complex 对象数组,其中每个对象代表原始信号的一个频率分量。toFixed(2) 方法用于格式化输出以提高可读性,显示每个分量的实部和虚部。请记住,对于大型信号或实际应用,您可能会使用现有库或 FFT 算法来提高效率。


纳维-斯托克斯方程 The Navier-Stokes equations

u t + ( u ) u = 1 ρ p + ν 2 u + f \frac{\partial \mathbf{u}}{\partial t} + (\mathbf{u} \cdot \nabla) \mathbf{u} = -\frac{1}{\rho} \nabla p + \nu \nabla^2 \mathbf{u} + \mathbf{f}

纳维-斯托克斯方程以克劳德-路易-纳维叶和乔治-加布里埃尔-斯托克斯的名字命名,是一组描述液体和气体等流体物质运动的非线性偏微分方程。这些方程是流体动力学的基础,通过计算作用在流体质点上的各种力(包括压力、粘性力和外力)来捕捉流体流动现象的本质。纳维-斯托克斯方程的重要性无论怎样强调都不为过;它们对于模拟天气模式、设计飞机和汽车、了解洋流以及分析人体血液流动都至关重要。此外,它们在环境科学、化学工程和天体物理学中也发挥着至关重要的作用。求解这些方程有助于预测流体在复杂情况下的行为,使它们成为工程师、物理学家和数学家推动技术进步和了解自然现象不可或缺的工具。

在 JavaScript 中为流体动力学模拟实现该方程需要对方程进行离散化和数值求解。这项任务相当复杂,通常需要大量代码,特别是处理各种边界条件和确保数值稳定性的代码。因此,我们只能在此展示一个简化示例,勾勒出非常简单情况下的基本结构,例如在均匀网格中的二维流体,并提出一些假设以保持可管理性

这个示例并不能完全求解纳维-斯托克斯方程,但可以说明如何使用有限差分法求解空间导数,欧拉法求解时间导数,从而建立求解器的结构。

假设:

  • 流体不可压缩 ( u = 0 \nabla \cdot \mathbf{u} = 0 )
  • 密度 ρ \rho 是常数
  • 我们在 x x 维和 y y 维的二维域中工作
  • 为简单起见,外力 f \mathbf{f} 忽略不计
  • 使用简单的欧拉法进行时间步进
// Parameters
const nx = 20; // Number of grid points in x direction
const ny = 20; // Number of grid points in y direction
const nu = 0.01; // Kinematic viscosity
const dt = 0.1; // Time step
const rho = 1.0; // Density, assuming constant
// Initialize velocity and pressure fields
const u = new Array(ny).fill(0).map(() => new Array(nx).fill(0));
const v = new Array(ny).fill(0).map(() => new Array(nx).fill(0));
const p = new Array(ny).fill(0).map(() => new Array(nx).fill(0));
// Function to approximate the first derivatives using central difference
function derivative(arr, dx, axis) {
const result = new Array(arr.length)
.fill(0)
.map(() => new Array(arr[0].length).fill(0));
for (let i = 1; i < arr.length - 1; i++) {
for (let j = 1; j < arr[i].length - 1; j++) {
if (axis === "x") {
result[i][j] = (arr[i][j + 1] - arr[i][j - 1]) / (2 * dx);
} else if (axis === "y") {
result[i][j] = (arr[i + 1][j] - arr[i - 1][j]) / (2 * dx);
}
}
}
return result;
}
// Function to approximate the second derivatives using central difference
function secondDerivative(arr, dx) {
// Similar to derivative function but for second derivatives
// This is a placeholder; implementation would be similar to the first derivative
}
// Main update function (simplified and not fully accurate)
function updateVelocity(u, v, p, nu, dt, dx, dy) {
// Calculate derivatives
const uxx = secondDerivative(u, dx);
const uyy = secondDerivative(u, dy);
const vxx = secondDerivative(v, dx);
const vyy = secondDerivative(v, dy);
const ux = derivative(u, dx, "x");
const uy = derivative(u, dy, "y");
const vx = derivative(v, dx, "x");
const vy = derivative(v, dy, "y");
const px = derivative(p, dx, "x");
const py = derivative(p, dy, "y");
// Update velocities (simplified Euler integration)
for (let i = 1; i < ny - 1; i++) {
for (let j = 1; j < nx - 1; j++) {
u[i][j] -=
dt *
(u[i][j] * ux[i][j] +
v[i][j] * uy[i][j] +
px[i][j] / rho +
nu * (uxx[i][j] + uyy[i][j]));
v[i][j] -=
dt *
(u[i][j] * vx[i][j] +
v[i][j] * vy[i][j] +
py[i][j] / rho +
nu * (vxx[i][j] + vyy[i][j]));
}
}
}
// Placeholder function for pressure calculation
// Real implementation would solve the pressure Poisson equation
function updatePressure(p, u, v, dx, dy) {
// This is a placeholder; actual implementation is complex
}
// Example of running an update
updateVelocity(u, v, p, nu, dt, 1.0 / nx, 1.0 / ny);

如前所述,这段代码并不直接求解纳维-斯托克斯方程,而是提供了一个结构,演示如何实现这些方程。


麦克斯韦方程组 Maxwell's equations

× H = J + ϵ 0 E t \nabla \times \mathbf{H} = \mathbf{J} + \epsilon_0\frac{\partial \mathbf{E}}{\partial t}

麦克斯韦方程组是由詹姆斯-克拉克-麦克斯韦在 19 世纪提出的,是一套关于电学和磁学的基本定律。该方程描述了电荷和电流如何产生电场和磁场,以及这些场如何相互影响并与物质相互作用。从经典电动力学到现代物理学,麦克斯韦方程对于理解和预测各种情况下的电磁场行为至关重要。几乎所有现代电气和电子技术,包括发电机、电动机、无线电、电视和电信,都是以麦克斯韦方程为基础的。

在 JavaScript 中实现上述方程需要模拟磁场 ( H H )如何受到电流密度 ( J J ) 和电场时间变化率 ( E E )的影响。由于涉及矢量微积分和电磁场随时间的变化,这种模拟可能会很复杂。不过,简化的方法可以说明这一概念。首先,让我们定义离散空间中每个项所代表的含义,假设是均匀线性材料,并为简单起见忽略边界条件。我们不会直接求解方程,而是演示如何为模拟步骤设置数值。

假设:

  • H H 是磁场矢量
  • J J 是电流密度矢量
  • E E 是电场矢量
  • ϵ 0 \epsilon_0 是真空介电常数
  • E t \frac{\partial \mathbf{E}}{\partial t} 由有限差分 Δ E Δ t \frac{\Delta \mathbf{E}}{\Delta t} 近似

下面是 JavaScript 的写法:

const epsilon0 = 8.854187817e-12; // Vacuum permittivity in F/m (farads per meter)
// Example vectors represented as arrays [x, y, z]
const H = [0, 0, 1]; // Example magnetic field vector
const J = [0.1, 0.1, 0]; // Example current density vector
const E = [1, 0, 0]; // Initial electric field vector
const E_prev = [0.9, 0, 0]; // Electric field vector at previous time step
const deltaTime = 0.1; // Time step in seconds
// Function to calculate the rate of change of the electric field
function rateOfChangeE(E, E_prev, deltaTime) {
return E.map((value, index) => (value - E_prev[index]) / deltaTime);
}
// Function to update the magnetic field based on Ampère's Law with Maxwell's addition
function updateMagneticField(H, J, rateOfChangeE, epsilon0) {
// Assuming a simple model where each component of H is updated directly
// This is a conceptual demonstration and not a direct numerical solution of the curl equation
return H.map(
(value, index) =>
value + J[index] + epsilon0 * rateOfChangeE[index]
);
}
// Calculate the rate of change of E
const rateOfChangeEVector = rateOfChangeE(E, E_prev, deltaTime);
// Update the magnetic field H
const updatedH = updateMagneticField(
H,
J,
rateOfChangeEVector,
epsilon0
);
console.log(`Updated Magnetic Field H: [${updatedH.join(", ")}]`);

该代码计算两个时间步之间电场矢量 ( E E ) 的变化率,并根据安培定律和麦克斯韦加法更新磁场矢量 ( H H ) 。

rateOfChangeE函数使用简单的有限差分近似计算 E E 的时间变化率。

updateMagneticField 函数通过添加电流密度 ( J J ) 的影响和 E E 的时间导数(按 ϵ 0 \epsilon_0 来更新 H H

该演示高度简化,抽象出了求解矢量微分方程的复杂性。在实际应用中,求解 H H 场和 E E 场的麦克斯韦方程通常需要使用有限元分析 (FEA) 或有限差分时域 (FDTD) 等数值方法,而且通常使用为计算电磁学设计的专用软件或库来执行此类计算。


热力学第二定律 Second law of thermodynamics

Δ S = Q T \Delta S = \frac{Q}{T}

热力学第二定律是物理学的一项基本原理,它指出一个孤立系统的总熵或无序度永远不会随着时间的推移而减少;它只能保持不变或增加。这一定律强调了自然过程的不可逆性质,表明能量转化并非百分之百有效,因为总会有一些能量因无序而损失。第二定律的重要性超出了理论物理学的范畴,进入了实际应用领域:它制约着发动机、冰箱和所有能量转换设备的效率极限,影响着我们对能源管理、可持续发展和宇宙最终命运的理解。它解释了为什么永动机是不可能的,并驱动着热传递的方向,使其成为工程学、化学和环境科学中不可或缺的一部分。

虽然第二定律本身是一个原理而非数学公式,但我们可以通过计算给定过程的熵变化( Δ S \Delta S )来说明它的一个方面。计算热量传递时系统熵变的一个简单方法是使用上述公式。

其中:

  • Δ S \Delta S 是熵的变化
  • Q Q 是添加到系统中的热量(焦耳)
  • T T 是系统的绝对温度(开尔文)

为简单起见,该公式假定过程可逆且温度恒定。下面是一个 JavaScript 函数的计算方法:

function calculateEntropyChange(heat, temperature) {
// heat: heat added to the system in joules
// temperature: absolute temperature in kelvins
if (temperature <= 0) {
throw new Error("Temperature must be greater than 0 K");
}
const deltaS = heat / temperature;
return deltaS; // Change in entropy in joules per kelvin (J/K)
}
// Example usage:
const heat = 1000; // Heat added in joules
const temperature = 300; // Absolute temperature in kelvins
const entropyChange = calculateEntropyChange(heat, temperature);
console.log(`Change in entropy: ${entropyChange} J/K`);

为简单起见,该公式假定过程可逆且温度恒定。下面是一个 JavaScript 函数的计算方法:

热力学第二定律是物理化学和热力学的基础,包括热量传递的方向、发动机的效率以及某些化学反应的自发性质。对于更复杂的系统或过程,计算需要考虑到系统内发生的特定条件和相互作用。


爱因斯坦的相对论 Einstein's theory of relativity

E = m c 2 E = mc^2

爱因斯坦的相对论包括狭义相对论和广义相对论,彻底改变了我们对空间、时间和引力的理解。狭义相对论于 20 世纪初提出,它挑战了传统观念,表明物理定律对所有非加速观察者都是相同的,而且真空中的光速是恒定的,与观察者的速度无关。这产生了深远的影响,包括时间膨胀和长度收缩。广义相对论进一步扩展了这些观点,提出引力不是质量间的作用力,而是由质量和能量引起的时空曲率效应。爱因斯坦的理论对现代物理学至关重要,是全球定位系统等技术的基础,也是从黑洞行为到宇宙膨胀等宇宙结构的基础。

构成爱因斯坦相对论的方程过于复杂,无法在此演示,但经典方程 E = m c 2 E = mc^2 却非常简单,它说明物质和能量是等价的。

在这个等式中, c c 是真空中的光速,约为每秒 3.00 × 1 0 8 3.00 \times 10^8 米。这个等式表明,质量可以转化为能量,反之亦然。

对于一个简单的 JavaScript 函数,如果要使用这个等式计算给定质量的能量等值,可以这样写:

function massEnergyEquivalence(mass) {
const speedOfLight = 3.0e8; // Speed of light in meters per second
return mass * Math.pow(speedOfLight, 2);
}
// Example usage:
const mass = 1; // 1 kilogram
const energy = massEnergyEquivalence(mass);
console.log(`Energy equivalent of ${mass} kg: ${energy} joules`);

该函数计算与给定质量(千克)相当的能量(焦耳)。


薛定谔方程 Schrödinger equation

2 2 m d 2 ψ ( x ) d x 2 + V ( x ) ψ ( x ) = E ψ ( x ) -\frac{\hbar^2}{2m}\frac{d^2\psi(x)}{dx^2} + V(x)\psi(x) = E\psi(x)

薛定谔方程由埃尔温-薛定谔于 1926 年提出,是量子力学的基础方程,描述了物理系统的量子态如何随时间变化。它对于理解原子和亚原子尺度的粒子行为至关重要,体现了量子理论的核心--波粒二象性。该方程提供了一种计算粒子位置和动量概率振幅的方法,从而可以预测一系列物理特性和现象,如能级、键合结构和原子中电子的行为。它的意义超出了理论物理学的范畴,影响着化学、材料科学以及半导体、激光和量子计算等技术的发展。

用 JavaScript 编写薛定谔方程需要进行简化,因为方程本身是一个复杂的偏微分方程,用于描述物理系统的量子态。上述方程是一维中与时间无关的薛定谔方程, 其中:

  • h h 是缩小的普朗克常数
  • m m 是粒子的质量
  • d 2 ψ ( x ) d x 2 \frac{d^2\psi(x)}{dx^2} 是波函数 ψ ( x ) \psi(x) 相对于位置 x x 的二阶导数
  • V ( x ) V(x) 是作为位置函数的势能
  • E E 是粒子的总能量
  • ψ ( x ) \psi(x) 是粒子的波函数

在给定势能 V ( x ) V(x) 的情况下,分析或数值求解 ψ ( x ) \psi(x) 的这个方程需要了解微分方程和数值方法,这可能很复杂,超出了简单 JavaScript 函数的范围。

不过,我可以举例说明如何建立一个结构来数值求解简化版的薛定谔方程,例如,使用有限差分法(FDM)求解盒子中的粒子,其中盒子内的 V ( x ) = 0 V(x)=0 而盒子外的无穷大。这是一个高度简化的方案,用于教学目的:

// Constants
const hbar = 1.0545718e-34; // Reduced Planck's constant (Joule-second)
const m = 9.10938356e-31; // Mass of an electron (kg)
// Potential energy function V(x), assuming a particle in a box where V(x) = 0
function V(x) {
return 0;
}
// Simplified setup for the Schrödinger equation in a "particle in a box" scenario
function solveSchrodinger(N, L) {
// N: Number of points
// L: Length of the box (meters)
const dx = L / (N - 1); // Step size
const dx2 = dx * dx;
const factor = Math.pow(-hbar, 2) / (2 * m * dx2);
// Initialize the wave function array and potential energy array
let psi = new Array(N).fill(0);
let potential = new Array(N).fill(0).map((_, i) => V(i * dx));
// Example: Finite difference method (FDM) setup (not fully implemented)
// This is a placeholder to illustrate where the FDM or other numerical method would go
// Return the wave function (this is a simplified placeholder)
return psi;
}
// Example usage (this is a conceptual example and not a complete solution)
const N = 100; // Number of points
const L = 1e-10; // Length of the box in meters (e.g., 1 nm)
const psi = solveSchrodinger(N, L);
console.log(psi); // This would output the wave function array (placeholder values)

这个脚本建立了一个基本结构,但实际上并不求解薛定谔方程,因为实现数值求解(如有限差分法)需要更复杂的代码和对数值分析的理解。数值求解薛定谔方程的真正挑战在于设置和求解相关的线性代数问题,这通常涉及构建表示方程的哈密顿矩阵并对其进行对角。在实际应用中,您可能会使用专为科学计算设计的数值库和软件,如 Python 中的 SciPy,而不是用 JavaScript 从头开始实现。


香农信息论 Shannon's information theory

H ( X ) = i = 1 n P ( x i ) log b P ( x i ) H(X) = -\sum_{i=1}^{n} P(x_i) \log_b P(x_i)

克劳德-香农于 1948 年提出的香农信息论是通信和数据处理领域的基石。它定量地定义了信息的概念,引入了信息含量、熵和冗余度的测量方法。通过确定压缩数据和在噪声信道上可靠传输数据的基本限制,香农的工作为现代数字通信和数据存储技术奠定了基础。其重要性远远超出了电信领域,对计算机科学、密码学、语言学和认知科学都产生了影响。

香农的信息论,尤其是熵的概念,量化了信息中包含的不确定性或信息量。一个可能值为 x 1 , x 2 , , x n x_1, x_2, \ldots, x_n 的离散随机变量和概率质量函数 P ( x ) P(x) 的熵( H H ) 如上式。

其中, b b 是所用对数的底数,通常为 2(比特)、e(纳特)或 10(哈特里)。当 b = 2 b = 2 时,熵的单位是比特,这在信息论中最为常见。

下面是如何用 JavaScript 实现熵的计算:

function calculateEntropy(probabilities, base = 2) {
// probabilities: an array of probabilities for each outcome
// base: the base of the logarithm (default is 2 for bits)
const log =
base === 2 ? Math.log2 : base === Math.E ? Math.log : Math.log10;
let entropy = 0;
for (let p of probabilities) {
if (p > 0) {
// Ensure probability is positive to avoid NaN results
entropy -= p * log(p);
}
}
return entropy;
}
// Example usage:
const probabilities = [0.5, 0.5]; // Fair coin flip probabilities for heads and tails
const entropyBits = calculateEntropy(probabilities); // Default is base 2
console.log(`Entropy: ${entropyBits} bits`);
// For a more complex example, probabilities of a dice roll
const diceProbabilities = [1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6];
const entropyDice = calculateEntropy(diceProbabilities);
console.log(`Entropy of a fair dice roll: ${entropyDice} bits`);

函数 calculateEntropy 在给定概率和对数底数的情况下计算分布的香农熵。熵衡量的是随机变量结果的平均信息含量。在信息论中,熵值越高意味着信息的不确定性越大或信息含量越多,而熵值越低则表示不确定性越小或信息冗余越少。


人口增长的逻辑模型 Logistic model for population growth

P n + 1 = r P n ( 1 P n ) P_{n+1} = r P_n (1 - P_n)

罗伯特-梅(Robert May)在 20 世纪 70 年代对人口增长的逻辑模型进行了重新研究,这标志着科学家对动态系统及其在生物种群中应用的看法发生了关键性转变。梅的研究表明,简单的非线性模型,如对数方程,在某些条件下会表现出混沌行为。这一见解具有开创性,因为它挑战了自然界中复杂行为需要复杂模型的普遍观点。通过将对数模型应用于种群,梅证明了种群动态可能是不可预测的,并且对初始条件高度敏感,这是混沌理论的一个标志。他的研究强调了在生态模型中考虑非线性效应和混沌的重要性,影响了生态学以外的领域,包括经济学、气象学和流行病学。

上式假设如下:

  • P n P_n 是时间步 n n 的种群数量
  • r r 是增长率
  • P n + 1 P_{n+1} 是下一个时间步长 ( n + 1 n+1 ) 时的种群数量

在这个模型中,人口数量被归一化,使得承载能力 K = 1 K = 1 ,而 P n P_n 代表承载能力的比例(因此, 0 P n 1 0 \leq P_n \leq 1 ).

下面是用 JavaScript 实现逻辑图的方法:

function logisticMap(r, P0, n) {
// r: growth rate
// P0: initial population proportion (0 <= P0 <= 1)
// n: number of iterations/generations
let P = P0; // Initialize population size
for (let i = 0; i < n; i++) {
P = r * P * (1 - P); // Apply logistic map equation
}
return P;
}
// Example usage:
const r = 3.5; // Growth rate
const P0 = 0.5; // Initial population proportion (as a fraction of carrying capacity)
const n = 10; // Number of iterations
const populationAtN = logisticMap(r, P0, n);
console.log(
`Population proportion at iteration ${n}: ${populationAtN}`
);

该函数从初始比例 P 0 P_0 开始,以 r r 的速率增长,计算 n n 次迭代后的种群比例。在这个模型中, r r 的值至关重要;根据其值的不同,系统可以表现出稳定、周期性或混乱的行为。例如,当 r r 介于 1 和 3 之间时,种群数量达到稳定平衡。在 3 到大约 3.57 之间,种群会进入一个振荡期,超过 3.57 后,系统会表现出混沌行为,这意味着初始条件( P 0 P_0 )或参数 r r 的微小变化会导致截然不同的结果。


布莱克-斯科尔斯模型 Black–Scholes model

C = S 0 N ( d 1 ) K e r T N ( d 2 ) C = S_0 \cdot N(d_1) - K \cdot e^{-rT} \cdot N(d_2)

P = K e r T N ( d 2 ) S 0 N ( d 1 ) P = K \cdot e^{-rT} \cdot N(-d_2) - S_0 \cdot N(-d_1)

布莱克-斯科尔斯模型由经济学家费舍尔-布莱克(Fischer Black)和迈伦-斯科尔斯(Myron Scholes)于 20 世纪 70 年代初提出,后由罗伯特-默顿(Robert Merton)加以扩展,为欧式期权和衍生品的估值提供了一个理论框架,从而彻底改变了金融经济学领域。这个开创性的模型通过考虑几个变量来计算期权的价格,包括标的资产的价格、期权的执行价格、到期时间、无风险利率和资产的波动率。布莱克-斯科尔斯公式的重要性在于它能够为期权定价提供一种一致而精确的方法,而在该公式推出之前,期权定价缺乏科学依据。

上述公式可分别用于计算欧式看涨期权和看跌期权的理论价格,其中:

  • C C 是看涨期权价格
  • P P 是看跌期权价格
  • S 0 S_0 是当前股票价格
  • K K 是期权的执行价格
  • r r 为无风险利率
  • T T 是到期时间(单位:年)
  • N ( ) N(\cdot) 是标准正态分布的累积分布函数
  • d 1 d_1 d 2 d_2 计算公式如下:

d 1 = ln ( S 0 K ) + ( r + σ 2 2 ) T σ T d_1 = \frac{\ln(\frac{S_0}{K}) + (r + \frac{\sigma^2}{2})T}{\sigma\sqrt{T}}

d 2 = d 1 σ T d_2 = d_1 - \sigma\sqrt{T}

  • σ \sigma 是股票收益的波动率

在 JavaScript 中,可以用 Black-Scholes 公式计算看涨和看跌期权的价格,如下所示:

function normCDF(x) {
// Approximation of the cumulative distribution function for the standard normal distribution
const a1 = 0.254829592;
const a2 = -0.284496736;
const a3 = 1.421413741;
const a4 = -1.453152027;
const a5 = 1.061405429;
const p = 0.3275911;
const t = 1 / (1 + p * x);
const y =
1 -
((((a5 * t + a4) * t + a3) * t + a2) * t + a1) *
t *
Math.exp(-x * x);
return 0.5 * (1 + Math.sign(x) * y);
}
function blackScholes(S, K, T, r, sigma, optionType) {
const d1 =
(Math.log(S / K) + (r + (sigma * sigma) / 2) * T) /
(sigma * Math.sqrt(T));
const d2 = d1 - sigma * Math.sqrt(T);
if (optionType === "call") {
return S * normCDF(d1) - K * Math.exp(-r * T) * normCDF(d2);
} else if (optionType === "put") {
return K * Math.exp(-r * T) * normCDF(-d2) - S * normCDF(-d1);
} else {
throw new Error("optionType must be either 'call' or 'put'");
}
}
// Example usage:
const currentStockPrice = 100; // S
const strikePrice = 100; // K
const timeToMaturity = 1; // T in years
const riskFreeInterestRate = 0.05; // r
const volatility = 0.2; // sigma
const callOptionPrice = blackScholes(
currentStockPrice,
strikePrice,
timeToMaturity,
riskFreeInterestRate,
volatility,
"call"
);
const putOptionPrice = blackScholes(
currentStockPrice,
strikePrice,
timeToMaturity,
riskFreeInterestRate,
volatility,
"put"
);
console.log("Call Option Price: " + callOptionPrice.toFixed(2));
console.log("Put Option Price: " + putOptionPrice.toFixed(2));

这个 JavaScript 函数根据 Black-Scholes 模型计算看涨或看跌期权的价格。请注意,normCDF 是标准正态分布的累积分布函数的近似值,用于计 N ( d 1 ) N(d_1) N ( d 2 ) N(d_2) 。请记住,Black-Scholes 模型有其局限性和假设条件,如波动率恒定和不分红,这并不是在 所有市场条件下都适用的。