Khả thi? Đúng. Hữu ích? Không. Các tối ưu hóa tôi sẽ liệt kê ở đây dường như không thể tạo ra nhiều hơn một phần nhỏ của phần trăm chênh lệch trong thời gian chạy. Một trình biên dịch tốt có thể đã làm những điều này cho bạn.
Dù sao, nhìn vào vòng lặp bên trong của bạn:
for (s=0,j=a;j<b;j+=h){
func2 = func(j+h);
s = s + 0.5*(func1+func2)*h;
func1 = func2;
}
Tại mỗi lần lặp lại, bạn thực hiện ba phép toán có thể được đưa ra bên ngoài: cộng j + h
, nhân với 0.5
và nhân với h
. Cách đầu tiên bạn có thể khắc phục bằng cách bắt đầu biến lặp của mình tại a + h
và các biến khác bằng cách bao gồm các phép nhân:
for (s=0, j=a+h; j<=b; j+=h){
func2 = func(j);
s += func1+func2;
func1 = func2;
}
s *= 0.5 * h;
Mặc dù tôi sẽ chỉ ra rằng bằng cách thực hiện điều này, do lỗi vòng tròn dấu phẩy động, có thể bỏ lỡ lần lặp cuối cùng của vòng lặp. (Đây cũng là một vấn đề trong quá trình triển khai ban đầu của bạn.) Để giải quyết vấn đề đó, hãy sử dụng một unsigned int
hoặc bộ size_t
đếm:
size_t n;
for (s=0, n=0, j=a+h; n<N; n++, j+=h){
func2 = func(j);
s += func1+func2;
func1 = func2;
}
s *= 0.5 * h;
Như câu trả lời của Brian nói, thời gian của bạn tốt hơn dành cho việc tối ưu hóa việc đánh giá chức năng func
. Nếu độ chính xác của phương pháp này là đủ, tôi nghi ngờ bạn sẽ tìm thấy mọi thứ nhanh hơn cho cùng N
. (Mặc dù bạn có thể chạy một số thử nghiệm để xem liệu Runge-Kutta có cho phép bạn hạ thấp N
đủ để việc tích hợp tổng thể mất ít thời gian hơn mà không làm mất độ chính xác hay không.)
trapezoidal_integration
thay vìtrap
,sum
hoặcrunning_total
thay vìs
(và cũng sử dụng+=
thay vìs = s +
),trapezoid_width
hoặcdx
thay vìh
(hoặc không, tùy thuộc vào ký hiệu ưa thích của bạn cho quy tắc hình thang), và thay đổifunc1
vàfunc2
phản ánh thực tế rằng chúng là các giá trị, không phải là hàm. Ví dụfunc1
->previous_value
vàfunc2
->current_value
, hoặc một cái gì đó tương tự.