جمع الشرائح الرفيعة
تقيس التكاملات المساحة تحت منحنى: اجمع قيمة f على خطوات صغيرة كثيرة. وفي المالية تظهر التكاملات متنكرة في كل مكان: الربح التراكمي لمركز عبر الزمن، والقيمة الحالية لتدفق نقدي مستمر، والعائد المتوقع كمتوسط للعائد موزونًا بكثافة احتمال، أو إجمالي تعرّض محفظة خلال فترة. وقليلة هي الدوال الحقيقية ذات الصيغة المرتبة، فنقرّب المساحة بشرائح. قسّم الفترة [a, b] إلى n شريحة متساوية عرضها h = (b - a) / n واجمع مساحاتها.
# Area under x^2 on [0, 1] is exactly 1/3. Left rectangles, n slices:
def left_riemann(f, a, b, n):
h = (b - a) / n
return sum(f(a + i * h) for i in range(n)) * h
square = lambda x: x * x
for n in (10, 100, 1000):
print(n, round(left_riemann(square, 0, 1, n), 6))
# 10 0.285
# 100 0.32835
# 1000 0.332834شرائح أفضل: شبه المنحرف وسيمبسون
المستطيلات اليسرى فجّة: تتظاهر كل شريحة بأن المنحنى مسطح. أما قاعدة شبه المنحرف فتصل طرفي كل شريحة بخط مستقيم، فتكون مساحة الشريحة h * (f(يسار) + f(يمين)) / 2؛ وعند جمعها تُحسب النقاط الداخلية مرتين وطرفا الفترة مرة: h * (f(a) / 2 + f(a + h) + ... + f(b - h) + f(b) / 2). وهي دقيقة للخطوط المستقيمة. وتُلائم قاعدة سيمبسون قطعًا مكافئًا عبر كل ثلاث نقاط: h / 3 * (f(a) + 4 * f(النقاط الفردية) + 2 * f(النقاط الداخلية الزوجية) + f(b))، وتتطلب n زوجيًا، وهي دقيقة للتكعيبيات. وللدوال الملساء تكون سيمبسون غالبًا أدق بكثير لقاء الجهد نفسه.
def trapezoid(f, a, b, n):
h = (b - a) / n
return h * (f(a) / 2 + sum(f(a + i * h) for i in range(1, n)) + f(b) / 2)
def simpson(f, a, b, n):
if n % 2:
raise ValueError("n must be even")
h = (b - a) / n
odd = sum(f(a + i * h) for i in range(1, n, 2))
even = sum(f(a + i * h) for i in range(2, n, 2))
return h / 3 * (f(a) + 4 * odd + 2 * even + f(b))
square = lambda x: x * x
for n in (10, 100, 1000):
print(n, round(trapezoid(square, 0, 1, n), 6), round(simpson(square, 0, 1, n), 6))
# 10 0.335 0.333333
# 100 0.33335 0.333333
# 1000 0.333334 0.333333
print(simpson(lambda x: x**3, 0, 2, 4)) # 4.0 (exact for cubics)تكامل بيانات لديك بالفعل
كثيرًا ما لا توجد دالة، بل قياسات عند أوقات منتظمة: قائمة تعرضات تؤخذ كل يوم. وتعمل قاعدة شبه المنحرف مباشرة على هذه العيّنات. فبقيم ys تفصل بينها dt يشكّل كل زوج متجاور شبه منحرف مساحته dt * (ys[i] + ys[i + 1]) / 2، ويقرّب المجموع المساحة تحت المنحنى المأخوذ بالعيّنات، مثل إجمالي أيام التعرض. ومع أقل من عيّنتين لا توجد فترة، فتكون المساحة 0.0.
def trapezoid_samples(ys, dt):
if len(ys) < 2:
return 0.0
return dt * (ys[0] / 2 + sum(ys[1:-1]) + ys[-1] / 2)
# Exposure sampled daily: 0, 2, 4, 2, 0 million
exposure = [0, 2, 4, 2, 0]
print(trapezoid_samples(exposure, 1.0)) # 8.0 exposure-days
print(trapezoid_samples([5.0], 1.0)) # 0.0import math
# An expected value is an integral: E[X^2] for a standard normal is 1
def density(x):
return math.exp(-x * x / 2) / math.sqrt(2 * math.pi)
def simpson(f, a, b, n):
h = (b - a) / n
odd = sum(f(a + i * h) for i in range(1, n, 2))
even = sum(f(a + i * h) for i in range(2, n, 2))
return h / 3 * (f(a) + 4 * odd + 2 * even + f(b))
second_moment = simpson(lambda x: x * x * density(x), -8, 8, 400)
print(round(second_moment, 6)) # 1.0
# Probability that X is within one standard deviation: about 68%
print(round(simpson(density, -1, 1, 100), 4)) # 0.6827x**2 أو sin من 0 إلى pi) وراقب هبوط الخطأ مع ازدياد n. والمستطيلات اليسرى دقيقة للثوابت فقط، وشبه المنحرف للخطوط المستقيمة، وسيمبسون للتكعيبيات؛ فإن لم تكن قاعدة دقيقة حيث ينبغي ففيها خطأ برمجي. وتستخدم اختبارات المختبر فحوص الدقة هذه بالضبط.- شرائح عرضها
h = (b - a) / n؛ والمستطيلات اليسرىh * sum(f(a + i*h))لـi < n. - شبه المنحرف: الطرفان يُحسبان نصفًا؛ وسيمبسون: الأوزان 1 و4 و2 و4 ... 4 و1 في
h / 3وnزوجي. - للبيانات المأخوذة بالعيّنات استخدم
dt * (الأول / 2 + القيم الوسطى + الأخير / 2)؛ واختبر على تكاملات معروفة.
التالي: المتجهات والجداء النقطي، اللبنة الأساسية لعوائد المحافظ والارتباطات ولاحقًا NumPy.
المختبر: ما الذي يُقيَّم
- قرّب مساحة بمستطيلات باستخدام
left_riemann25 نقطة - تحسّن باستخدام شبه المنحرف عبر
trapezoid25 نقطة - لائِم قطوعًا مكافئة باستخدام
simpson25 نقطة - كامِل بيانات مقيسة باستخدام
trapezoid_samples25 نقطة