Wolfy
Wolfy

Reputation: 458

Non-comformable arguments in R

I am re-writting an algorithm I did in C++ in R for practice called the Finite Difference Method. I am pretty new with R so I don't know all the rules regarding vector/matrix multiplication. For some reason I am getting a non-conformable arguments error when I do this:

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)
  }

I get this error:

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

Here is my whole code:

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)

I can't seem to figure out the problem, any suggestions would be greatly appreciated.

Upvotes: 1

Views: 2092

Answers (1)

K. A. Buhr
K. A. Buhr

Reputation: 50829

In R, the %*% operator is reserved for multiplying two conformable matrices. As one special case, you can also use it to multiply a vector by a matrix (or vice versa), if the vector can be treated as a row or column vector that conforms to the matrix; as a second special case, it can be used to multiply two vectors to calculate their inner product.

However, one thing it cannot do is perform scalar multipliciation. Scalar multiplication of vectors or matrices always uses the plain * operator. Specifically, in the expression sqrt(T) %*% Z, the first term sqrt(T) is a scalar, and the second Z is a matrix. If what you intend to do here is multiply the matrix Z by the scalar sqrt(T), then this should just be written sqrt(T) * Z.

When I made this change, your program still didn't work because of another bug -- S is used but never defined -- but I don't understand your algorithm well enough to attempt a fix.

A few other comments on the program not directly related to your original question:

  1. The first loop in Finite_Difference looks suspicious: guassian_box_muller(i) generates a vector of length i as i varies in the loop from 1 up to M, and forcing these vectors into a column matrix of length M to generate Z is probably not doing what you want. It will "reuse" the values in a cycle to populate the matrix. Try these to see what I mean:

    matrix(gaussian_box_muller(1),10,1)   # all one value
    matrix(gaussian_box_muller(3),10,1)   # cycle of three values
    
  2. You also use loops in many places where R's vector operations would be easier to read and (typically) faster to execute. For example, your definition of Var is equivalent to:

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

    and the definitions of Delta and totDelta could also be written in this simplified fashion.

    I'd suggest Googling for "vector and matrix operations in r" or something similar and reading some tutorials. Vector arithmetic in particular is idiomatic R, and you'll want to learn it early and use it often.

  3. You might find it helpful to consider the rnorm function to generate random Gaussians.

Happy R-ing!

Upvotes: 3

Related Questions