Các tích phân xác định gần đúng bằng cách sử dụng tổng Riemann


19

Tổng Riemann trái và phải là xấp xỉ với các tích phân xác định . Tất nhiên, trong toán học, chúng ta cần phải rất chính xác, vì vậy chúng tôi đặt mục tiêu tính toán chúng với một số phân ngành tiếp cận vô hạn, nhưng điều đó không cần thiết cho mục đích của thử thách này. Thay vào đó, bạn nên cố gắng viết chương trình ngắn nhất, lấy đầu vào và cung cấp đầu ra thông qua bất kỳ phương thức mặc định nào , bằng bất kỳ ngôn ngữ lập trình nào , thực hiện như sau:

Bài tập

Cho hai số hữu tỉ mộtb (các giới hạn của tích phân xác định), một số nguyên dương n , một boolean k đại diện cho trái / phải và một chức năng hộp đen f , tính toán Riemann tổng sang trái hoặc phải (tùy thuộc vào k ) của mộtbf(x)dx , sử dụng n phân chia bằng nhau .

Thông số I / O

  • mộtb có thể là số hữu tỷ / dấu phẩy động hoặc phân số.

  • k có thể được biểu thị bằng bất kỳ hai giá trị riêng biệt và nhất quán nào, nhưng xin lưu ý rằngbạn không được phépthực hiện các chức năng hoàn chỉnh hoặc một phần làm đầu vào.

  • f là hàm hộp đen. Trích dẫn câu trả lời meta được liên kết ở trên,nội dung (tức là mã) của các hàm hộp đen có thể không được truy cập, bạn chỉ có thể gọi chúng (truyền đối số nếu có) và quan sát đầu ra của chúng. Nếu cần, vui lòng bao gồm các thông tin cần thiết về cú pháp ngôn ngữ của bạn sử dụng để chúng tôi có thể kiểm tra trình của bạn.

Là đầu ra, bạn phải cung cấp một tỷ lệ hợp lý / dấu phẩy động / phân số đại diện cho tổng Riemann mà bạn được yêu cầu. Như đã thảo luận trong quá khứ , sự thiếu chính xác của dấu phẩy động có thể bị bỏ qua, miễn là đầu ra của bạn chính xác đến ít nhất ba vị trí thập phân khi được làm tròn đến bội số gần nhất của 1/1000 (ví dụ: 1.4529999tốt thay vì 1.453).

Thông số toán học

  • f được đảm bảo liên tục giữamộtb (không nhảy, không lỗ, không tiệm cận đứng).

  • Có ba trường hợp có thể bạn phải xử lý: một= =b (Kết quả phải là 0 hoặc tương đương của nó), một<b hoặc một>b .

  • Nếu b<một , tích phân thay đổi dấu của nó. Ngoài ra, ý nghĩa đúng của tích phân trong trường hợp này là hướng tới một .

  • Các khu vực dưới biểu đồ là âm và những khu vực trên biểu đồ là tích cực.

Ví dụ / Trường hợp kiểm tra

Độ phân giải không tối ưu, vì tôi phải thu nhỏ chúng xuống một chút, nhưng chúng vẫn có thể đọc được.

  • f(x)=2x+1,a=5,b=13,n=4 , k = phải:

    2x + 1

    Kết quả sẽ được 152+192+232+272=168 , vì chiều rộng của mỗi hình chữ nhật là |ba|n=2và chiều cao tương ứng làf(7)=15,f(9)=19,f(11)=23,f(13)=27 .

  • f(x)=x,a=1,b=2.5,n=3 , k = trái:

    Căn bậc hai

    Đầu ra phải là 1.8194792169 .

  • f(x)= =-3x+4+x25,một= =12,5,b= =2,5,n= =10 , k = phải:

    -3x + 4 + 1 / 5x ^ 2

    Giá trị đầu ra dự kiến ​​là -(-4.05-5,45-6,45-7,05-7,25-7,05-6,45-5,45-4.05-2,25)= =55,5 , vì tích phân thay đổi dấu hiệu khi lật ranh giới ( b<một ) .

  • f(x)= =9-4x+2x27,một= =0,b= =15,n= =3 , k = trái:

    9-4x + 2 / 7x ^ 2

    Tính tổng Riemann của chúng tôi, chúng tôi nhận được 13,5714285715 .

  • f(x)= =6,một= =1,b= =4,n= =2 , k = phải - Đầu ra:18 .

  • f(x)= =x7+165x+1,một= =7,b= =7,n= =4 , k = trái - Đầu ra:0 .

  • f(x)= =xtội(x-1),một= =0,b= =1,n= =50 , k = phải - Đầu ra:0,385723952885505 . Lưu ý rằng sin sử dụng radian ở đây, nhưng thay vào đó hãy sử dụng độ.


