Anda perlu menggunakan Sympy: sympy.org/en/index.html Numpy adalah pustaka komputasi numerik untuk Python
prrao
Atau, apakah Anda menginginkan metode untuk memperkirakan nilai numerik dari turunan? Untuk ini, Anda dapat menggunakan metode perbedaan hingga, tetapi perlu diingat bahwa metode tersebut cenderung sangat berisik.
Perbedaan terbatas tidak memerlukan alat eksternal tetapi rentan terhadap kesalahan numerik dan, jika Anda berada dalam situasi multivarian, dapat memakan waktu cukup lama.
Diferensiasi simbolik ideal jika masalah Anda cukup sederhana. Metode simbolis semakin kuat belakangan ini. SymPy adalah proyek luar biasa untuk ini yang terintegrasi dengan baik dengan NumPy. Lihat fungsi autowrap atau lambdify atau lihat posting blog Jensen tentang pertanyaan serupa .
Turunan otomatis sangat keren, tidak rentan terhadap kesalahan numerik, tetapi memerlukan beberapa pustaka tambahan (untuk ini google, ada beberapa opsi bagus). Ini adalah pilihan yang paling kuat tetapi juga yang paling canggih / sulit untuk diatur. Jika Anda baik-baik saja membatasi diri Anda pada numpysintaks, maka Theano mungkin pilihan yang baik.
Berikut ini contoh penggunaan SymPy
In [1]: from sympy import *
In [2]: import numpy as np
In [3]: x = Symbol('x')
In [4]: y = x**2 + 1
In [5]: yprime = y.diff(x)
In [6]: yprime
Out[6]: 2⋅x
In [7]: f = lambdify(x, yprime, 'numpy')
In [8]: f(np.ones(5))
Out[8]: [ 2.2.2.2.2.]
Maaf, jika ini terlihat bodoh, Apa perbedaan antara 3. Diferensiasi Simbolik dan 4. Diferensiasi tangan ??
DrStrangeLove
11
Ketika saya mengatakan "diferensiasi simbolis", saya bermaksud menyiratkan bahwa proses tersebut ditangani oleh komputer. Pada prinsipnya 3 dan 4 hanya berbeda dalam hal siapa yang mengerjakan, komputer atau pemrogramnya. 3 lebih disukai daripada 4 karena konsistensi, skalabilitas, dan kemalasan. 4 diperlukan jika 3 gagal menemukan solusi.
MRocklin
4
Di baris 7 kita membuat f, sebuah fungsi yang menghitung turunan dari y wrt x. Dalam 8 kita menerapkan fungsi turunan ini ke vektor dari semua satu dan mendapatkan vektor dari semua berpasangan. Ini karena, seperti yang dinyatakan pada baris 6, yprime = 2 * x.
MRocklin
Hanya demi kelengkapan, Anda juga dapat melakukan diferensiasi dengan integrasi (lihat rumus integral Cauchy), itu diimplementasikan misalnya di mpmath(tidak yakin apa yang mereka lakukan).
DerWeh
Apakah ada cara mudah untuk melakukan perbedaan terbatas di numpy tanpa menerapkannya sendiri? misalnya saya ingin mencari gradien fungsi pada titik-titik yang telah ditentukan.
Alex
43
Cara paling mudah yang dapat saya pikirkan adalah menggunakan fungsi gradien numpy :
x = numpy.linspace(0,10,1000)
dx = x[1]-x[0]
y = x**2 + 1
dydx = numpy.gradient(y, dx)
Dengan cara ini, dydx akan dihitung menggunakan perbedaan pusat dan akan memiliki panjang yang sama dengan y, tidak seperti numpy.diff, yang menggunakan perbedaan maju dan akan mengembalikan vektor ukuran (n-1).
@ weberc2, dalam hal ini Anda harus membagi satu vektor dengan vektor lainnya, tetapi perlakukan tepinya secara terpisah dengan turunan maju dan mundur secara manual.
Sparkler
2
Atau Anda dapat menginterpolasi y dengan konstanta dx, lalu menghitung gradiennya.
IceArdor
@Sparkler Terima kasih atas saran Anda. Jika saya boleh mengajukan 2 pertanyaan kecil, (i) mengapa kita lolos dxke numpy.gradientalih-alih x? (ii) Bisakah kita juga melakukan baris terakhir dari Anda sebagai berikut: dydx = numpy.gradient(y, numpy.gradient(x))?
user929304
2
Mulai v1.13, spasi yang tidak seragam dapat ditentukan menggunakan array sebagai argumen kedua. Lihat bagian Contoh di halaman ini .
Nathaniel Jones
28
NumPy tidak menyediakan fungsionalitas umum untuk menghitung turunan. Ia dapat menangani kasus khusus polinomial sederhana namun:
>>> p = numpy.poly1d([1, 0, 1])
>>> print p
21 x + 1>>> q = p.deriv()
>>> print q
2 x
>>> q(5)
10
Jika Anda ingin menghitung turunan secara numerik, Anda dapat menggunakan kuosien perbedaan pusat untuk sebagian besar aplikasi. Untuk turunan dalam satu titik, rumusnya akan seperti ini
'Menghitung turunan numerik untuk kasus yang lebih umum itu mudah' - Saya mohon berbeda, menghitung turunan numerik untuk kasus umum cukup sulit. Anda baru saja memilih fungsi yang berperilaku baik.
Performa Tinggi Mark
apa artinya 2 setelah >>> print p ?? (pada baris ke-2)
DrStrangeLove
@DrStrangeLove: Itu eksponennya. Ini dimaksudkan untuk mensimulasikan notasi matematika.
Sven Marnach
@Svenarnach apakah itu eksponen maksimum ?? atau apa?? Mengapa menurutnya eksponen adalah 2 ?? Kami hanya
memasukkan
2
@DrStrangeLove: Outputnya seharusnya dibaca sebagai 1 * x**2 + 1. Mereka meletakkan 2di baris di atas karena eksponennya. Lihatlah dari kejauhan.
Sven Marnach
15
Dengan asumsi Anda ingin menggunakan numpy, Anda dapat menghitung turunan suatu fungsi secara numerik pada titik mana pun menggunakan definisi Ketelitian :
defd_fun(x):
h = 1e-5#in theory h is an infinitesimalreturn (fun(x+h)-fun(x))/h
Anda juga dapat menggunakan turunan Symmetric untuk hasil yang lebih baik:
defd_fun(x):
h = 1e-5return (fun(x+h)-fun(x-h))/(2*h)
Menggunakan contoh Anda, kode lengkap akan terlihat seperti ini:
deffun(x):return x**2 + 1defd_fun(x):
h = 1e-5return (fun(x+h)-fun(x-h))/(2*h)
Sekarang, Anda dapat menemukan turunannya secara numerik di x=5:
scipy.interpolateBanyak splines interpolasi mampu menghasilkan turunan. Jadi, dengan menggunakan spline linier ( k=1), turunan dari spline (menggunakan derivative()metode) harus setara dengan perbedaan maju. Saya tidak sepenuhnya yakin, tapi saya percaya menggunakan turunan spline kubik akan mirip dengan turunan perbedaan terpusat karena menggunakan nilai dari sebelum dan sesudah untuk membuat spline kubik.
from scipy.interpolate import InterpolatedUnivariateSpline
# Get a function that evaluates the linear spline at any x
f = InterpolatedUnivariateSpline(x, y, k=1)
# Get a function that evaluates the derivative of the linear spline at any x
dfdx = f.derivative()
# Evaluate the derivative dydx at each x location...
dydx = dfdx(x)
baru saja mencoba ini, saya terus mendapatkan kesalahan dari fungsi ini AxisError: sumbu -1 di luar batas untuk array dimensi 0 dan saya juga tidak melihat jawaban untuk ini di komunitas, ada bantuan?
Ayan Mitra
Poskan masalah Anda sebagai pertanyaan baru dan tautkan ke sini. Memberikan contoh yang menyebabkan kesalahan Anda mungkin akan dibutuhkan. Kesalahan yang saya miliki dengan fungsi interp biasanya karena datanya tidak terbentuk dengan baik - seperti nilai yang berulang, jumlah dimensi yang salah, salah satu array tidak sengaja kosong, data tidak diurutkan terhadap x atau ketika diurutkan bukan a fungsi yang valid, dll. Mungkin saja scipy salah memanggil numpy, tetapi sangat tidak mungkin. Centang x.shape dan y.shape. Lihat apakah np.interp () berfungsi - ini mungkin memberikan kesalahan yang lebih berguna jika tidak.
flutefreak7
6
Untuk menghitung gradien, komunitas pembelajaran mesin menggunakan Autograd:
Jawaban:
Anda memiliki empat opsi
Perbedaan terbatas tidak memerlukan alat eksternal tetapi rentan terhadap kesalahan numerik dan, jika Anda berada dalam situasi multivarian, dapat memakan waktu cukup lama.
Diferensiasi simbolik ideal jika masalah Anda cukup sederhana. Metode simbolis semakin kuat belakangan ini. SymPy adalah proyek luar biasa untuk ini yang terintegrasi dengan baik dengan NumPy. Lihat fungsi autowrap atau lambdify atau lihat posting blog Jensen tentang pertanyaan serupa .
Turunan otomatis sangat keren, tidak rentan terhadap kesalahan numerik, tetapi memerlukan beberapa pustaka tambahan (untuk ini google, ada beberapa opsi bagus). Ini adalah pilihan yang paling kuat tetapi juga yang paling canggih / sulit untuk diatur. Jika Anda baik-baik saja membatasi diri Anda pada
numpy
sintaks, maka Theano mungkin pilihan yang baik.Berikut ini contoh penggunaan SymPy
In [1]: from sympy import * In [2]: import numpy as np In [3]: x = Symbol('x') In [4]: y = x**2 + 1 In [5]: yprime = y.diff(x) In [6]: yprime Out[6]: 2⋅x In [7]: f = lambdify(x, yprime, 'numpy') In [8]: f(np.ones(5)) Out[8]: [ 2. 2. 2. 2. 2.]
sumber
mpmath
(tidak yakin apa yang mereka lakukan).Cara paling mudah yang dapat saya pikirkan adalah menggunakan fungsi gradien numpy :
x = numpy.linspace(0,10,1000) dx = x[1]-x[0] y = x**2 + 1 dydx = numpy.gradient(y, dx)
Dengan cara ini, dydx akan dihitung menggunakan perbedaan pusat dan akan memiliki panjang yang sama dengan y, tidak seperti numpy.diff, yang menggunakan perbedaan maju dan akan mengembalikan vektor ukuran (n-1).
sumber
dx
kenumpy.gradient
alih-alihx
? (ii) Bisakah kita juga melakukan baris terakhir dari Anda sebagai berikut:dydx = numpy.gradient(y, numpy.gradient(x))
?NumPy tidak menyediakan fungsionalitas umum untuk menghitung turunan. Ia dapat menangani kasus khusus polinomial sederhana namun:
>>> p = numpy.poly1d([1, 0, 1]) >>> print p 2 1 x + 1 >>> q = p.deriv() >>> print q 2 x >>> q(5) 10
Jika Anda ingin menghitung turunan secara numerik, Anda dapat menggunakan kuosien perbedaan pusat untuk sebagian besar aplikasi. Untuk turunan dalam satu titik, rumusnya akan seperti ini
x = 5.0 eps = numpy.sqrt(numpy.finfo(float).eps) * (1.0 + x) print (p(x + eps) - p(x - eps)) / (2.0 * eps * x)
jika Anda memiliki larik
x
absis dengan lariky
nilai fungsi yang sesuai , Anda dapat menghitung perkiraan turunan dengansumber
1 * x**2 + 1
. Mereka meletakkan2
di baris di atas karena eksponennya. Lihatlah dari kejauhan.Dengan asumsi Anda ingin menggunakan
numpy
, Anda dapat menghitung turunan suatu fungsi secara numerik pada titik mana pun menggunakan definisi Ketelitian :def d_fun(x): h = 1e-5 #in theory h is an infinitesimal return (fun(x+h)-fun(x))/h
Anda juga dapat menggunakan turunan Symmetric untuk hasil yang lebih baik:
def d_fun(x): h = 1e-5 return (fun(x+h)-fun(x-h))/(2*h)
Menggunakan contoh Anda, kode lengkap akan terlihat seperti ini:
def fun(x): return x**2 + 1 def d_fun(x): h = 1e-5 return (fun(x+h)-fun(x-h))/(2*h)
Sekarang, Anda dapat menemukan turunannya secara numerik di
x=5
:In [1]: d_fun(5) Out[1]: 9.999999999621423
sumber
Saya akan melempar metode lain ke tumpukan ...
scipy.interpolate
Banyak splines interpolasi mampu menghasilkan turunan. Jadi, dengan menggunakan spline linier (k=1
), turunan dari spline (menggunakanderivative()
metode) harus setara dengan perbedaan maju. Saya tidak sepenuhnya yakin, tapi saya percaya menggunakan turunan spline kubik akan mirip dengan turunan perbedaan terpusat karena menggunakan nilai dari sebelum dan sesudah untuk membuat spline kubik.from scipy.interpolate import InterpolatedUnivariateSpline # Get a function that evaluates the linear spline at any x f = InterpolatedUnivariateSpline(x, y, k=1) # Get a function that evaluates the derivative of the linear spline at any x dfdx = f.derivative() # Evaluate the derivative dydx at each x location... dydx = dfdx(x)
sumber
Untuk menghitung gradien, komunitas pembelajaran mesin menggunakan Autograd:
Untuk memasang:
Berikut ini contohnya:
import autograd.numpy as np from autograd import grad def fct(x): y = x**2+1 return y grad_fct = grad(fct) print(grad_fct(1.0))
Ia juga dapat menghitung gradien fungsi kompleks, misalnya fungsi multivariasi.
sumber
Bergantung pada tingkat presisi yang Anda butuhkan, Anda dapat mengerjakannya sendiri, menggunakan bukti diferensiasi sederhana:
>>> (((5 + 0.1) ** 2 + 1) - ((5) ** 2 + 1)) / 0.1 10.09999999999998 >>> (((5 + 0.01) ** 2 + 1) - ((5) ** 2 + 1)) / 0.01 10.009999999999764 >>> (((5 + 0.0000000001) ** 2 + 1) - ((5) ** 2 + 1)) / 0.0000000001 10.00000082740371
kita tidak bisa benar-benar mengambil batas gradien, tapi ini agak menyenangkan. Anda harus berhati-hati karena
>>> (((5+0.0000000000000001)**2+1)-((5)**2+1))/0.0000000000000001 0.0
sumber
Anda dapat menggunakan
scipy
, yang sangat mudah:scipy.misc.derivative(func, x0, dx=1.0, n=1, args=(), order=3)
Dalam kasus Anda:
from scipy.misc import derivative def f(x): return x**2 + 1 derivative(f, 5, dx=1e-6) # 10.00000000139778
sumber