Cara membuat fungsi dari n variabel (Julia)

Untuk n tetap, saya ingin membuat fungsi dengan variabel n

f(x_1, ..., x_n)

Misalnya jika n=3, saya ingin membuat algoritma seperti itu

f(x_1, x_2, x_3) = x_1 + x_2 + x_3

Akan sangat menyenangkan jika memiliki algoritme untuk setiap n:

f(x_1, ..., x_n) = x_1 + ... + x_n

Saya tidak tahu cara mendeklarasikan fungsi dan cara membuat variabel n.

Terima kasih untuk bantuannya,


person Tio Miserias    schedule 22.02.2021    source sumber


Jawaban (2)


Di Julia Anda bisa melakukannya

function f(x...)
     sum(x)
end

Dan sekarang:

julia> f(1,2,3)
6

Perhatikan bahwa dalam fungsi f, x hanya dilihat sebagai Tuple sehingga Anda dapat melakukan apa pun yang Anda inginkan (termasuk menanyakan jenis elemen, dll).

Secara lebih umum Anda dapat mendefinisikan function f(x...;y...). Mari kita mencobanya

function f(x...;y...)
    @show x
    @show Dict(y)
end

Dan sekarang jalankan:

julia> f(1,2,"hello";a=22, b=777)
x = (1, 2, "hello")
Dict(y) = Dict(:a => 22, :b => 777)
Dict{Symbol, Int64} with 2 entries:
  :a => 22
  :b => 777

Terakhir, cara lain (yang mungkin kurang elegan) adalah:

g(v::NTuple{3,Int}) = sum(v)

Ini memaksa v menjadi elemen 3 Tuple dan g disebut sebagai g((1,2,3))

person Przemyslaw Szufel    schedule 22.02.2021
comment
Dan jika Anda menginginkan fungsi f(x_1,x_2,...,x_n) = x_i untuk beberapa 1 \leq i\leq n. Bagaimana kamu melakukan ini? - person Tio Miserias; 23.02.2021
comment
Jika Anda menginginkan fungsi dengan parameter yang tepat, katakanlah 55 Int, Anda dapat membuatnya dengan macro tetapi menurut saya menggunakan makro dalam skenario seperti itu lebih berlebihan daripada gaya Julian yang bagus. Salah satu cara yang kurang elegan adalah g(v::NTuple{3,Int}) = sum(v) yang kemudian disebut sebagai g((1,2,3)). Semoga itu bisa membantu. - person Przemyslaw Szufel; 23.02.2021
comment
@Tio Untuk ini Anda dapat melakukan f(x...) = x[i] tetapi IMHO agak aneh. - person Benoit Pasquier; 23.02.2021
comment
Anda dapat menggunakan Base.Cartesian (lihat dokumen) tetapi saya sangat setuju dengan poster di atas bahwa Anda lebih baik menggunakan tupel untuk hal-hal semacam ini. Daripada meneruskan banyak argumen, cukup berikan satu argumen tuple. - person tholy; 23.02.2021

Jika n Anda kecil, Anda dapat melakukannya secara manual berkat beberapa pengiriman.

julia> f(x) = x + 1   # Method definition for one variable.
f (generic function with 1 method)

julia> f(x, y) = x + y + 1   # Method definition for two variables.
f (generic function with 2 methods)

julia> f(2)
3

julia> f(2, 4)
7

Anda dapat menggunakan pemrograman makro untuk menghasilkan serangkaian metode ini secara otomatis, tetapi hal itu dengan cepat menjadi rumit. Anda mungkin lebih baik menyusun fungsi Anda sehingga beroperasi pada Vector atau Tuple dengan panjang yang berubah-ubah. Definisi fungsi akan bergantung pada apa yang ingin Anda lakukan. Beberapa contoh yang mengharapkan x menjadi Tuple, Vector, atau tipe data serupa lainnya ada di bawah.

julia> g(x) = sum(x)   # Add all the elements
g (generic function with 1 method)

julia> h(x) = x[end - 1]   # Return the second to last element
h (generic function with 1 method)

julia> g([10, 11, 12])
33

julia> h([10, 11, 12])
11

Jika Anda lebih suka fungsi tersebut menerima sejumlah input yang berubah-ubah daripada satu Tuple atau Vector seperti yang Anda tulis di pertanyaan awal, maka Anda harus mendefinisikan metode untuk fungsi tersebut dengan operator slurping ... seperti di bawah ini. Perhatikan bahwa isi definisi fungsi dan keluaran dari fungsi sama persis seperti sebelumnya. Jadi, operator slurping ... hanya untuk kenyamanan sintaksis. Fungsi di bawah ini masih beroperasi pada Tuple x. Argumen fungsi hanya dimasukkan ke dalam Tuple sebelum melakukan hal lain. Perhatikan juga bahwa Anda dapat menentukan metode di atas dan di bawah secara bersamaan sehingga pengguna dapat memilih salah satu metode masukan.

julia> g(x...) = sum(x)   # Add all the variables
g (generic function with 2 methods)

julia> h(x...) = x[end - 1]   # Return the second to last variable
h (generic function with 2 methods)

julia> g(10, 11, 12)
33

julia> h(10, 11, 12)
11

Terakhir, trik lain yang terkadang berguna adalah memanggil suatu fungsi secara rekursif. Dengan kata lain, untuk memanggil fungsi itu sendiri (berpotensi menggunakan metode yang berbeda).

julia> q(x) = 2 * x   # Double the input
q (generic function with 1 method)

julia> q(x...) = q(sum(x)) # Add all the inputs and call the function again on the result
q (generic function with 2 methods)

julia> q(3)
6

julia> q(3, 4, 5)
24
person Nathan Boyer    schedule 23.02.2021