3
Cảm ơn đặc biệt: Thử thách này đã được đăng trong Sandbox , nơi nó nhận được phản hồi có giá trị từ người dùng202729 , admBorkBorkLeaky Nun .
Ông Xcoder

Tôi chắc chắn hy vọng các giải pháp ở đây sẽ giúp sinh viên Calc I đáng giá nhiều năm ...
Giuseppe

f(x) = x * sin(1 / x); a = 0; b = 1; n = 50; k = right — Output: 0.385723952885505. Note that sine uses radians here, but feel free to use degrees instead.Bây giờ f (x) là một hộp đen tại sao nó lại quan trọng?
l4m2

@ l4m2 Không quan trọng lắm, chỉ muốn cho mọi người biết rằng họ không nên lo lắng về những điều đó.
Ông Xcoder

@Giuseppe Không. Các phương pháp của chương trình ở đây thậm chí còn tồi tệ hơn các phương pháp của máy tính cầm tay. [chỉ nói]
user202729

Câu trả lời:


8

R , 69 65 63 57 byte

function(a,b,n,k,f,w=(b-a)/n)sum(sapply(a+w*(1:n-k),f))*w

Hãy thử trực tuyến!

Mất k=FALSEcác khoản tiền bên tay phải, mặc dù liên kết TIO hiện bao gồm các bí danh cho "bên trái" và "bên phải" để dễ sử dụng.

a+w*(1:n-k) tạo các điểm bên trái hoặc bên phải thích hợp.

Sau đó sapplyáp dụng fcho từng yếu tố của kết quả, sau đó chúng tôi sumtăng và nhân với độ rộng khoảng (b-a)/nđể mang lại kết quả. Điều cuối cùng này cũng gọn gàng quan tâm đến bất kỳ vấn đề dấu hiệu chúng ta có thể có.


4

SNOBOL4 (CSNOBOL4) , 127 byte

	DEFINE('R(a,b,n,k,p)')
R	l =(b - a) / n
	i =1
l	R =R + eval(p '(a + l * (i - k))')
	i =lt(i,n) i + 1	:s(l)
	R =R * l :(return)

Hãy thử trực tuyến!

Giả sử rằng hàm pđược xác định ở đâu đó, điều này sẽ xảy ra a,b,n,k,(name of p), với k=0bên phải và l=1bên trái.

SNOBOL4+hỗ trợ của catpaw REALnhưng không có chức năng tích hợp sẵn. Tuy nhiên, tôi cho rằng một người có thể đưa ra một sinchức năng hợp lý bằng cách sử dụng một chuỗi taylor.

Tôi không chắc chắn 100% đây là cách "đúng" để truyền chức năng hộp đen trong SNOBOL (theo hiểu biết của tôi, không có chức năng hạng nhất), nhưng có vẻ hợp lý với tôi.

Tôi giả sử rằng giả sử hàm được định nghĩa là f sẽ ngắn hơn, vì dòng lcó thể là

l	R =R + f(a + l * (i - k))

nhưng sau đó nó không được thông qua như một cuộc tranh cãi, mà cảm giác hơi giống như "gian lận".

Lưu ý rằng liên kết TIO có :(e)sau DEFINEcâu lệnh, do đó mã sẽ thực sự chạy đúng.


4

Julia 0,6 , 50 byte

R(f,a,b,n,k)=(c=(b-a)/n;sum(f.(a+[k:n+k-1...]c))c)

Hãy thử trực tuyến!

Một phạm vi chuẩn hóa được xây dựng, thu thập thành một vectơ và sau đó thu nhỏ. Việc thu thập phạm vi vào một vectơ bằng cách sử dụng [X...]là cần thiết để tránh inexact errorkhi nhân phạm vi trực tiếp với 0 khi a=b. Tương tự, xây dựng một phạm vi trực tiếp với :hoặcrange() là không thể khi a=b.

Cách sử dụng k rất giống với giải pháp của Guiseppe , với k=1for rightk=0for left.


f.véc tơ ftrên (các) đối số của nó?
Giuseppe

@Giuseppe: Chính xác. f.là ứng dụng yếu tố khôn ngoan của f.
LukeS

2

Haskell , 73 67 byte

Cảm ơn H.PWiz và Bruce Forte vì những lời khuyên!

