import math
import numpy as np
# =========================================================
# فصل 2 : حل معادلات غیرخطی
# =========================================================
def bisection(f, a, b, tol=1e-10, max_iter=100):
"""
روش دوبخشی برای یافتن ریشه f(x)=0 در بازه [a, b]
شرط لازم: f(a)*f(b) < 0
"""
fa = f(a)
fb = f(b)
if fa * fb > 0:
raise ValueError("شرط تغییر علامت در بازه برقرار نیست.")
results = []
for i in range(1, max_iter + 1):
c = (a + b) / 2
fc = f(c)
results.append({
"iter": i,
"a": a,
"b": b,
"c": c,
"f(c)": fc,
"error": abs(b - a) / 2
})
if abs(fc) < tol or abs(b - a) / 2 < tol:
return c, results
if fa * fc < 0:
b = c
fb = fc
else:
a = c
fa = fc
return c, results
def false_position(f, a, b, tol=1e-10, max_iter=100):
"""
روش نابجایی / رگولا فالسی
"""
fa = f(a)
fb = f(b)
if fa * fb > 0:
raise ValueError("شرط تغییر علامت در بازه برقرار نیست.")
results = []
for i in range(1, max_iter + 1):
c = (a * fb - b * fa) / (fb - fa)
fc = f(c)
results.append({
"iter": i,
"a": a,
"b": b,
"c": c,
"f(c)": fc,
"error": abs(fc)
})
if abs(fc) < tol:
return c, results
if fa * fc < 0:
b = c
fb = fc
else:
a = c
fa = fc
return c, results
def fixed_point(g, x0, tol=1e-10, max_iter=100):
"""
روش تکرار نقطه ثابت: x_{n+1} = g(x_n)
"""
results = []
x_old = x0
for i in range(1, max_iter + 1):
x_new = g(x_old)
err = abs(x_new - x_old)
results.append({
"iter": i,
"x_old": x_old,
"x_new": x_new,
"error": err
})
if err < tol:
return x_new, results
x_old = x_new
return x_new, results
def newton_raphson(f, df, x0, tol=1e-10, max_iter=100):
"""
روش نیوتون-رافسون
x_{n+1} = x_n - f(x_n)/f'(x_n)
"""
results = []
x = x0
for i in range(1, max_iter + 1):
fx = f(x)
dfx = df(x)
if abs(dfx) < 1e-15:
raise ZeroDivisionError("مشتق در نقطه بسیار کوچک یا صفر است.")
x_new = x - fx / dfx
err = abs(x_new - x)
results.append({
"iter": i,
"x": x,
"f(x)": fx,
"df(x)": dfx,
"x_new": x_new,
"error": err
})
if err < tol or abs(fx) < tol:
return x_new, results
x = x_new
return x, results
def secant(f, x0, x1, tol=1e-10, max_iter=100):
"""
روش وتری (Secant)
"""
results = []
for i in range(1, max_iter + 1):
f0 = f(x0)
f1 = f(x1)
if abs(f1 - f0) < 1e-15:
raise ZeroDivisionError("اختلاف مقادیر تابع بسیار کوچک است.")
x2 = x1 - f1 * (x1 - x0) / (f1 - f0)
err = abs(x2 - x1)
results.append({
"iter": i,
"x0": x0,
"x1": x1,
"x2": x2,
"f(x2)": f(x2),
"error": err
})
if err < tol or abs(f(x2)) < tol:
return x2, results
x0, x1 = x1, x2
return x2, results
# =========================================================
# فصل 3 : درونیابی
# =========================================================
def lagrange_interpolation(x_points, y_points, x):
"""
محاسبه مقدار درونیابی لاگرانژ در x
"""
n = len(x_points)
result = 0.0
for i in range(n):
term = y_points[i]
for j in range(n):
if i != j:
term *= (x - x_points[j]) / (x_points[i] - x_points[j])
result += term
return result
def lagrange_polynomial_string(x_points, y_points):
"""
نمایش تقریبی چندجملهای لاگرانژ به صورت رشته
"""
n = len(x_points)
terms = []
for i in range(n):
numerator_parts = []
denom = 1
for j in range(n):
if i != j:
numerator_parts.append(f"(x - {x_points[j]})")
denom *= (x_points[i] - x_points[j])
term_str = f"{y_points[i]/denom:.6f}*" + "*".join(numerator_parts)
terms.append(term_str)
return " + ".join(terms)
def divided_differences(x_points, y_points):
"""
جدول تفاضلات تقسیمشده نیوتون
"""
n = len(x_points)
table = np.zeros((n, n))
table[:, 0] = y_points
for j in range(1, n):
for i in range(n - j):
table[i, j] = (table[i + 1, j - 1] - table[i, j - 1]) / (x_points[i + j] - x_points[i])
return table
def newton_interpolation(x_points, y_points, x):
"""
درونیابی نیوتون با تفاضلات تقسیمشده
"""
n = len(x_points)
table = divided_differences(x_points, y_points)
result = table[0, 0]
product = 1.0
for i in range(1, n):
product *= (x - x_points[i - 1])
result += table[0, i] * product
return result, table
def newton_forward_difference_table(y):
"""
جدول تفاضلات پیشرو
"""
n = len(y)
table = np.zeros((n, n))
table[:, 0] = y
for j in range(1, n):
for i in range(n - j):
table[i, j] = table[i + 1, j - 1] - table[i, j - 1]
return table
def factorial(n):
return math.factorial(n)
def newton_forward(x_points, y_points, x):
"""
درونیابی نیوتون پیشرو
شرط: نقاط با فاصله مساوی باشند
"""
n = len(x_points)
h = x_points[1] - x_points[0]
for i in range(1, n - 1):
if abs((x_points[i + 1] - x_points[i]) - h) > 1e-12:
raise ValueError("فاصله نقاط مساوی نیست.")
table = newton_forward_difference_table(y_points)
p = (x - x_points[0]) / h
result = y_points[0]
p_term = 1.0
for i in range(1, n):
p_term *= (p - (i - 1))
result += (p_term * table[0, i]) / factorial(i)
return result, table
def newton_backward_difference_table(y):
"""
جدول تفاضلات پسرو
"""
n = len(y)
table = np.zeros((n, n))
table[:, 0] = y
for j in range(1, n):
for i in range(n - 1, j - 1, -1):
table[i, j] = table[i, j - 1] - table[i - 1, j - 1]
return table
def newton_backward(x_points, y_points, x):
"""
درونیابی نیوتون پسرو
شرط: نقاط با فاصله مساوی باشند
"""
n = len(x_points)
h = x_points[1] - x_points[0]
for i in range(1, n - 1):
if abs((x_points[i + 1] - x_points[i]) - h) > 1e-12:
raise ValueError("فاصله نقاط مساوی نیست.")
table = newton_backward_difference_table(y_points)
p = (x - x_points[-1]) / h
result = y_points[-1]
p_term = 1.0
for i in range(1, n):
p_term *= (p + (i - 1))
result += (p_term * table[-1, i]) / factorial(i)
return result, table
def inverse_interpolation(x_points, y_points, y_target):
"""
درونیابی معکوس:
با جابجایی نقش x و y، مقدار x متناظر با y_target را تقریب میزند
"""
return lagrange_interpolation(y_points, x_points, y_target)
# =========================================================
# چندجملهایهای چبیشف
# =========================================================
def chebyshev_polynomial(n, x):
"""
محاسبه T_n(x) به روش بازگشتی
"""
if n == 0:
return 1
elif n == 1:
return x
T0, T1 = 1, x
for _ in range(2, n + 1):
T0, T1 = T1, 2 * x * T1 - T0
return T1
def chebyshev_nodes(a, b, n):
"""
تولید n گره چبیشف در بازه [a, b]
"""
nodes = []
for k in range(1, n + 1):
xk = 0.5 * (a + b) + 0.5 * (b - a) * math.cos((2 * k - 1) * math.pi / (2 * n))
nodes.append(xk)
return sorted(nodes)
# =========================================================
# درونیابی تکهای
# =========================================================
def piecewise_linear_interpolation(x_points, y_points, x):
"""
درونیابی خطی تکهای
"""
n = len(x_points)
if x < x_points[0] or x > x_points[-1]:
raise ValueError("x خارج از بازه دادههاست.")
for i in range(n - 1):
if x_points[i] <= x <= x_points[i + 1]:
x0, x1 = x_points[i], x_points[i + 1]
y0, y1 = y_points[i], y_points[i + 1]
return y0 + (y1 - y0) * (x - x0) / (x1 - x0)
return y_points[-1]
def piecewise_quadratic_interpolation(x_points, y_points, x):
"""
درونیابی سهمی تکهای
برای هر بازه از 3 نقطه نزدیک استفاده میشود
"""
n = len(x_points)
if n < 3:
raise ValueError("برای درونیابی سهمی حداقل 3 نقطه لازم است.")
if x < x_points[0] or x > x_points[-1]:
raise ValueError("x خارج از بازه دادههاست.")
for i in range(n - 1):
if x_points[i] <= x <= x_points[i + 1]:
if i == 0:
indices = [0, 1, 2]
elif i == n - 2:
indices = [n - 3, n - 2, n - 1]
else:
indices = [i - 1, i, i + 1]
xp = [x_points[j] for j in indices]
yp = [y_points[j] for j in indices]
return lagrange_interpolation(xp, yp, x)
return y_points[-1]
def cubic_spline_coefficients(x, y):
"""
محاسبه ضرایب اسپلاین مکعبی طبیعی
"""
n = len(x)
a = np.array(y, dtype=float)
h = np.diff(x)
alpha = np.zeros(n)
for i in range(1, n - 1):
alpha[i] = (3 / h[i]) * (a[i + 1] - a[i]) - (3 / h[i - 1]) * (a[i] - a[i - 1])
l = np.ones(n)
mu = np.zeros(n)
z = np.zeros(n)
for i in range(1, n - 1):
l[i] = 2 * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1]
mu[i] = h[i] / l[i]
z[i] = (alpha[i] - h[i - 1] * z[i - 1]) / l[i]
c = np.zeros(n)
b = np.zeros(n - 1)
d = np.zeros(n - 1)
for j in range(n - 2, -1, -1):
c[j] = z[j] - mu[j] * c[j + 1] if j < n - 1 else 0
if j < n - 1:
b[j] = (a[j + 1] - a[j]) / h[j] - h[j] * (c[j + 1] + 2 * c[j]) / 3
d[j] = (c[j + 1] - c[j]) / (3 * h[j])
return a[:-1], b, c[:-1], d
def cubic_spline_interpolation(x_points, y_points, x):
"""
درونیابی با اسپلاین مکعبی طبیعی
"""
if x < x_points[0] or x > x_points[-1]:
raise ValueError("x خارج از بازه دادههاست.")
a, b, c, d = cubic_spline_coefficients(x_points, y_points)
for i in range(len(x_points) - 1):
if x_points[i] <= x <= x_points[i + 1]:
dx = x - x_points[i]
return a[i] + b[i] * dx + c[i] * dx**2 + d[i] * dx**3
return y_points[-1]
# =========================================================
# فصل 4 : انتگرالگیری رامبرگ
# =========================================================
def trapezoidal_rule(f, a, b, n):
"""
قاعده ذوزنقه مرکب
"""
h = (b - a) / n
s = 0.5 * (f(a) + f(b))
for i in range(1, n):
s += f(a + i * h)
return h * s
def romberg_integration(f, a, b, max_level=5, tol=1e-10):
"""
انتگرالگیری رامبرگ
"""
R = np.zeros((max_level, max_level), dtype=float)
for i in range(max_level):
n = 2**i
R[i, 0] = trapezoidal_rule(f, a, b, n)
for j in range(1, i + 1):
R[i, j] = R[i, j - 1] + (R[i, j - 1] - R[i - 1, j - 1]) / (4**j - 1)
if i > 0 and abs(R[i, i] - R[i - 1, i - 1]) < tol:
return R[i, i], R[:i+1, :i+1]
return R[max_level - 1, max_level - 1], R
# =========================================================
# توابع کمکی برای نمایش نتایج
# =========================================================
def print_iteration_table(results, max_rows=10):
"""
چاپ بخشی از جدول تکرارها
"""
if not results:
print("نتیجهای برای نمایش وجود ندارد.")
return
keys = list(results[0].keys())
print("-" * 100)
print(" | ".join(f"{k:^15}" for k in keys))
print("-" * 100)
for row in results[:max_rows]:
print(" | ".join(f"{str(round(v, 10)) if isinstance(v, float) else str(v):^15}" for v in row.values()))
if len(results) > max_rows:
print("...")
print("-" * 100)
# =========================================================
# مثالهای تست
# =========================================================
if name == "__main__":
# -------------------------------
# فصل 2 : حل معادلات غیرخطی
# -------------------------------
f = lambda x: x**3 - x - 2
df = lambda x: 3*x**2 - 1
g = lambda x: (x + 2)**(1/3)
print("\n===== روش دوبخشی =====")
root, res = bisection(f, 1, 2)
print("ریشه تقریبی:", root)
print_iteration_table(res)
print("\n===== روش نابجایی =====")
root, res = false_position(f, 1, 2)
print("ریشه تقریبی:", root)
print_iteration_table(res)
print("\n===== روش نقطه ثابت =====")
root, res = fixed_point(g, 1.5)
print("ریشه تقریبی:", root)
print_iteration_table(res)
print("\n===== روش نیوتون-رافسون =====")
root, res = newton_raphson(f, df, 1.5)
print("ریشه تقریبی:", root)
print_iteration_table(res)
print("\n===== روش وتری =====")
root, res = secant(f, 1, 2)
print("ریشه تقریبی:", root)
print_iteration_table(res)
# -------------------------------
# فصل 3 : درونیابی
# -------------------------------
x_data = [1, 2, 3, 4]
y_data = [1, 4, 9, 16]
x_val = 2.5
print("\n===== لاگرانژ =====")
y_interp = lagrange_interpolation(x_data, y_data, x_val)
print(f"f({x_val}) ≈ {y_interp}")
print("\n===== نیوتون تقسیمشده =====")
y_interp, table = newton_interpolation(x_data, y_data, x_val)
print(f"f({x_val}) ≈ {y_interp}")
print("جدول تفاضلات تقسیمشده:")
print(table)
x_eq = [0, 1, 2, 3]
y_eq = [1, 2, 4, 8]
print("\n===== نیوتون پیشرو =====")
y_interp, table = newton_forward(x_eq, y_eq, 1.5)
print("مقدار تقریبی:", y_interp)
print(table)
print("\n===== نیوتون پسرو =====")
y_interp, table = newton_backward(x_eq, y_eq, 2.5)
print("مقدار تقریبی:", y_interp)
print(table)
print("\n===== درونیابی معکوس =====")
x_inv = inverse_interpolation(x_data, y_data, 6.25)
print("x تقریبی برای y=6.25 :", x_inv)
print("\n===== چندجملهای چبیشف =====")
print("T_4(0.5) =", chebyshev_polynomial(4, 0.5))
print("گرههای چبیشف در [0,1] برای n=5:")
print(chebyshev_nodes(0, 1, 5))
print("\n===== درونیابی تکهای خطی =====")
print(piecewise_linear_interpolation(x_data, y_data, 2.5))
print("\n===== درونیابی تکهای سهمی =====")
print(piecewise_quadratic_interpolation(x_data, y_data, 2.5))
print("\n===== اسپلاین مکعبی =====")
print(cubic_spline_interpolation(x_data, y_data, 2.5))
# -------------------------------
# فصل 4 : انتگرالگیری رامبرگ
# -------------------------------
f_int = lambda x: math.sin(x)
integral, table = romberg_integration(f_int, 0, math.pi, max_level=6)
print("\n===== انتگرالگیری رامبرگ =====")
print("مقدار تقریبی انتگرال:", integral)
print("جدول رامبرگ:")
print(table)
To embed this project on your website, copy the following code and paste it into your website's HTML: