Perkiraan ∫ ((e ^ x) / (x ^ x)) dx


24

Anda harus memperkirakan nilai:

masukkan deskripsi gambar di sini

Di mana input Anda I.

Aturan

  • Anda tidak boleh menggunakan fungsi integral bawaan.
  • Anda tidak dapat menggunakan fungsi penjumlahan tak terbatas bawaan.
  • Kode Anda harus dijalankan dalam jumlah waktu yang wajar (<20 detik pada mesin saya)
  • Anda dapat berasumsi bahwa input lebih besar dari 0 tetapi kurang dari batas atas bahasa Anda.
  • Ini bisa berupa segala bentuk pengembalian / keluaran standar.

Anda dapat memverifikasi hasil Anda di Wolfram | Alpha (Anda dapat memverifikasi dengan menggabungkan input yang Anda maksudkan dengan permintaan yang ditautkan).

Contohnya

(sebut saja fungsinya f)

f(1) -> 2.18273
f(50) -> 6.39981
f(10000) -> 6.39981
f(2.71828) -> 5.58040
f(3.14159) -> 5.92228

Jawaban Anda harus akurat ±.0001.


@ThomasKwa Maksimum untuk bahasa Anda. Saya akan menambahkannya ke pertanyaan.
Addison Crump

Wolfram Alpha mengatakan putaran terakhir ke5.92228
Neil

@Neil oo Baiklah kalau begitu, pasti salah ketik. Terima kasih!
Addison Crump

7
Saya akan memberikan 200 rep untuk jawaban valid terpendek dalam TI-BASIC yang dijalankan dalam <20 detik pada WabbitEmu dengan kecepatan 100%.
lirtosiast

@ lirtosiast Jika Anda masih ingin menindaklanjuti hadiah ini, Anda harus mempostingnya di sini .
Addison Crump

Jawaban:


10

Julia, 79 77 38 byte

I->sum(x->(e/x)^x,0:1e-5:min(I,9))/1e5

Ini adalah fungsi anonim yang menerima nilai numerik dan mengembalikan float. Untuk menyebutnya, tetapkan ke variabel.

Pendekatan di sini adalah dengan menggunakan jumlah Riemann yang tepat untuk memperkirakan integral, yang diberikan oleh rumus berikut:

getah

Dalam kasus kami, a = 0 dan b = I , input. Kami membagi wilayah integrasi menjadi n = 10 5 bagian diskrit, jadi ∆ x = 1 / n = 10 -5 . Karena ini adalah relatif konstan terhadap penjumlahan, kita dapat menarik ini di luar penjumlahan dan hanya menjumlahkan evaluasi fungsi pada setiap titik dan membaginya dengan n .

Fungsi ini secara mengejutkan berperilaku baik (plot dari Mathematica):

tempat matematika

Karena fungsi mengevaluasi hampir ke 0 untuk input lebih besar dari sekitar 9, kami memotong input menjadi I jika saya kurang dari 9, atau 9 sebaliknya. Ini menyederhanakan perhitungan yang harus kita lakukan secara signifikan.

Kode tidak dikunci:

function g(I)
    # Define the range over which to sum. We truncate the input
    # at 9 and subdivide the region into 1e5 pieces.
    range = 0:1e-5:min(I,9)

    # Evaluate the function at each of the 1e5 points, sum the
    # results, and divide by the number of points.
    return sum(x -> (e / x)^x, range) / 1e5
end

Disimpan 39 byte berkat Dennis!


Bukankah ini juga setara dengan: $ \ frac {t \ sum_ {k = 0} ^ {n} (f (a + kt) + f (a + (k + 1) t))}} {2} $? Itu tampaknya sedikit lebih sederhana dari suatu algoritma untuk digunakan.
Addison Crump

10^4dapat ditulis sebagai 1e4.
Rainer P.

@VoteToClose Akhirnya mengambil pendekatan yang berbeda
Alex A.

@RainerP. Heh, benar. Terima kasih.
Alex A.

Nilai asimptotik integral adalah $ 6,39981 ... $. Nilai $ 6,39981 ... - 10 ^ {- 4} $ pertama kali diperoleh pada $ I = 7,91399 ... $, sehingga Anda dapat memotong pada $ 8 $ bukannya $ 9 $ untuk menghemat sedikit waktu.
Eric Towers

9

Jelly, 20 19 17 byte

ð«9×R÷øȷ5µØe÷*×ḢS

Ini meminjam truncate pintar pada 9 trik dari jawaban @ AlexA. , Dan menggunakan jumlah Riemann yang tepat untuk memperkirakan integral yang sesuai.

