Bỏ qua

Tích phân

Tích phân tích lũy các đại lượng trên những khoảng, biến các tốc độ cục bộ trở lại thành tổng thể. Tài liệu này bao quát tích phân xác định và bất định, Định lý cơ bản của giải tích, các kỹ thuật tích phân, và những ứng dụng vào mật độ xác suất cùng kỳ vọng trong học máy.

  • Vi phân cho ta biết tốc độ thay đổi tại một điểm đơn lẻ. Tích phân đi theo chiều ngược lại: nó tích lũy nhiều mảnh nhỏ để tính một tổng.

  • Nếu đạo hàm trả lời "nhanh thế nào?", thì tích phân trả lời "bao nhiêu?"

  • Cách đơn giản nhất để hình dung tích phân là như diện tích dưới một đường cong. Nếu bạn vẽ một hàm \(f(x)\) và tô bóng vùng nằm giữa đường cong và trục x từ \(x = a\) đến \(x = b\), tích phân cho diện tích có dấu của vùng đó.

Tích phân tính diện tích dưới đường cong bằng cách cộng các hình chữ nhật mỏng

  • Tại sao lại là "có dấu"? Các vùng phía trên trục x đóng góp diện tích dương, các vùng phía dưới đóng góp diện tích âm. Điều này hợp lý về mặt vật lý: nếu \(f(x)\) biểu diễn vận tốc, tích phân cho độ dời ròng (tiến lùi trừ lùi), chứ không phải quãng đường tổng cộng.

  • Để tính diện tích này, hãy tưởng tượng cắt vùng đó thành \(n\) hình chữ nhật dọc mỏng, mỗi cái có độ rộng \(\Delta x\). Độ cao của mỗi hình chữ nhật là giá trị hàm tại một điểm nào đó trong khoanh đó. Cộng chúng lại:

\[\text{Area} \approx \sum_{i=1}^{n} f(x_i^\ast) \, \Delta x\]
  • Khi ta làm cho các hình chữ nhật mỏng dần (\(n \to \infty\), \(\Delta x \to 0\)), tổng trở nên chính xác. Quá trình giới hạn này định nghĩa tích phân xác định:
\[\int_a^b f(x)\, dx = \lim_{n \to \infty} \sum_{i=1}^{n} f(x_i^\ast) \, \Delta x\]
  • Ký hiệu \(\int\) là một chữ "S" kéo dài, viết tắt cho "sum" (tổng). Ký hiệu \(dx\) nhắc nhở ta rằng ta đang cộng các lát cắt mỏng vô hạn nhỏ dọc theo trục x.

  • Một tích phân bất định (hay nguyên hàm) là một hàm \(F(x)\) có đạo hàm là \(f(x)\). Ta viết:

\[\int f(x)\, dx = F(x) + C\]
  • Ký hiệu \(+ C\)hằng số tích phân. Vì đạo hàm của bất kỳ hằng số nào cũng bằng không, nên có vô số nguyên hàm chỉ khác nhau một hằng số. Ví dụ, \(\int 2x\, dx = x^2 + C\), bởi vì đạo hàm của \(x^2 + 7\) hay \(x^2 - 3\) đều vẫn là \(2x\).

  • Định lý cơ bản của giải tích là cây cầu nối kết vi phân và tích phân. Nó có hai phần:

  • Phần 1: Nếu \(F(x)\) là một nguyên hàm của \(f(x)\), thì tích phân xác định bằng hiệu của \(F\) tại hai đầu mút:

