2017-06-22 92 views
1

我正在重寫一個我在R中爲C++所做的算法,稱爲有限差分方法。我對R很新,所以我不知道有關向量/矩陣乘法的所有規則。出於某種原因,我得到一個是非柔順的參數錯誤,當我這樣做:R中的不可整合參數

ST_u <- matrix(0,M,1) 
    ST_l <- matrix(0,M,1) 
    for(i in 1:M){ 
    Z <- matrix(gaussian_box_muller(i),M,1) 
    ST_u[i] <- (S0 + delta_S)*exp((r - (sigma*sigma)/(2.0))*T + sigma*sqrt(T)%*%Z) 
    ST_l[i] <- (S0 - delta_S)*exp((r - (sigma*sigma)/(2.0))*T + sigma*sqrt(T)%*%Z) 
    } 

我得到這個錯誤:

Error in sqrt(T) %*% Z : non-conformable arguments 

這裏是我的全部代碼:

gaussian_box_muller <- function(n){ 
    theta <- runif(n, 0, 2 * pi) 
    rsq <- rexp(n, 0.5) 
    x <- sqrt(rsq) * cos(theta) 
    return(x) 
} 

d_j <- function(j, S, K, r, v,T) { 
    return ((log(S/K) + (r + (-1^(j-1))*0.5*v*v)*T)/(v*(T^0.5))) 
} 

call_delta <- function(S,K,r,v,T){ 
    return (S * dnorm(d_j(1, S, K, r, v, T))-K*exp(-r*T) * dnorm(d_j(2, S, K, r, v, T))) 
} 


Finite_Difference <- function(S0,K,r,sigma,T,M,delta_S){ 
    ST_u <- matrix(0,M,1) 
    ST_l <- matrix(0,M,1) 
    for(i in 1:M){ 
    Z <- matrix(gaussian_box_muller(i),M,1) 
    ST_u[i] <- (S0 + delta_S)*exp((r - (sigma*sigma)/(2.0))*T + sigma*sqrt(T)%*%Z) 
    ST_l[i] <- (S0 - delta_S)*exp((r - (sigma*sigma)/(2.0))*T + sigma*sqrt(T)%*%Z) 
    } 

    Delta <- matrix(0,M,1) 
    totDelta <- 0 
    for(i in 1:M){ 
    if(ST_u[i] - K > 0 && ST_l[i] - K > 0){ 
     Delta[i] <- ((ST_u[i] - K) - (ST_l[i] - K))/(2*delta_S) 
    }else{ 
     Delta <- 0 
    } 
    totDelta = totDelta + exp(-r*T)*Delta[i] 
    } 
    totDelta <- totDelta * 1/M 

    Var <- 0 
    for(i in 1:M){ 
    Var = Var + (Delta[i] - totDelta)^2 
    } 
    Var = Var*1/M 
    cat("The Finite Difference Delta is : ", totDelta) 
    call_Delta_a <- call_delta(S,K,r,sigma,T) 
    bias <- abs(call_Delta_a - totDelta) 
    cat("The bias is: ", bias) 
    cat("The Variance of the Finite Difference method is: ", Var) 
    MSE <- bias*bias + Var 
    cat("The marginal squared error is thus: ", MSE) 
} 

S0 <- 100.0      
delta_S <- 0.001  
K <- 100.0   
r <- 0.05       
sigma <- 0.2      
T <- 1.0        
M <- 10 

result1 <- Finite_Difference(S0,K,r,sigma,T,M,delta_S) 

我似乎無法找出問題,任何建議將不勝感激。

+0

好的,我應該試試'*'嗎? – Wolfy

+1

考慮到你的函數非常「循環繁重」,可能值得考慮將函數作爲C++代碼,並且使用'library(Rcpp)直接從R中調用它「 – SymbolixAU

回答

3

在R中,%*%算子被保留用於乘以兩個一致矩陣。作爲一種特殊情況,如果可以將向量視爲符合矩陣的行或列向量,也可以使用它將向量乘以矩陣(反之亦然);作爲第二種特殊情況,它可以用來乘以兩個向量來計算它們的內積。

但是,有一件事不能 do是執行標量乘。向量或矩陣的標量乘法總是使用簡單的運算符。具體而言,在表達式sqrt(T) %*% Z中,第一項sqrt(T)是標量,而第二項Z是矩陣。如果您打算在此處執行的操作是將矩陣Z乘以標量sqrt(T),則應將其寫爲sqrt(T) * Z

當我做了這個改變,你的程序仍然沒有工作,因爲另一個bug - S被使用,但從未定義 - 但我不明白你的算法足夠好,試圖修復。

在不直接關係到你原來的問題程序的一些其他意見:

  1. Finite_Difference第一個循環看起來很可疑:guassian_box_muller(i)產生的i長度i的載體從1了在循環變化到M,並強制這些向量爲長度爲M的列矩陣生成Z可能沒有做你想做的。它將「重用」週期中的值來填充矩陣。試試這些,看看我的意思是:

    matrix(gaussian_box_muller(1),10,1) # all one value 
    matrix(gaussian_box_muller(3),10,1) # cycle of three values 
    
  2. 您也可以用在很多地方循環,其中R的矢量操作會更容易閱讀和(通常情況下)更快地執行。例如,你的Var定義等同於:

    Var <- sum((Delta - totDelta)^2)/M 
    

    DeltatotDelta的定義也可以在這個簡化的方式編寫的。

    我建議谷歌搜索「r中的矢量和矩陣操作」或類似的東西,閱讀一些教程。矢量算術尤其是慣用的R,你會想早點學習並經常使用它。

  3. 您可能會考慮使用rnorm函數來生成隨機高斯。

Happy Ring!