Test case terpotong membutuhkan waktu, tetapi cukup cepat di Coba online!

Bagaimana itu bekerja

ð«9×R÷øȷ5µØe÷*×ḢS  Main link. Input: I

      øȷ5          Niladic chain. Yields 1e5 = 100,000.

ð                  Dyadic chain. Left argument: I. Right argument: 1e5.
 «9                Compute min(I, 9).
   ×               Multiply the minimum with 1e5.
    R              Range; yield [1, 2, ..., min(I, 9) * 1e5] or [0] if I < 1e-5.
     ÷             Divide the range's items by 1e5.
                   This yields r := [1e-5, 2e-5, ... min(I, 9)] or [0] if I < 1e-5.

         µ         Monadic chain. Argument: r
          Øe÷      Divide e by each element of r.
             *     Elevate the resulting quotients to the corresponding elements,
                   mapping t -> (e/t) ** t over r.
                   For the special case of r = [0], this yields [1], since
                   (e/0) ** 0 = inf ** 0 = 1 in Jelly.
              ×Ḣ   Multiply each power by the first element of r, i.e., 1e-5 or 0.
                S  Add the resulting products.

Oh, baiklah. Aturan kiri adalah bagaimana itu disebut dalam kelas AP Calculus. : P Coolio.
Addison Crump

Saya tidak akrab dengan nama itu, tetapi aturan sebelah kiri mungkin menggunakan titik akhir kiri. Kode saya menggunakan yang benar.
Dennis

2
(~ -.-) ~ Ini semacam aturan tangan. xD
Addison Crump

4

ES7, 78 byte

i=>[...Array(n=2e3)].reduce(r=>r+Math.exp(j+=i)/j**j,0,i>9?i=9:0,i/=n,j=-i/2)*i

Ini menggunakan aturan persegi panjang dengan 2000 persegi panjang, yang (setidaknya untuk contoh) tampaknya menghasilkan jawaban yang cukup akurat, tetapi akurasi dapat dengan mudah ditingkatkan jika perlu. Itu harus menggunakan 9 trik jika tidak, akurasi menurun untuk nilai yang besar.

Versi 73 byte yang menggunakan persegi panjang lebar ~ 0,001 sehingga tidak bekerja di atas ~ 700 karena Math.exp hits Infinity:

i=>[...Array(n=i*1e3|0)].reduce(r=>r+Math.exp(j+=i)/j**j,0,i/=n,j=-i/2)*i

2

golflua , 83 karakter

Saya akan mengakuinya: butuh beberapa saat untuk mencari tahu min(I,9)trik yang disajikan Alex memungkinkan komputasi angka tinggi sewenang-wenang karena integral terpusat pada saat itu.

\f(x)~M.e(x)/x^x$b=M.mn(I.r(),9)n=1e6t=b/n g=0.5+f(b/2)~@k=1,n-1g=g+f(k*t)$I.w(t*g)

Setara dengan Lua yang tidak diserang adalah

function f(x)
   return math.exp(x)/x^x
end

b=math.min(io.read("*n"),9)
n=1e6
t=b/n
g=0.5+f(b/2)

for k=1,n-1 do
   g=g+f(k*t)
end
io.write(t*g)

Dan "sebentar" maksud saya sekitar 10 menit. Dan itu sepenuhnya karena saya tidak benar-benar membaca komentar Alex yang menjelaskannya, hanya melihatnya dalam kode.
Kyle Kanos

2

Python 2, 94 76 byte

Terima kasih kepada @Dennis karena telah menyelamatkan saya 18 byte!

lambda I,x=1e5:sum((2.71828/i*x)**(i/x)/x for i in range(1,int(min(I,9)*x)))

Cobalah online dengan testcases!

Menggunakan metode persegi panjang untuk aproksimasi. Menggunakan lebar persegi panjang 0,0001 yang memberi saya presisi yang diminta. Juga memotong input yang lebih besar 9 untuk mencegah kesalahan memori dengan input yang sangat besar.


2

Perl 6, 90 55 byte

{my \x=1e5;sum ((e/$_*x)**($_/x)/x for 1..min($_,9)*x)}

pemakaian

my &f = {my \x=1e5;sum ((e/$_*x)**($_/x)/x for 1..min($_,9)*x)}

f(1).say;       # 2.1827350239231
f(50).say;      # 6.39979602775846
f(10000).say;   # 6.39979602775846
f(2.71828).say; # 5.58039854392816
f(3.14159).say; # 5.92227602782184

Sudah larut dan aku perlu tidur, aku akan melihat apakah aku bisa mendapatkan ini lebih pendek besok.

