R語言編程數(shù)學(xué)分析重讀微積分微分學(xué)原理運用
1 連續(xù)性
比如下面這個隨機函數(shù)
x = seq(0,0.1,0.01) y = runif(11,0,1) plot(x,y) lines(x,y)
x = seq(0,0.01,0.00001) y = runif(1001,0,1) plot(x,y)
無論我們把區(qū)間縮小到什么程度,這種亂糟糟的仿佛要鋪滿整個坐標(biāo)圖的點的樣式并不會發(fā)生變化。
也就是說, f(x)從左邊趨近于0的時候,f(x)在0處是連續(xù)的,而在右側(cè)趨近于0的時候,卻并不連續(xù)。此即左連續(xù)和右連續(xù)的概念。
2 求導(dǎo)
回到切線的問題,如果曲線 y=f(x)在 x0點并不連續(xù),那么這點顯然沒有唯一的一條切線。
有的時候,盡管滿足了連續(xù)性的要求,也不一定存在切線,比如
y = ∣ x ∣
x = seq(-10,10) y = abs(x) plot(x,y,type='l')
在 x=0的位置,我們找到的切線要么和左邊重合,要么和右邊重合,也就是說這個函數(shù)在x=0處存在兩條切線。
同時也就意味著這一點有兩個斜率,兩個導(dǎo)數(shù)。所以,如果把導(dǎo)數(shù)定義為某種映射,則一個點只能映射為一個值,所以只能定義這點的導(dǎo)數(shù)不存在。
3 數(shù)值導(dǎo)數(shù)
根據(jù)導(dǎo)數(shù)的定義,當(dāng)函數(shù)的定義域不連續(xù)時,其不連續(xù)處顯然是不存在導(dǎo)數(shù)的,但圖形可以“欺騙”我們的眼睛。
> x = seq(-1,1,0.1) > y = sin(x) > y1 = cos(x) > xEnd = x+0.1 > yEnd = y+y1*0.1 > plot(x,y) > for(i in seq_along(x)){ + lines(c(x[i],xEnd[i]),c(y[i],yEnd[i]),col="red") + }
上圖中,圓圈是對y = sinx 進行抽樣的結(jié)果,可以理解為不連續(xù)函數(shù);紅線則是在每一個分立的點上,sinx在該點的切線。這兩者看上去如此一致,說明連續(xù)函數(shù)的導(dǎo)數(shù)在抽樣之后仍然具備一定的數(shù)學(xué)意義。相應(yīng)地,不連續(xù)的函數(shù),也應(yīng)該有類似于導(dǎo)數(shù)一樣的存在,從而與連續(xù)函數(shù)的導(dǎo)數(shù)相對應(yīng),此即數(shù)值導(dǎo)數(shù)。如果回顧導(dǎo)數(shù)的定義
x = seq(-5,5,0.1) y = cos(x) x1 = seq(-5,5,0.1) end = length(x1) y1 = (sin(x1[2:end])-sin(x1[1:end-1]))/0.1 x5 = seq(-5,5,0.5) end = length(x5) y5 = (sin(x5[2:end])-sin(x5[1:end-1]))/0.5 x10 = seq(-5,5,1) end = length(x10) y10 = (sin(x10[2:end])-sin(x10[1:end-1]))/0.5 plot(x,y,type="l",col="red") lines(x1[2:length(x1)],y1) lines(x5[2:length(x5)],y5) lines(x10[2:length(x10)],y10)
如圖所示
由于我們采用的是后向差分,所以三組差商的值整體右移。此外,隨著 h的增大,其誤差也越來越明顯。
對一個函數(shù)進行反復(fù)求導(dǎo),即可得到高階導(dǎo)數(shù),可以用數(shù)學(xué)歸納法的方式記為
4 差商與牛頓插值
根據(jù)這個表達(dá)式,可以通過一個簡單的遞歸程序計算數(shù)組的差商
# 差商算法,x,y為同等長度的數(shù)組 diffDiv<-function(x,y){ end = length(x) ind = 2:end #索引 return( if(end==1) y[1] else (diffDiv(x[ind],y[ind]) -diffDiv(x[ind-1],y[ind-1]))/(x[end]-x[1]) ) }
如果要計算階數(shù)為k的差商,只需重復(fù)調(diào)用diffDiv
,
kDiffDiv <- function(x,y,k){ len <- length(x) if(len<k) return(0) d<-rep(0,len-k) for(i in 1:(len-k)) d[i] <- diffDiv(x[i:(i+k)],y[i:(i+k)]) return(d) }
據(jù)此,繪制出 y=x^5這個函數(shù)的差商,
> plot(x,y) > k = 1 > lines(x[1:(end-k)],kDiffDiv(x,y,k),col="red") > k = 2 > lines(x[1:(end-k)],kDiffDiv(x,y,k),col="green") > k = 3 > lines(x[1:(end-k)],kDiffDiv(x,y,k),col="blue") > k = 4 > lines(x[1:(end-k)],kDiffDiv(x,y,k),col="purple") > k = 5 > lines(x[1:(end-k)],kDiffDiv(x,y,k),col="yellow") > k = 6 > lines(x[1:(end-k)],kDiffDiv(x,y,k),col="gray")
如圖所示
可見差商與微分在階數(shù)上有著一致的趨勢。那么,知道了差商之后,可以做點什么呢?
根據(jù)差商定義,可得
polyMulti<-function(x){ n = length(x) if(n<2) return(c(-x,1)) omega = rep(0,n+1) omega[1] = - x[1] omega[2] = 1 for(i in 2:n){ omega[2:i] = -x[i]*omega[2:i]*+omega[1:(i-1)] omega[1] = -x[i]*omega[1] omega[i+1] = 1 } return(omega) } Newton<-function(x,y){ n = length(x) N = rep(0,n+1) N[1]=y[1] for(i in 1:n){ omega = polyMulti(x[1:i]) d = kDiffDiv(x[1:i],y[1:i],i-1) N[1:i] = N[1:i] + d*omega[1:i] N[i+1] = d*omega[i+1] } return(N) }
驗證一下
x = sort(rnorm(10)) y = x^5+2*x^4 N = Newton(x,y) Y = y*0 for(i in 1:length(Y)) for(j in 1:length(N)) Y[i] = Y[i]+N[j]*x[i]^(j-1) plot(x,y) lines(x,Y)
可見效果還是不錯的。
5 方向?qū)?shù)
現(xiàn)繪制出100個隨機點處x方向的偏導(dǎo)數(shù)
x = matrix(data=seq(-5,4.95,0.05),nrow=200,ncol=200) y = t(x) z = 1-(x^2+y^2) library(rgl) persp3d(x,y,z,col="red") N = 1000 x0 = rnorm(N) y0 = rnorm(N) z0 = 1-(x0^2+y0^2) x1 = x0+3 z1 = -2*x0*3+z0 for(i in 1:N) lines3d(c(x0[i],x1[i]),c(y0[i],y0[i]),c(z0[i],z1[i]),col="green")
從觀感上來看,綠線的確是沿著 x x x方向。但是這個切線顯然不是唯一的, y y y軸方向顯然存在另一條切線。推而廣之,一旦坐標(biāo)系旋轉(zhuǎn),那么曲面上任意一點處的 x和 y方向均會發(fā)生變化。
那么曲面是否存在一個只和曲面特征有關(guān),而與坐標(biāo)系無關(guān)的參數(shù)?
在解決這個問題之前,最好先找到曲面某點沿著任意方向的導(dǎo)數(shù)?;仡?x方向偏導(dǎo)數(shù)的定義
如果導(dǎo)數(shù)的方向發(fā)生旋轉(zhuǎn),則可以寫為
如果寫成矢量形式,則定義梯度
沿這些點梯度方向做一些直線,看看效果如何
x = matrix(data=seq(-5,4.95,0.05),nrow=200,ncol=200) y = t(x) z = -(x^2+y^2) library(rgl) persp3d(x,y,z,col="red") theta = seq(-pi,pi,0.01) x0 = cos(theta) y0 = sin(theta) z0 = 1-(x0^2+y0^2) x1 = x0*0 y1 = y0*0 z1 = z0+2 for(i in 1:N) lines3d(c(x0[i],x1[i]),c(y0[i],y1[i]),c(z0[i],z1[i]),col="green")
如圖所示,像一頂漂亮的帽子,在某個投影方向看去,和我們熟知的切線如出一轍。
6 全微分
做圖如下
theta = seq(-pi,pi,0.1) x = cos(theta) y = sin(theta) plot(x,y,type='l',col='red') x1 = x*0 y1 = (x1-x)/(-2*x)*(-2*y)+y for(i in 1:length(theta)) lines(c(x[i],x1[i]),c(y[i],y1[i]),col='green')
可見,梯度方向?qū)?yīng)的是圖形的法線方向。對于二維平面內(nèi)的曲線而言,其法線方向與切線方向垂直。
回顧偏導(dǎo)數(shù)的定義
7 法線
相應(yīng)地最大方向?qū)?shù)的方向即為梯度的歸一化
現(xiàn)隨機選擇一些點,來繪制一下這四個方向的向量
library(rgl) N = 1500 x<-rnorm(N) y<-rnorm(N) z<-1-x^2-y^2 for(i in 1:N){ lines3d(c(x[i],3*x[i]),c(y[i],3*y[i]),c(z[i],z[i]+1),col='red') if(y[i]>0.1) lines3d(c(x[i],x[i]),c(y[i],y[i]-1/y[i]/2),c(z[i],z[i]+1),col='green') if(x[i]>0.1) lines3d(c(x[i],x[i]-1/x[i]/2),c(y[i],y[i]),c(z[i],z[i]+1),col='green') lines3d(c(x[i],x[i]*(1-2*z[i])/(2-2*z[i])),c(y[i],y[i]*(1-2*z[i])/(2-2*z[i])),c(z[i],z[i]+1),col='green') }
可以看到,綠線幾乎重新編織了一遍原函數(shù),而紅線則刺破了曲面。
8 偏導(dǎo)數(shù)和邊緣檢測
基于偏導(dǎo)數(shù)的邊緣檢測
灰度圖像是天然的z=f(x,y)函數(shù),盡管以一種差分化的形式存在。其中x,y分別代表圖像坐標(biāo)系中的坐標(biāo) z可以表示灰度圖像的灰度值。
那么接下來我們可以觀察一下偏導(dǎo)數(shù)作用在圖像上是一個什么效果。圖片當(dāng)然是最經(jīng)典的lena
library(imager) img = load.image("lena.jpg") dim(img) [1] 512 512 1 3 gray = grayscale(img) par(mfrow=c(1,2)) plot(img) plot(gray)
可見gray
顯然為灰度圖像,從其維度就能看得出來,然后將其變?yōu)槎S的數(shù)組,接下來就可以進行求導(dǎo)操作了。
dim(gray) [1] 512 512 1 1 mat = array(gray,dim=c(512,512)) mat_x = diff(mat,1) mat_y = t(diff(t(mat),1)) par(mfrow=c(1,2)) image(mat_x) image(mat_y)
由于圖像坐標(biāo)系默認(rèn)是從上向下為 y y y軸,從左向右為 x x x軸,所以在我們熟知的坐標(biāo)系中,圖像是上下顛倒的。而且R語言還非常智能(障)地添加了一層偽彩色,這讓我們更加清晰地看出,對圖像進行差分操作,提取出了邊緣信息。
這很容易理解,所謂“邊緣”,往往意味著變化較大的點,如果我們抽取lena圖的任意一行,
a=mat[256,] par(mfrow=c(1,2)) plot(a,type='l') plot(diff(a,1),type='l')
在變化劇烈處,相應(yīng)地導(dǎo)數(shù)較大。
若將偏導(dǎo)數(shù)在圖像空間中展開,由于任意兩個像素點之間的差恒為1,則可得到其差分形式
Roberts算子
求導(dǎo)是對整個函數(shù)的定義域展開的一次性操作,但在考察其差分形式之后卻發(fā)現(xiàn),數(shù)值偏導(dǎo)數(shù)可以寫成一種對局部區(qū)域的反復(fù)操作。
例如,就前向差分而言,可以對圖像的任意一個子矩陣
theta = c(pi/3,pi/4,pi/5,pi/6) par(mfrow=c(2,2)) for(i in 1:4) image(mat_x[,1:511]*cos(theta[i])+mat_y[1:511,]*sin(theta[i]))
可以看到,最后一張圖片的法向角度為 30° ,而其右下角正好有一個 30°附近的清晰的邊緣。
其他算子
如果通過中心差分來定義算子,則統(tǒng)一維度后,其x和 y向的梯度算子分別寫為
以上就是R語言編程數(shù)學(xué)分析重讀微積分微分學(xué)原理運用的詳細(xì)內(nèi)容,更多關(guān)于R語言數(shù)學(xué)分析微分學(xué)原理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
R語言學(xué)習(xí)VennDiagram包繪制韋恩圖示例
這篇文章主要為大家介紹了R語言學(xué)習(xí)VennDiagram包繪制韋恩圖示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06R包clusterProfiler如何安裝成功(新手必看!)
最近在我以為ClusterProfiler已經(jīng)安裝好的時候,又遇到了一些問題,所以這篇文章主要給大家介紹了關(guān)于R包clusterProfiler如何安裝成功的相關(guān)資料,需要的朋友可以參考下2023-02-02R語言基于Keras的MLP神經(jīng)網(wǎng)絡(luò)及環(huán)境搭建
這篇文章主要介紹了R語言基于Keras的MLP神經(jīng)網(wǎng)絡(luò),我并沒有使用python去對比結(jié)果,但NSS的文章中有做對比,數(shù)據(jù)顯示R與Python相比在各方面的差別都不大,具體內(nèi)容介紹跟隨小編一起看看吧2022-01-01