合成関数と逆関数
合成関数
「コーヒーを作るには、まずお湯を沸かして(関数 )、それからコーヒー粉を入れて抽出する(関数 )」——2つの操作を順番に組み合わせる、これが合成関数のイメージです。
2つの関数 、 があるとき、 の値を に代入した新しい関数
を と の合成関数といいます。
注意
- 一般に (順序が重要)——「お湯を沸かしてからコーヒーを入れる」と「コーヒーを入れてからお湯を沸かす」は違う結果になります
- の値域が の定義域に含まれている必要がある
例
、 のとき:
なので、——順序を逆にすると全然違う関数になります。
逆関数
「ある操作を元に戻す操作」——逆関数とはそういうものです。「2倍にする」関数の逆は「半分にする」関数。「3を足す」関数の逆は「3を引く」関数です。
関数 において、 と を入れ替えた関数が存在するとき、それを逆関数 といいます。
逆関数の求め方
- を について解く
- と を入れ替える( → )
「 をいじって を求めてから、ラベルを入れ替える」——この2ステップだけです。
例
の逆関数を求めよ。
→ → 入れ替えて:
確認:(元に戻る)
逆関数の存在条件
関数 が逆関数を持つためには、 が単射(1対1対応)である必要があります。
つまり、 が成り立つ必要があります——「違う入力からは、必ず違う出力が出る」ということです。
「同じ結果が出る入力が複数あると、逆向きに戻せない」——たとえば に を入れると か の2つが出てきて、「どちらに戻せばいいか」がわかりません。
は 全体では単射でないため逆関数を持ちませんが、 に制限すると単射になり、逆関数 が存在します。
インタラクティブデモ:関数と逆関数の対称性
()(青)と逆関数 (オレンジ)は、直線 (緑の点線)に関して対称です。マウスを左右に動かすと、対応する点ペアが強調されます——青い点と橙色の点がちょうど の線に対して鏡対称になっているのを確認してください。
function loop() {
ctx.clearRect(0, 0, W, H);
var ox = W / 2 - 100, oy = H / 2 + 100;
var scale = 45;
var xVal = (mx / W) * 5;
xVal = Math.max(0, Math.min(5, xVal));
function toScreen(x, y) {
return { sx: ox + x * scale, sy: oy - y * scale };
}
// Grid
ctx.strokeStyle = 'rgba(255,255,255,0.06)';
ctx.lineWidth = 1;
for (var gi = 0; gi <= 6; gi++) {
var gs = toScreen(gi, 0);
ctx.beginPath(); ctx.moveTo(gs.sx, 0); ctx.lineTo(gs.sx, H); ctx.stroke();
var gs2 = toScreen(0, gi);
ctx.beginPath(); ctx.moveTo(0, gs2.sy); ctx.lineTo(W, gs2.sy); ctx.stroke();
}
// Axes
ctx.strokeStyle = 'rgba(255,255,255,0.3)';
ctx.lineWidth = 1.5;
ctx.beginPath(); ctx.moveTo(0, oy); ctx.lineTo(W, oy); ctx.stroke();
ctx.beginPath(); ctx.moveTo(ox, 0); ctx.lineTo(ox, H); ctx.stroke();
// Axis labels
ctx.fillStyle = 'rgba(255,255,255,0.4)';
ctx.font = '12px sans-serif';
for (var lx = 1; lx <= 5; lx++) {
var ls = toScreen(lx, 0);
ctx.fillText(lx, ls.sx - 4, oy + 16);
}
for (var ly = 1; ly <= 5; ly++) {
var ls2 = toScreen(0, ly);
ctx.fillText(ly, ox + 6, ls2.sy + 4);
}
// y=x line (green dashed)
ctx.strokeStyle = 'rgba(102,187,106,0.45)';
ctx.lineWidth = 1.5;
ctx.setLineDash([6,4]);
ctx.beginPath();
var sA = toScreen(0, 0), sB = toScreen(5.5, 5.5);
ctx.moveTo(sA.sx, sA.sy); ctx.lineTo(sB.sx, sB.sy); ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = 'rgba(102,187,106,0.7)';
ctx.font = '13px sans-serif';
ctx.fillText('y = x', toScreen(4.6, 4.9).sx, toScreen(4.6, 4.9).sy);
// y=x^2 (x>=0) - blue
ctx.strokeStyle = '#4fc3f7';
ctx.lineWidth = 2.5;
ctx.beginPath();
var st1 = false;
for (var xi = 0; xi <= 5.5; xi += 0.03) {
var yi = xi * xi;
if (yi > 6) { st1 = false; continue; }
var s = toScreen(xi, yi);
if (!st1) { ctx.moveTo(s.sx, s.sy); st1 = true; } else ctx.lineTo(s.sx, s.sy);
}
ctx.stroke();
ctx.fillStyle = '#4fc3f7';
ctx.font = 'bold 13px sans-serif';
ctx.fillText('y = x² (x≥0)', toScreen(1.5, 5.5).sx, toScreen(1.5, 5.5).sy);
// y=sqrt(x) - orange
ctx.strokeStyle = '#ffb74d';
ctx.lineWidth = 2.5;
ctx.beginPath();
var st2 = false;
for (var xi2 = 0; xi2 <= 5.5; xi2 += 0.03) {
var yi2 = Math.sqrt(xi2);
var s2 = toScreen(xi2, yi2);
if (!st2) { ctx.moveTo(s2.sx, s2.sy); st2 = true; } else ctx.lineTo(s2.sx, s2.sy);
}
ctx.stroke();
ctx.fillStyle = '#ffb74d';
ctx.fillText('y = √x', toScreen(5.0, 2.4).sx, toScreen(5.0, 2.4).sy);
// Symmetric pair
var yOnF = xVal * xVal;
var yOnInv = Math.sqrt(xVal);
if (yOnF <= 6) {
var pF = toScreen(xVal, yOnF);
var pMirrorF = toScreen(yOnF, xVal);
ctx.strokeStyle = 'rgba(255,235,59,0.5)';
ctx.lineWidth = 1.5;
ctx.setLineDash([3,3]);
ctx.beginPath(); ctx.moveTo(pF.sx, pF.sy); ctx.lineTo(pMirrorF.sx, pMirrorF.sy); ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = '#4fc3f7';
ctx.beginPath(); ctx.arc(pF.sx, pF.sy, 6, 0, Math.PI*2); ctx.fill();
ctx.fillStyle = '#ffb74d';
ctx.beginPath(); ctx.arc(pMirrorF.sx, pMirrorF.sy, 6, 0, Math.PI*2); ctx.fill();
}
var pInv = toScreen(xVal, yOnInv);
var pMirrorInv = toScreen(yOnInv, xVal);
ctx.strokeStyle = 'rgba(255,235,59,0.3)';
ctx.lineWidth = 1.5;
ctx.setLineDash([3,3]);
ctx.beginPath(); ctx.moveTo(pInv.sx, pInv.sy); ctx.lineTo(pMirrorInv.sx, pMirrorInv.sy); ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = '#ffb74d';
ctx.beginPath(); ctx.arc(pInv.sx, pInv.sy, 6, 0, Math.PI*2); ctx.fill();
// Info panel
ctx.fillStyle = 'rgba(0,0,0,0.65)';
ctx.beginPath(); ctx.roundRect(10, 10, 230, 70, 8); ctx.fill();
ctx.fillStyle = '#ffeb3b';
ctx.font = 'bold 13px monospace';
ctx.fillText('x = ' + xVal.toFixed(2), 18, 32);
ctx.fillStyle = '#4fc3f7';
ctx.font = '13px monospace';
ctx.fillText('f(x) = x² = ' + (xVal*xVal).toFixed(2), 18, 52);
ctx.fillStyle = '#ffb74d';
ctx.fillText('f⁻¹(x) = √x = ' + yOnInv.toFixed(3), 18, 70);
requestAnimationFrame(loop);
}
loop(); 合成関数と逆関数の関係
「操作して、戻す」——これを繰り返すと元に戻ります。逆関数の定義から、次が成り立ちます:
これは恒等関数()になります——「何もしない関数」です。「前進して後退すれば元の場所に戻る」のと同じ論理です。
グラフ上の対称性
関数 と逆関数 のグラフは、直線 に関して対称です。
理由: の点 は では に対応します。 と は に関して対称——「 座標と 座標が入れ替わる」という逆関数の定義が、そのままグラフの対称性として現れます。
練習問題
- の逆関数 を求めよ。
- ()の逆関数を求めよ。
- ()と の合成関数 を求めよ。
解答
- → →
- → → → ()
まとめ
- 合成関数:、順序に注意——「逆順は別の関数」
- 逆関数: は と を入れ替えて解く——「操作を逆向きにする」
- 逆関数の存在条件: が単射(1対1)であること——「同じ結果が出る入力が二つあったら逆には戻れない」
- と は に関して対称
次回は分数関数と無理関数を学びます。「」の双曲線と「」の半放物線——どちらも日常の現象を記述する重要なグラフです。