Solve Differential Equation Calculator

First-Order Differential Equation Solver

This calculator uses the Runge-Kutta 4th Order (RK4) Method to solve initial value problems of the form:
dy/dx = f(x, y)

Use standard JS math: Math.sin(x), Math.exp(y), Math.pow(x,2), etc.

Result

y() ≈

Iteration Summary

Step x y (Numerical)

Understanding Differential Equation Solutions

Differential equations are the backbone of physics, engineering, and economics. They describe the relationship between a function and its derivatives, essentially modeling how systems change over time or space.

What is an Initial Value Problem (IVP)?

An initial value problem is a differential equation combined with a specified value of the unknown function at a given point in its domain. This calculator focuses on First-Order Ordinary Differential Equations (ODEs) defined as:

dy/dx = f(x, y), with y(x₀) = y₀

The Runge-Kutta (RK4) Method

While some differential equations can be solved analytically (finding an exact formula), many real-world equations require numerical approximation. The RK4 Method is one of the most popular and accurate numerical techniques. It calculates the slope at four different points within each step to minimize error, providing a much higher precision than the simpler Euler's Method.

The RK4 Formulas:

  • k1 = h * f(x_n, y_n)
  • k2 = h * f(x_n + h/2, y_n + k1/2)
  • k3 = h * f(x_n + h/2, y_n + k2/2)
  • k4 = h * f(x_n + h, y_n + k3)
  • y_{n+1} = y_n + (k1 + 2k2 + 2k3 + k4) / 6

Example Calculation

Suppose you want to solve the differential equation dy/dx = x + y with the initial condition y(0) = 1 and find the value of y at x = 1.

  1. f(x, y): x + y
  2. Initial x: 0
  3. Initial y: 1
  4. Target x: 1

By entering these values and clicking calculate, the tool iterates through the steps (typically 100 steps for high accuracy) to find that y(1) ≈ 3.4365.

Mathematical Syntax Guide

When entering your function, use standard JavaScript notation:

Operation Syntax
Addition / Subtraction x + y, x – y
Multiplication / Division x * y, x / y
Exponents Math.pow(x, 2) or x**2
Natural Log / Sine Math.log(x), Math.sin(x)
function calculateODE() { var funcStr = document.getElementById("ode-function").value; var x0 = parseFloat(document.getElementById("ode-x0").value); var y0 = parseFloat(document.getElementById("ode-y0").value); var xn = parseFloat(document.getElementById("ode-xn").value); var steps = parseInt(document.getElementById("ode-steps").value); var errorDiv = document.getElementById("ode-error"); var resultArea = document.getElementById("ode-result-area"); var tableBody = document.getElementById("ode-table-body"); errorDiv.style.display = "none"; resultArea.style.display = "none"; tableBody.innerHTML = ""; // Validation if (isNaN(x0) || isNaN(y0) || isNaN(xn) || isNaN(steps) || steps <= 0) { showError("Please enter valid numeric values. Steps must be greater than zero."); return; } if (x0 === xn) { showError("Target x must be different from Initial x."); return; } // Function evaluator var f = function(x, y) { try { // Replace common math expressions with JS Math equivalents for convenience if user didn't use Math. var processedStr = funcStr .replace(/sin\(/g, "Math.sin(") .replace(/cos\(/g, "Math.cos(") .replace(/exp\(/g, "Math.exp(") .replace(/pow\(/g, "Math.pow(") .replace(/log\(/g, "Math.log(") .replace(/sqrt\(/g, "Math.sqrt(") .replace(/PI/g, "Math.PI"); return Function('x', 'y', 'return ' + processedStr)(x, y); } catch (e) { throw new Error("Invalid function syntax."); } }; try { var h = (xn – x0) / steps; var currentX = x0; var currentY = y0; var displayInterval = Math.max(1, Math.floor(steps / 10)); // Show ~10 steps in table // Add Initial step addTableRow(0, currentX, currentY); for (var i = 1; i <= steps; i++) { var k1 = h * f(currentX, currentY); var k2 = h * f(currentX + h/2, currentY + k1/2); var k3 = h * f(currentX + h/2, currentY + k2/2); var k4 = h * f(currentX + h, currentY + k3); currentY = currentY + (k1 + 2*k2 + 2*k3 + k4) / 6; currentX = x0 + i * h; // Better precision than currentX += h if (i % displayInterval === 0 || i === steps) { addTableRow(i, currentX, currentY); } if (isNaN(currentY) || !isFinite(currentY)) { showError("The solution diverged. Try reducing step size or checking the equation."); return; } } document.getElementById("res-target-x").innerText = xn; document.getElementById("res-final-y").innerText = currentY.toFixed(6); resultArea.style.display = "block"; } catch (e) { showError("Error in calculation: " + e.message); } } function addTableRow(step, x, y) { var tableBody = document.getElementById("ode-table-body"); var row = tableBody.insertRow(); var cell1 = row.insertCell(0); var cell2 = row.insertCell(1); var cell3 = row.insertCell(2); cell1.style.padding = "8px"; cell1.style.borderBottom = "1px solid #eee"; cell1.innerText = step; cell2.style.padding = "8px"; cell2.style.borderBottom = "1px solid #eee"; cell2.innerText = x.toFixed(4); cell3.style.padding = "8px"; cell3.style.borderBottom = "1px solid #eee"; cell3.innerText = y.toFixed(6); } function showError(msg) { var errorDiv = document.getElementById("ode-error"); errorDiv.innerText = msg; errorDiv.style.display = "block"; }

Leave a Comment