2017-06-22 89 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!