Perkiraan integral pasti menggunakan jumlah Riemann

19

Jumlah Riemann kiri dan kanan adalah perkiraan untuk integral tertentu . Tentu saja, dalam matematika kita harus sangat akurat, jadi kita bertujuan untuk menghitungnya dengan sejumlah subdivisi yang mendekati tak terhingga, tetapi itu tidak diperlukan untuk keperluan tantangan ini. Anda sebaiknya mencoba menulis program terpendek, mengambil input dan memberikan output melalui salah satu metode default , dalam bahasa pemrograman apa pun , yang melakukan hal berikut:

Tugas

Diberikan dua bilangan rasional dan (batas integral integral), bilangan bulat positif , boolean mewakili fungsi kiri / kanan dan kotak hitam , menghitung jumlah Riemann kiri atau kanan (tergantung pada ) dari , menggunakan subdivisi yang sama .Sebuahbnk fkabf(x)dxn

I / O Spesifikasi

  • a dan dapat berupa angka atau pecahan rasional / floating-point. b

  • k dapat diwakili oleh dua nilai berbeda dan konsisten, tetapi harap diingat bahwa Anda tidak diizinkan untuk mengambil fungsi lengkap atau parsial sebagai input.

  • f adalah fungsi kotak hitam. Mengutip jawaban meta yang ditautkan di atas, konten (yaitu kode) dari fungsi kotak-hitam mungkin tidak dapat diakses, Anda hanya dapat memanggil mereka (melewati argumen jika ada) dan mengamati hasilnya . Jika perlu, harap sertakan informasi yang diperlukan tentang sintaksis yang digunakan bahasa Anda sehingga kami dapat menguji kiriman Anda.

Sebagai output, Anda harus memberikan fraksi / floating-point / rasional yang mewakili jumlah Riemann yang Anda minta. Seperti dibahas di masa lalu , ketidaktepatan floating-point dapat diabaikan, selama output Anda akurat untuk setidaknya tiga tempat desimal ketika dibulatkan ke kelipatan terdekat 1/1000 (mis. Baik 1.4529999-baik saja alih-alih 1.453).

Spesifikasi Matematika

  • f dijamin kontinu antara dan (tidak ada lompatan, tidak ada lubang, tidak ada asimtot vertikal).Sebuahb

  • Ada tiga kemungkinan kasus yang harus Anda tangani: (Hasilnya harus atau yang setara), atau .Sebuah=b0Sebuah<bSebuah>b

  • Jika , integral mengubah tandanya. Juga, pengertian yang tepat dari integral dalam hal ini adalah menuju .b<SebuahSebuah

  • Area di bawah grafik negatif dan yang di atas grafik positif.

Contoh / Kasus Uji

Resolusi tidak optimal, karena saya harus menyusutkannya sedikit, tetapi masih dapat dibaca.

  • f(x)=2x+1,Sebuah=5,b=13,n=4 , k = benar:

    2x + 1

    Hasilnya harus 152+192+232+272=168 , karena lebar setiap persegi adalah dan ketinggian yang sesuai adalah .|b-Sebuah|n=2f(7)=15,f(9)=19,f(11)=23,f(13)=27

  • f(x)=x,Sebuah=1,b=2.5,n=3 , k = kiri:

    Akar pangkat dua

    Outputnya harus .1.8194792169

  • f(x)=-3x+4+x25,Sebuah=12.5,b=2.5,n=10 , k = benar:

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

    Nilai output yang diharapkan adalah -(-4.05-5.45-6.45-7.05-7.25-7.05-6.45-5.45-4.05-2.25)=55.5 , karena integral berubah tanda ketika membalik batas ( b<Sebuah ) .

  • f(x)=9-4x+2x27,Sebuah=0,b=15,n=3 , k = kiri:

    9-4x + 2 / 7x ^ 2

    Menghitung jumlah Riemann kami, kami mendapatkan 13.5714285715 .

  • f(x)=6,Sebuah=1,b=4,n=2 , k = kanan - Output:18 .

  • f(x)=x7+165x+1,Sebuah=7,b=7,n=40

  • f(x)=xdosa(x-1),Sebuah=0,b=1,n=500.385723952885505

Tuan Xcoder
sumber
3
Terima kasih khusus: Tantangan ini telah diposting di Sandbox , di mana ia menerima umpan balik yang berharga dari user202729 , AdmBorkBork dan Leaky Nun .
Tn. Xcoder
Saya sungguh berharap solusi di sini membantu siswa Calc I selama bertahun-tahun ...
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.Sekarang f (x) adalah kotak hitam mengapa itu penting?
l4m2
@ l4m2 Tidak masalah, hanya ingin membuat orang tahu bahwa mereka tidak perlu khawatir tentang hal-hal seperti itu.
Tn. Xcoder
@Giuseppe No. Metode program di sini bahkan lebih buruk daripada metode kalkulator genggam. [hanya mengatakan]
user202729

Jawaban:

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

Cobalah online!

Diperlukan k=FALSEuntuk jumlah kanan, meskipun tautan TIO sekarang menyertakan alias untuk "kiri" dan "kanan" untuk kemudahan penggunaan.