\[\int_a^b f(x)\, dx = F(b) - F(a)\]
  • Điều này thật sự rất thực dụng. Thay vì tính một giới hạn của các tổng (vốn khó), ta tìm một nguyên hàm và tính nó tại hai điểm (thường là dễ).

  • Phần 2: Nếu ta định nghĩa \(F(x) = \int_a^x f(t)\, dt\), thì \(F'(x) = f(x)\). Vi phân và tích phân là các phép toán ngược, chúng triệt tiêu lẫn nhau.

  • Ví dụ, để tính \(\int_1^3 x^2\, dx\): nguyên hàm của \(x^2\)\(\frac{x^3}{3}\). Vậy \(\int_1^3 x^2\, dx = \frac{27}{3} - \frac{1}{3} = \frac{26}{3} \approx 8.67\).

  • Cũng giống như vi phân có các quy tắc, tích phân có các quy tắc tương ứng đảo ngược chúng:

Function Integral Condition
\(x^n\) \(\frac{x^{n+1}}{n+1} + C\) \(n \neq -1\)
\(\frac{1}{x}\) $\ln x
\(e^x\) \(e^x + C\)
\(a^x\) \(\frac{a^x}{\ln a} + C\)
\(\sin x\) \(-\cos x + C\)
\(\cos x\) \(\sin x + C\)
\(k\) (constant) \(kx + C\)
  • Quy tắc tổng/hiệu được giữ nguyên: \(\int [f(x) \pm g(x)]\, dx = \int f(x)\, dx \pm \int g(x)\, dx\). Các hằng số có thể đưa ra ngoài: \(\int k\, f(x)\, dx = k \int f(x)\, dx\).

  • Khi một hàm quá phức tạp để tích phân trực tiếp, ta có các kỹ thuật để đơn giản hóa nó.

  • Thế u (u-substitution) là phép đảo của quy tắc dẫn hàm hàm hợp. Nếu bạn thấy một hàm hợp \(f(g(x))\) nhân với \(g'(x)\), hãy thế \(u = g(x)\) sao cho \(du = g'(x)\, dx\), và tích phân sẽ được đơn giản hóa.

  • Ví dụ: \(\int 2x \cos(x^2)\, dx\). Đặt \(u = x^2\), nên \(du = 2x\, dx\). Tích phân trở thành \(\int \cos(u)\, du = \sin(u) + C = \sin(x^2) + C\).

  • Tích phân từng phần (integration by parts) là phép đảo của quy tắc tích. Nếu hàm bị tích phân là tích của hai hàm:

\[\int u\, dv = uv - \int v\, du\]
  • Chọn \(u\)\(dv\) một cách chiến lược sao cho tích phân còn lại \(\int v\, du\) đơn giản hơn cái ban đầu. Một mẹo ghi nhớ phổ biến để chọn \(u\)LIATE: Logarithmic, Inverse trig, Algebraic, Trigonometric, Exponential (chọn \(u\) từ hạng mục xuất hiện sớm hơn).

  • Ví dụ: \(\int x\, e^x\, dx\). Đặt \(u = x\) (đại số) và \(dv = e^x\, dx\). Khi đó \(du = dx\)\(v = e^x\). Vậy: \(\int x\, e^x\, dx = x\, e^x - \int e^x\, dx = x\, e^x - e^x + C = e^x(x - 1) + C\).

  • Trong học máy, tích phân xuất hiện trong lý thuyết xác suất (tính xác suất bằng cách tích phân các hàm mật độ), trong kỳ vọng (trung bình có trọng số trên các phân bố liên tục), và trong tính diện tích dưới các đường cong ROC. Mặc dù trên thực tế ta hiếm khi tích phân bằng tay, việc hiểu tích phân nghĩa là gì giúp diễn giải các đại lượng này.

Bài tập lập trình (dùng CoLab hoặc notebook)

  1. Xấp xỉ số học \(\int_0^1 x^2\, dx\) bằng một tổng Riemann với số lượng hình chữ nhật tăng dần. So sánh với đáp án chính xác \(\frac{1}{3}\).

    import jax.numpy as jnp
    
    for n in [10, 100, 1000, 10000]:
        x = jnp.linspace(0, 1, n, endpoint=False)
        dx = 1.0 / n
        area = jnp.sum(x**2 * dx)
        print(f"n={n:5d}  approx: {area:.6f}  exact: {1/3:.6f}")
    

  2. Kiểm tra Định lý cơ bản của giải tích bằng phương pháp số. Định nghĩa \(F(x) = \int_0^x t^2\, dt = \frac{x^3}{3}\) và kiểm tra rằng đạo hàm của nó (tính qua jax.grad) bằng \(x^2\).

    import jax
    import jax.numpy as jnp
    
    F = lambda x: x**3 / 3
    dF = jax.grad(F)
    
    for x in [0.5, 1.0, 2.0, 3.0]:
        print(f"x={x:.1f}  F'(x)={dF(x):.4f}  x^2={x**2:.4f}")
    

  3. Trực quan hóa diện tích dưới \(f(x) = \sin(x)\) từ \(0\) đến \(\pi\). Dùng plt.fill_between để tô bóng diện tích và tính nó bằng phương pháp số với một tổng Riemann.

    import jax.numpy as jnp
    import matplotlib.pyplot as plt
    
    x = jnp.linspace(0, jnp.pi, 500)
    y = jnp.sin(x)
    
    plt.plot(x, y, color="purple", linewidth=2)
    plt.fill_between(x, y, alpha=0.2, color="purple")
    plt.title(f"Area = {jnp.sum(jnp.sin(x) * (jnp.pi / 500)):.4f}  (exact: 2.0)")
    plt.show()