Considere o seguinte problema linear no intervalo $[a,b]$:
Se $p, q, r$ são contínuas em $[a,b]$ (com hipóteses usuais adicionais garantindo unicidade), o PVF tem solução única.
Definem-se dois PVI:
Se $y_1$ e $y_2$ são soluções dos PVI, então a solução do PVF é
Selecione um exemplo para visualizar resultados e gráficos:
| $x_k$ | $y_k$ |
|---|
Entre com os dados do problema na forma \[ \begin{cases} y'' = p(x)y' + q(x)y + r(x), & x \in (a, b) \\ y(a) = \alpha, & y(b) = \beta. \end{cases} \]
| $x_k$ | $y_k$ |
|---|
// Avaliador simples de expressões em função de x (uso educativo)
function evaluateFunction(expr, x) {
const expression = String(expr).replace(/x/g, `(${x})`);
try { return (new Function('return ' + expression))(); }
catch (e) { console.error('Erro ao avaliar expressão:', expression, e); return 0; }
}
// Método do shooting linear com RK4
function shootingLinear(pExpr, qExpr, rExpr, a, b, alpha, beta, N) {
const u1 = new Array(N + 1).fill(0), u2 = new Array(N + 1).fill(0);
const v1 = new Array(N + 1).fill(0), v2 = new Array(N + 1).fill(0);
const y = new Array(N + 1).fill(0);
const h = (b - a) / N;
u1[0] = alpha; u2[0] = 0; // PVI-1
v1[0] = 0; v2[0] = 1; // PVI-2
for (let i = 1; i <= N; i++) {
const x = a + (i - 1) * h;
const p0 = evaluateFunction(pExpr, x), q0 = evaluateFunction(qExpr, x), r0 = evaluateFunction(rExpr, x);
const p1 = evaluateFunction(pExpr, x + h/2), q1 = evaluateFunction(qExpr, x + h/2), r1 = evaluateFunction(rExpr, x + h/2);
const p2 = p1, q2 = q1, r2 = r1;
const p3 = evaluateFunction(pExpr, x + h), q3 = evaluateFunction(qExpr, x + h), r3 = evaluateFunction(rExpr, x + h);
// RK4 para (u1,u2)
const k11 = h * u2[i-1];
const k12 = h * (p0 * u2[i-1] + q0 * u1[i-1] + r0);
const k21 = h * (u2[i-1] + 0.5 * k12);
const k22 = h * (p1 * (u2[i-1] + 0.5*k12) + q1 * (u1[i-1] + 0.5*k11) + r1);
const k31 = h * (u2[i-1] + 0.5 * k22);
const k32 = h * (p2 * (u2[i-1] + 0.5*k22) + q2 * (u1[i-1] + 0.5*k21) + r2);
const k41 = h * (u2[i-1] + k32);
const k42 = h * (p3 * (u2[i-1] + k32) + q3 * (u1[i-1] + k31) + r3);
u1[i] = u1[i-1] + (k11 + 2*k21 + 2*k31 + k41)/6;
u2[i] = u2[i-1] + (k12 + 2*k22 + 2*k32 + k42)/6;
// RK4 para (v1,v2)
const kp11 = h * v2[i-1];
const kp12 = h * (p0 * v2[i-1] + q0 * v1[i-1]);
const kp21 = h * (v2[i-1] + 0.5 * kp12);
const kp22 = h * (p1 * (v2[i-1] + 0.5*kp12) + q1 * (v1[i-1] + 0.5*kp11));
const kp31 = h * (v2[i-1] + 0.5 * kp22);
const kp32 = h * (p2 * (v2[i-1] + 0.5*kp22) + q2 * (v1[i-1] + 0.5*kp21));
const kp41 = h * (v2[i-1] + kp32);
const kp42 = h * (p3 * (v2[i-1] + kp32) + q3 * (v1[i-1] + kp31));
v1[i] = v1[i-1] + (kp11 + 2*kp21 + 2*kp31 + kp41)/6;
v2[i] = v2[i-1] + (kp12 + 2*kp22 + 2*kp32 + kp42)/6;
}
const denom = v1[N];
if (Math.abs(denom) < 1e-12) {
throw new Error('Falha no shooting: y2(b)=v1[N] ≈ 0. Ajuste condições/intervalo ou N.');
}
for (let k = 0; k <= N; k++) {
y[k] = u1[k] + ((beta - u1[N]) * v1[k]) / denom;
}
const xVals = Array.from({ length: N + 1 }, (_, i) => a + i * (b - a) / N);
return { solution: y, xValues: xVals, endpointResidual: y[N] - beta };
}