(f&a)b n k|d<-(b-a)/realToFrac n=d*sum(f<$>take n(drop k[a,a+d..]))

Hãy thử trực tuyến!

Giải pháp khá đơn giản.

k0cho trái và 1phải.


1
Nếu bạn đang dùng n, bạn không cần phải truy cậpb
H.PWiz



1

Thạch , 21 byte

ƓḶ+Ɠ÷
IḢ×¢A+ṂɠvЀÆm×I

Hãy thử trực tuyến!

Lấy a,btừ các đối số, và

n
right
f

từ stdin.


Nếu bạn không quen với Jelly, bạn có thể sử dụng Python để viết hàm hộp đen f:

f (x) = 2x + 1 ; a = 5; b = 13; n = 4; k = đúng

f (x) = √x ; a = 1; b = 2,5; n = 3; k = trái

f (x) = -3x + 4 + 1/5 * x 2 ; a = 12,5; b = 2,5; n = 10; k = đúng

f (x) = 9 - 4x + 2/7 * x 2 ; a = 0; b = 15; n = 3; k = trái

f (x) = 6 ; a = 1; b = 4; n = 2; k = đúng

f (x) = x * sin (1 / x) ; a = 0; b = 1; n = 50; k = đúng


Giải trình:


ƓḶ+Ɠ÷     Helper niladic link.
Ɠ         First line from stdin. (n). Assume n = 4.
 Ḷ        Lowered range (unlength). Get [0, 1, 2, 3].
  +Ɠ      Add second line from stdin (k). Assume k = 1 (right).
            Get [1, 2, 3, 4].
    ÷     Divide by (n). Get [0.25,0.5,0.75,1].

IḢ×¢A+ṂɠvЀÆm×I   Main monadic link. Take input `[a, b]`, assume `a=2,b=6`.
IḢ                `a-b`. Get `-4`.
  ×¢              Multiply by value of niladic link above. Get `[-1,-2,-3,-4]`.
    A             Absolute value. Get `[1,2,3,4]`.
     +Ṃ           Add min(a, b) = 2. Get `[3,4,5,6]`.
        vЀ       For each number, evaluate with...
       ɠ            input line from stdin.
           Æm     Arithmetic mean.
             ×I   Multiply by `a-b`.


1

Perl 6 , 65 byte

{my \d=($^b-$^a)/$^n;sum ($a,*+d...*)[($^k+^0>d)+ ^$n]».&^f X*d}

Hãy thử trực tuyến!

Tương đối đơn giản. Các biến chứng chỉ là xử lý các a > btrường hợp, mà tôi làm bởi xor-ing lá cờ đầu vào $^kvới 0 > d, mà đảo ngược nó khi a > b.


0

APL (Dyalog Classic) , 37 byte

{(a b n k)←⍵⋄ln÷⍨b-al×+/⍺⍺a+l×k+⍳n}

Hãy thử trực tuyến!

APL NARS, 37 ký tự

Hàm có đối số ở bên trái hàm, trong đối số số bất thường k. Trong câu hỏi k = trái ở đây có nghĩa là k = 1; k = ngay tại đây có nghĩa là k = 0. Kiểm tra:

  f←{(a b n k)←⍵⋄ln÷⍨b-al×+/⍺⍺a+l×k+⍳n}
  {1+2×⍵} f 5 13 4 0
168
  {√⍵} f 1 2.5 3 ¯1
1.819479217
  {4+(¯3×⍵)+0.2×⍵×⍵} f 12.5 2.5 10 0
55.5
  {9+(¯4×⍵)+7÷⍨2×⍵×⍵} f 0 15 3 ¯1
13.57142857
  {6-0×⍵} f 1 4 2 0
18
  {1+(165×⍵)+⍵*7} f 7 7 4 ¯1
0
  {⍵×1○÷⍵} f 0 1 50 0
0.3857239529

Đệ trình được tính bằng byte, không phải ký tự. Tôi không nhớ nếu NARS có trang mã tùy chỉnh (vì vậy nó cũng sẽ là 37 byte) hoặc sử dụng UTF16.
Uriel

@Uriel Đó là 37 byte trong Dyalog APL classic theo liên kết; có thể 35x2 byte cho Nars Apl ...
RosLuP

Vậy tại sao bạn viết nó là NARS? NARS thậm chí có dfnss? Bằng cách này, bạn có thể bỏ cha mẹ đầu tiên trong 35 byte
Uriel

APL NARS, 37 ký tự có nghĩa là nó cũng nên chạy trong NARS APL
RosLuP
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.