a+w*(1:n-k) menghasilkan poin kiri atau kanan yang tepat.

Kemudian sapplyberlaku funtuk setiap elemen hasil, yang kemudian kita sumnaik dan kalikan dengan lebar interval (b-a)/nuntuk menghasilkan hasilnya. Yang terakhir ini juga dengan rapi menangani masalah tanda yang mungkin kita miliki.

Giuseppe
sumber
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)

Cobalah online!

Dengan asumsi bahwa fungsi ptersebut didefinisikan di suatu tempat, ini membutuhkan a,b,n,k,(name of p), dengan k=0untuk kanan dan l=1kiri.

catspaw ini SNOBOL4+mendukung REALs tetapi tidak memiliki builtin fungsi trigonometri. Namun, saya kira orang bisa datang dengan sinfungsi yang masuk akal menggunakan seri taylor.

Saya tidak 100% yakin ini adalah cara "benar" untuk melewatkan fungsi kotak hitam di SNOBOL (yang, sepengetahuan saya, tidak memiliki fungsi kelas satu), tetapi tampaknya masuk akal bagi saya.

Saya mengira bahwa dengan asumsi fungsi didefinisikan sebagai fakan lebih pendek, seperti garis lbisa

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

tapi kemudian itu tidak disahkan sebagai argumen, yang terasa agak seperti "curang".

Perhatikan bahwa tautan TIO memiliki pernyataan :(e)setelahnya DEFINE, sehingga kode tersebut akan benar-benar berjalan dengan benar.

Giuseppe
sumber
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)

Cobalah online!

Rentang yang dinormalkan dibangun, dikumpulkan ke dalam vektor dan kemudian diskalakan. Mengumpulkan rentang ke dalam vektor menggunakan [X...]perlu untuk menghindari inexact errorketika mengalikan rentang secara langsung dengan 0 saat a=b. Demikian pula, membangun rentang secara langsung dengan :atau range()tidak mungkin kapan a=b.

Penggunaan k sangat mirip dengan solusi Guiseppe , dengan k=1untuk rightdan k=0untuk left.

LukeS
sumber
f.meng-vektorisasi fargumennya?
Giuseppe
@Giuseppe: Tepat. f.adalah aplikasi elemen-bijaksana f.
LukeS
2

Haskell , 73 67 byte

Terima kasih kepada H.PWiz dan Bruce Forte untuk tipsnya!

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

Cobalah online!

Solusi yang sangat mudah.

kadalah 0untuk kiri dan 1hak.

Cristian Lupascu
sumber
1
Jika Anda mengambil n, Anda tidak perlu naik keb
H.PWiz
2

Python 2 , 99 94 byte

Sedikit solusi naif.

def R(f,a,b,n,k):s=cmp(b,a);d=s*(b-a)/n;return s*sum(d*f([0,a,b][s]+i*d)for i in range(k,n+k))

Cobalah online!

mbomb007
sumber
Untuk beberapa alasan saya pikir kami harus menangani input integer. Terima kasih.
mbomb007
1

Jelly , 21 byte

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

Cobalah online!

Ambil a,bdari argumen, dan

n
right
f

dari stdin.


Jika Anda tidak terbiasa dengan Jelly, Anda dapat menggunakan Python untuk menulis fungsi kotak hitam f:

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

f (x) = √x ; a = 1; b = 2.5; n = 3; k = kiri

f (x) = -3x + 4 + 1/5 * x 2 ; a = 12.5; b = 2.5; n = 10; k = benar

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

f (x) = 6 ; a = 1; b = 4; n = 2; k = benar

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


Penjelasan:


ƓḶ+Ɠ÷     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`.

pengguna202729
sumber
1

Perl 6 , 65 byte

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

Cobalah online!

Relatif mudah. Satu-satunya komplikasi adalah menangani a > bcase, yang saya lakukan dengan xor-ing flag input $^kdengan 0 > d, yang membalik kapan a > b.

Sean
sumber
0

APL (Dyalog Classic) , 37 byte

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

Cobalah online!

APL NARS, 37 karakter

Fungsi memiliki argumen di sebelah kiri fungsi, di argumen numerik kanan abnormal k. Dalam pertanyaan k = ditinggalkan di sini artinya k = ¯1; k = di sini artinya k = 0. Uji:

  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
RosLuP
sumber
Kiriman dihitung dalam byte, bukan karakter. Saya tidak ingat apakah NARS memiliki halaman kode khusus (jadi itu juga 37 byte) atau menggunakan UTF16.
Uriel
@Uriel Ini adalah 37 byte dalam Dyalog APL classic, ikuti tautannya; mungkin 35x2 byte untuk Nars Apl ...
RosLuP
Jadi mengapa Anda menulisnya sebagai NARS? Apakah NARS bahkan memiliki dfnss? Ngomong-ngomong, Anda dapat melepaskan orang tua pertama selama 35 byte
Uriel
APL NARS, 37 karakter artinya harus berjalan di NARS APL juga
RosLuP