微分方程式の入門
微分方程式とは
「薬を飲んだ後、体内の薬の濃度はどう変化するか」——飲んだ直後は濃度が高く、時間とともに体外に排出されて濃度は下がっていきます。このとき、「今の濃度が高いほど排出も速い」という関係があります。「今の状態がどれだけ速く変化するか」を数式で表したものが微分方程式です。
普通の方程式(例:)は「ある数」を求めますが、微分方程式は「ある関数(時間とともに変化するパターン全体)」を求めます——「 を含む方程式を解く」のが微分方程式(ordinary differential equation, ODE)です。
最も基本的な形は:
変数分離形
「 の部分と の部分を左辺・右辺に分けて、それぞれ別々に積分できる形」——これが変数分離形です:
の形を変数分離形といいます。 に関する式と に関する式に分けて積分できます——「 の仲間は右へ、 の仲間は左へ」:
最重要例:
「今の量が多いほど、変化も速い」——細胞の増殖や放射性物質の崩壊など、自然界でもっとも頻繁に登場するパターンです。 を定数として変数分離すると:
積分定数 (任意定数)とすれば——「 をまとめて新しい定数 で置き換える」:
解の族(Family of Solutions)
「 の値を変えるたびに、別の解が得られる」—— なら 、 なら 、というように、同じルール(微分方程式)に従いながらも、出発点(初期条件)の違いによって異なる軌跡を描く曲線の集まりを解の族(family of solutions)といいます。
重要な性質:解の族の曲線は互いに交わらない( の場合)。
これは解の一意性定理から保証されます——「ある一点を通る解はただ一つ」なので、二つの解曲線が交わることは絶対にありません。初期条件 が決まれば、解は一意に決まります。
デモ: の解の族
複数の 値に対する解曲線を描画しています。マウスを左右に動かすと、マウス位置を通る解曲線が強調表示されます。解がどこでも交差しないことを確認してください。
function loop() {
ctx.clearRect(0, 0, W, H);
var scale=50;
var ox=W/2, oy=H/2;
var k=0.3;
function toSx(x){return ox+x*scale;}
function toSy(y){return oy-y*scale;}
function drawAxes(){
ctx.strokeStyle='rgba(255,255,255,0.13)';
ctx.lineWidth=1;
ctx.beginPath();ctx.moveTo(0,oy);ctx.lineTo(W,oy);ctx.stroke();
ctx.beginPath();ctx.moveTo(ox,0);ctx.lineTo(ox,H);ctx.stroke();
ctx.fillStyle='rgba(255,255,255,0.25)';
ctx.font='10px monospace';
ctx.textAlign='center';
for(var i=-5;i<=5;i++){
if(i===0)continue;
ctx.fillText(i,toSx(i),oy+14);
}
ctx.textAlign='right';
for(var j=-3;j<=3;j++){
if(j===0)continue;
ctx.fillText(j,ox-6,toSy(j)+4);
}
}
function plotSolution(C,color,lw,alpha){
ctx.strokeStyle=color;ctx.lineWidth=lw||1.5;
ctx.globalAlpha=alpha||1;
ctx.beginPath();
var first=true;
for(var xi=-W/2;xi<=W/2;xi+=1){
var x=xi/scale;
var y=C*Math.exp(k*x);
if(!isFinite(y)||Math.abs(y)>H/scale+0.5){first=true;continue;}
if(first){ctx.moveTo(toSx(x),toSy(y));first=false;}
else ctx.lineTo(toSx(x),toSy(y));
}
ctx.stroke();
ctx.globalAlpha=1;
}
ctx.fillStyle='#0d1117';
ctx.fillRect(0,0,W,H);
drawAxes();
// Mouse: find C such that the curve passes through (mx, my) approximately
var xm=(mx-ox)/scale;
var ym=(oy-my)/scale;
// y = C*exp(k*xm) -> C = y/exp(k*xm)
var Cmouse=ym/Math.exp(k*xm);
// Colors for family
var cValues=[-3,-2,-1.5,-1,-0.5,0.5,1,1.5,2,3];
var colors=['#ef5350','#ff7043','#ffa726','#ffca28','#d4e157','#66bb6a','#26c6da','#42a5f5','#7e57c2','#ec407a'];
for(var ci=0;ci<cValues.length;ci++){
var C=cValues[ci];
var isClose=Math.abs(C-Cmouse)<0.3;
plotSolution(C, colors[ci%colors.length], isClose?2.5:1, isClose?1:0.3);
}
// Highlighted curve for mouse position
if(isFinite(Cmouse)&&Math.abs(Cmouse)<4){
plotSolution(Cmouse,'#ffffff',2.5,0.9);
// Dot at mouse position
ctx.beginPath();ctx.arc(toSx(xm),toSy(ym),7,0,Math.PI*2);
ctx.fillStyle='#ffca28';ctx.fill();
ctx.strokeStyle='#fff';ctx.lineWidth=2;ctx.stroke();
// Tangent direction (slope = k*y)
var slope=k*ym;
var ext=0.8;
ctx.strokeStyle='rgba(255,202,40,0.7)';
ctx.lineWidth=1.5;
ctx.setLineDash([4,4]);
ctx.beginPath();
ctx.moveTo(toSx(xm-ext),toSy(ym-slope*ext));
ctx.lineTo(toSx(xm+ext),toSy(ym+slope*ext));
ctx.stroke();
ctx.setLineDash([]);
// Info panel
ctx.fillStyle='rgba(0,0,0,0.75)';
ctx.fillRect(8,8,280,100);
ctx.font='13px monospace';ctx.textAlign='left';
ctx.fillStyle='rgba(255,255,255,0.8)';
ctx.fillText('dy/dx = 0.3y',14,28);
ctx.fillStyle='#ffca28';
ctx.fillText('C = '+Cmouse.toFixed(3),14,46);
ctx.fillStyle='#fff';
ctx.fillText('y = '+Cmouse.toFixed(2)+'·e^{0.3x}',14,64);
ctx.fillStyle='#81c784';
ctx.fillText('傾き dy/dx = '+slope.toFixed(3),14,82);
}
// y=0 line label (C=0 solution)
ctx.fillStyle='rgba(255,255,255,0.4)';
ctx.font='11px monospace';ctx.textAlign='left';
ctx.fillText('C=0: y≡0',ox+5,oy-8);
ctx.font='12px sans-serif';ctx.textAlign='center';
ctx.fillStyle='rgba(255,255,255,0.4)';
ctx.fillText('解の族 y = Ce^{0.3x} — 曲線は互いに交わらない',W/2,H-10);
requestAnimationFrame(loop);
}
loop(); 初期条件と特殊解
「解の族」から一つの解を選び出すには初期条件(initial condition)が必要です——「 のとき がどこにいるかを指定すると、曲線が一本に決まる」:
例:、 → →
「出発点が決まれば、その先の軌跡が自動的に決まる」——これが初期値問題の本質です。
応用例:人口増加モデル
「食料が十分にある離島に動物を放したとき、個体数はどう増えるか」——個体数 が増えるほど子どもの数も増えるので、「増加速度 ∝ 現在の個体数」という関係が成り立ちます:
解:
これはマルサスモデル(指数成長)と呼ばれ、食料・資源が十分な初期段階の人口増加を記述します——「最初はゆっくり増えているように見えても、時間が経つと急激に爆発的に増える」のが指数成長の特徴です。
応用例:放射性崩壊
「原子が不安定で、時間とともに別の原子に変わっていく」——残っている原子が多いほど、単位時間に崩壊する数も多い:
解:
半減期 :「最初の量が半分になるまでの時間」—— より
炭素 14 の半減期は約 5730 年——これを利用して古代の木材や化石の年代を測定するのが放射性炭素年代測定法です。
ロジスティック方程式(発展)
「指数成長は永遠には続かない——島が狭くなれば動物も増えにくくなる」——環境収容力 (島が養える最大個体数)を導入したモデルがロジスティック方程式です:
「 が に近づくほど右のカッコ内がゼロに近づき、成長が自然にブレーキがかかる」——変数分離で解くと:
で (収容力に収束する S 字曲線)——「最初は指数的に増えるが、途中から頭打ちになって収容力に近づく」のが S 字成長の特徴です。
2 階線形微分方程式(基礎)
「バネを引っ張って離すと、元の位置に引き戻される力が生まれる」——これがバネの振動を記述する 2 階微分方程式の直感的イメージです:
解の形: と仮定すると特性方程式 が得られます——「 を代入したら指数の部分が消えて、 の方程式になる」:
例:()
(複素根)
解:(単振動!)——「バネが と の重ね合わせで振動する」のは、微分方程式が教えてくれる自然の設計です。
まとめ:解析(微分・積分・極限)シリーズの振り返り
| 回 | テーマ | 核心 |
|---|---|---|
| 1–2 | 極限・連続性 | 、不連続の種類 |
| 3–5 | 微分の定義・規則 | 差分商→導関数、積・商・合成 |
| 6–7 | 三角・指数・対数 | 、 |
| 8–10 | 増減・最適化・接線 | で増加、接線 |
| 11–12 | 不定積分・技法 | 、置換、部分積分 |
| 13–14 | 定積分・応用 | 基本定理、面積、体積 |
| 15 | 微分方程式 |
- 変数分離形: と を分けて両辺を積分——「仲間同士でまとめて積分する」
- 解の族: の値が変わるたびに別の曲線——「同じルールに従う無数の解が存在する」
- 初期条件で解が一本に絞られる——「出発点を決めたら軌跡が自動的に決まる」
- 微分方程式は自然界の「変化の法則」を記述する最も重要な道具——人口・放射性崩壊・バネ・電気回路・経済モデルすべてに登場する
微分と積分はコインの表裏——互いが互いの逆演算です。この「解析」の視点が、物理・工学・経済・データサイエンスへの扉を開きます。
これこそが微分積分学の核心です。おつかれさまでした!