EDIT: Berhasil mendapatkannya sedikit lebih pendek setelah melihat metode @DenkerAffe.


1
Saya suka bagaimana ia mengatakan $ h * t di sana. : D
Addison Crump

2

Pyth, 34 29 byte

Disimpan 5 Bytes dengan bantuan dari @Dennis!

J^T5smcc^.n1d^ddJmcdJU*hS,Q9J

Cobalah online!

Penjelasan

Algoritma yang sama seperti pada jawaban Python saya .

J ^ T5smcc ^ .n1d ^ ddJmcdJU * hS, Q9J # Q = input
J ^ T5 # atur J jadi persegi panjang lebar * 10 ^ 5
                       hS, Q9 # truncate input lebih besar 9
                 mcdJU / J # berkisar dari nol hingga Input dalam langkah-langkah J
     mcc ^ .n1d ^ ddJ # menghitung luas untuk setiap elemen dalam daftar
    s # Jumlah semua area dan hasil keluaran


Anda dapat menyimpan beberapa byte dengan menetapkan Juntuk ^T5dan bertukar perkalian dengan pembagian dengan J. Selain itu, pemotongan dapat dilakukan dengan hS,Q9.
Dennis

@ Dennis Terima kasih, tidak memikirkan hal itu. Trik penyortirannya juga bagus, saya hanya mencari min^^
Denker

2

MATL , 26 byte

9hX<t1e6XK:K/*ttZebb^/sK/*

Ini mendekati integral sebagai jumlah Riemann. Seperti yang dikemukakan oleh Alex, kita dapat memotong interval integrasi sekitar 9 karena nilai-nilai fungsi sangat kecil di luar itu.

Nilai maksimum fungsi kurang dari 3, jadi langkah sekitar 1e-5 harus cukup untuk mendapatkan akurasi yang diinginkan. Jadi untuk input maksimum 9 kita membutuhkan sekitar 1e6 poin.

Ini membutuhkan waktu sekitar 1,5 detik dalam kompiler online, untuk setiap nilai input.

Cobalah online !

9hX<         % input number, and limit to 9
t            % duplicate
1e6XK:       % generate vector [1,2,...,1e6]. Copy 1e6 to clipboard K
K/*          % divide by 1e6 and multiply by truncated input. This gives 
             % a vector with 1e6 values of x from 0 to truncated input
ttZe         % duplicate twice. Compute exp(x)
bb^          % rotate top three elements of stack twice. Compute x^x
/            % divide to compute exp(x)/x^x
s            % sum function values
K/*          % multiply by the step, which is the truncated input divided
             % by 1e6

2

Vitsy, 39 byte

Pikir saya mungkin juga memberikan kontribusi saya sendiri. ¯ \ _ (ツ) _ / ¯ Ini menggunakan estimasi Left-Hand Riemann Sum dari integral.

D9/([X9]1a5^D{/V}*0v1{\[EvV+DDv{/}^+]V*

D9/([X9]               Truncation trick from Alex A.'s answer.
D                      Duplicate input.
 9/                    Divide it by 9.
   ([  ]               If the result is greater than 0
     X9                Remove the top item of the stack, and push 9.

1a5^D{/V}*0v0{         Setting up for the summation.
1                      Push 1.
 a5^                   Push 100000.
    D                  Duplicate the top item of the stack.
     {                 Push the top item of the stack to the back.
      /                Divide the top two items of the stack. (1/100000)
       V               Save it as a global variable.
                       Our global variable is ∆x.
        }              Push the bottom item of the stack to the top.
         *             Multiply the top two items.
                       input*100000 is now on the stack.
          0v           Save 0 as a temporary variable.
            0          Push 1.
             {         Push the bottom item of the stack to the top.
                       input*100000 is now the top of the stack.

\[EvV+DDv{/}^+]        Summation.
\[            ]        Loop over this top item of the stack times.
                       input*100000 times, to be exact.
  E                    Push Math.E to the stack.
   v                   Push the temporary variable to the stack.
                       This is the current value of x.
    V+                 Add ∆x.
      DD               Duplicate twice.
        v              Save the temporary variable again.
         {             Push the top item of the stack to the back.
          /            Divide the top two items.
                       e/x
           }           Push the top item back to the top of the stack.
            ^          Put the second to top item of the stack to the power of the top item.
                       (e/x)^x
             +         Add that to the current sum.

V*                     Multiply by ∆x

Ini meninggalkan jumlah di bagian atas tumpukan. Tautan online coba di bawah ini Nmenunjukkan hasil untuk Anda.

Cobalah secara Online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.