How to vectorize this function

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

How to vectorize this function

Lynette Chang
Hello everyone,

     I’ve a function with five input argument and one output number.
          impVolC <- function(callM, K, T, F, r)

     I hope this function can take five vectors as input, then return one vector as output. My vectorization ran into problems with the nested if-else operation. As a result, I have to write another for loop to call this function. Can anyone suggest some methods to overcome it? I put my code below, thanks.

impVolC <- function(callM, K, T, F, r){


 if(y >= 0){
     call0 <- K*exp(-r*T)*(exp(y)*polya(sqrt(2*y)) - 0.5)
     if(callM <= call0){
       sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
     }else{
       sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
     }
 }else{
     call0 <- K*exp(-r*T)*(exp(y)/2 - polya(-sqrt(-2*y)))
     if(callM <= call0){
       sig <- 1/sqrt(T)*(-sqrt(gamma + y) + sqrt(gamma - y))
     }else{
       sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
     }
 }
 sig
}

for(i in 1:length(call)){
 sigV[i] <- impVolC(callM = call[i], K = df$Strike[i], T = T, F = F, r = r_m)  
}

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: How to vectorize this function

David Carlson
Your function takes an argument "F" that is never used and uses an object "y" which is not defined. Give us some data to use for testing different approaches along with the answer you expect. It may be possible to use two ifelse() functions instead of the loop.

----------------------------------------
David L Carlson
Department of Anthropology
Texas A&M University
College Station, TX 77843-4352

-----Original Message-----
From: R-help <[hidden email]> On Behalf Of Lynette Chang
Sent: Thursday, September 20, 2018 10:09 AM
To: [hidden email]
Subject: [R] How to vectorize this function

Hello everyone,

     I’ve a function with five input argument and one output number.
          impVolC <- function(callM, K, T, F, r)

     I hope this function can take five vectors as input, then return one vector as output. My vectorization ran into problems with the nested if-else operation. As a result, I have to write another for loop to call this function. Can anyone suggest some methods to overcome it? I put my code below, thanks.

impVolC <- function(callM, K, T, F, r){


 if(y >= 0){
     call0 <- K*exp(-r*T)*(exp(y)*polya(sqrt(2*y)) - 0.5)
     if(callM <= call0){
       sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
     }else{
       sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
     }
 }else{
     call0 <- K*exp(-r*T)*(exp(y)/2 - polya(-sqrt(-2*y)))
     if(callM <= call0){
       sig <- 1/sqrt(T)*(-sqrt(gamma + y) + sqrt(gamma - y))
     }else{
       sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
     }
 }
 sig
}

for(i in 1:length(call)){
 sigV[i] <- impVolC(callM = call[i], K = df$Strike[i], T = T, F = F, r = r_m) }

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: How to vectorize this function

Bert Gunter-2
Also:

What package does polya() come from and "gamma" (as a numeric value)is
undefined (it is a function).


Bert Gunter

"The trouble with having an open mind is that people keep coming along and
sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )


On Thu, Sep 20, 2018 at 9:06 AM David L Carlson <[hidden email]> wrote:

> Your function takes an argument "F" that is never used and uses an object
> "y" which is not defined. Give us some data to use for testing different
> approaches along with the answer you expect. It may be possible to use two
> ifelse() functions instead of the loop.
>
> ----------------------------------------
> David L Carlson
> Department of Anthropology
> Texas A&M University
> College Station, TX 77843-4352
>
> -----Original Message-----
> From: R-help <[hidden email]> On Behalf Of Lynette Chang
> Sent: Thursday, September 20, 2018 10:09 AM
> To: [hidden email]
> Subject: [R] How to vectorize this function
>
> Hello everyone,
>
>      I’ve a function with five input argument and one output number.
>           impVolC <- function(callM, K, T, F, r)
>
>      I hope this function can take five vectors as input, then return one
> vector as output. My vectorization ran into problems with the nested
> if-else operation. As a result, I have to write another for loop to call
> this function. Can anyone suggest some methods to overcome it? I put my
> code below, thanks.
>
> impVolC <- function(callM, K, T, F, r){
>
>
>  if(y >= 0){
>      call0 <- K*exp(-r*T)*(exp(y)*polya(sqrt(2*y)) - 0.5)
>      if(callM <= call0){
>        sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>      }else{
>        sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
>      }
>  }else{
>      call0 <- K*exp(-r*T)*(exp(y)/2 - polya(-sqrt(-2*y)))
>      if(callM <= call0){
>        sig <- 1/sqrt(T)*(-sqrt(gamma + y) + sqrt(gamma - y))
>      }else{
>        sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
>      }
>  }
>  sig
> }
>
> for(i in 1:length(call)){
>  sigV[i] <- impVolC(callM = call[i], K = df$Strike[i], T = T, F = F, r =
> r_m) }
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: How to vectorize this function

R help mailing list-2
In reply to this post by Lynette Chang
In addition to what the other said, if callM is a vector then an expression of the form
   if (callM <= call0)
is inappropriate. Objects inside the parentheses of   if()  should have length one. For example,

> if (1:5 < 3) 'a' else 'b'
[1] "a"
Warning message:
In if (1:5 < 3) "a" else "b" :
  the condition has length > 1 and only the first element will be used


instead of what you have:
         if(callM <= call0){
           sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
         }else{
           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
        }

Here are a couple of (untested) possibilities:

  M.gt.0 <- callM > call0
  sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
  sig[M.gt.0] <- (1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y)))[M.gt.0]

or

    sig <- 1/sqrt(T)*(sqrt(gamma + y)  + ifelse(callM <= call0, -1, 1) * sqrt(gamma - y))

incidentally, I would write
   sig <- (sqrt(gamma + y) - sqrt(gamma - y))/sqrt(T)
instead of
   sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))

--
Don MacQueen
Lawrence Livermore National Laboratory
7000 East Ave., L-627
Livermore, CA 94550
925-423-1062
Lab cell 925-724-7509
 
 

On 9/20/18, 8:08 AM, "R-help on behalf of Lynette Chang" <[hidden email] on behalf of [hidden email]> wrote:

    Hello everyone,
   
         I’ve a function with five input argument and one output number.
     impVolC <- function(callM, K, T, F, r)
   
         I hope this function can take five vectors as input, then return one vector as output. My vectorization ran into problems with the nested if-else operation. As a result, I have to write another for loop to call this function. Can anyone suggest some methods to overcome it? I put my code below, thanks.
   
    impVolC <- function(callM, K, T, F, r){
   
   
     if(y >= 0){
         call0 <- K*exp(-r*T)*(exp(y)*polya(sqrt(2*y)) - 0.5)
         if(callM <= call0){
           sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
         }else{
           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
         }
     }else{
         call0 <- K*exp(-r*T)*(exp(y)/2 - polya(-sqrt(-2*y)))
         if(callM <= call0){
           sig <- 1/sqrt(T)*(-sqrt(gamma + y) + sqrt(gamma - y))
         }else{
           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
         }
     }
     sig
    }
   
    for(i in 1:length(call)){
     sigV[i] <- impVolC(callM = call[i], K = df$Strike[i], T = T, F = F, r = r_m)  
    }
   
    ______________________________________________
    [hidden email] mailing list -- To UNSUBSCRIBE and more, see
    https://stat.ethz.ch/mailman/listinfo/r-help
    PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
    and provide commented, minimal, self-contained, reproducible code.
   

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: How to vectorize this function

Jeff Newmiller
re: your last comment... why do you prefer to multiply by the reciprocal?

On September 20, 2018 10:56:22 AM PDT, "MacQueen, Don via R-help" <[hidden email]> wrote:

>In addition to what the other said, if callM is a vector then an
>expression of the form
>   if (callM <= call0)
>is inappropriate. Objects inside the parentheses of   if()  should have
>length one. For example,
>
>> if (1:5 < 3) 'a' else 'b'
>[1] "a"
>Warning message:
>In if (1:5 < 3) "a" else "b" :
>  the condition has length > 1 and only the first element will be used
>
>
>instead of what you have:
>         if(callM <= call0){
>           sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>         }else{
>           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
>        }
>
>Here are a couple of (untested) possibilities:
>
>  M.gt.0 <- callM > call0
>  sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
> sig[M.gt.0] <- (1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y)))[M.gt.0]
>
>or
>
>sig <- 1/sqrt(T)*(sqrt(gamma + y)  + ifelse(callM <= call0, -1, 1) *
>sqrt(gamma - y))
>
>incidentally, I would write
>   sig <- (sqrt(gamma + y) - sqrt(gamma - y))/sqrt(T)
>instead of
>   sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>
>--
>Don MacQueen
>Lawrence Livermore National Laboratory
>7000 East Ave., L-627
>Livermore, CA 94550
>925-423-1062
>Lab cell 925-724-7509
>
>
>
>On 9/20/18, 8:08 AM, "R-help on behalf of Lynette Chang"
><[hidden email] on behalf of [hidden email]> wrote:
>
>    Hello everyone,
>    
>       I’ve a function with five input argument and one output number.
>      impVolC <- function(callM, K, T, F, r)
>    
>I hope this function can take five vectors as input, then return one
>vector as output. My vectorization ran into problems with the nested
>if-else operation. As a result, I have to write another for loop to
>call this function. Can anyone suggest some methods to overcome it? I
>put my code below, thanks.
>    
>    impVolC <- function(callM, K, T, F, r){
>    
>    
>     if(y >= 0){
>         call0 <- K*exp(-r*T)*(exp(y)*polya(sqrt(2*y)) - 0.5)
>         if(callM <= call0){
>           sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>         }else{
>           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
>         }
>     }else{
>         call0 <- K*exp(-r*T)*(exp(y)/2 - polya(-sqrt(-2*y)))
>         if(callM <= call0){
>           sig <- 1/sqrt(T)*(-sqrt(gamma + y) + sqrt(gamma - y))
>         }else{
>           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
>         }
>     }
>     sig
>    }
>    
>    for(i in 1:length(call)){
>sigV[i] <- impVolC(callM = call[i], K = df$Strike[i], T = T, F = F, r =
>r_m)  
>    }
>    
>    ______________________________________________
>    [hidden email] mailing list -- To UNSUBSCRIBE and more, see
>    https://stat.ethz.ch/mailman/listinfo/r-help
>PLEASE do read the posting guide
>http://www.R-project.org/posting-guide.html
>    and provide commented, minimal, self-contained, reproducible code.
>    
>
>______________________________________________
>[hidden email] mailing list -- To UNSUBSCRIBE and more, see
>https://stat.ethz.ch/mailman/listinfo/r-help
>PLEASE do read the posting guide
>http://www.R-project.org/posting-guide.html
>and provide commented, minimal, self-contained, reproducible code.

--
Sent from my phone. Please excuse my brevity.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: How to vectorize this function

R help mailing list-2
You're asking me?

I prefer
> 4/2
[1] 2

not
> 1/2*4
[1] 2

(I think that's what I said)

And if I did want to multiply by the reciprocal, which does happen from time to time, I'd certainly do it this way:
   (1/2)*4

-Don

--
Don MacQueen
Lawrence Livermore National Laboratory
7000 East Ave., L-627
Livermore, CA 94550
925-423-1062
Lab cell 925-724-7509
 
 

On 9/20/18, 12:36 PM, "Jeff Newmiller" <[hidden email]> wrote:

    re: your last comment... why do you prefer to multiply by the reciprocal?
   
    On September 20, 2018 10:56:22 AM PDT, "MacQueen, Don via R-help" <[hidden email]> wrote:
    >In addition to what the other said, if callM is a vector then an
    >expression of the form
    >   if (callM <= call0)
    >is inappropriate. Objects inside the parentheses of   if()  should have
    >length one. For example,
    >
    >> if (1:5 < 3) 'a' else 'b'
    >[1] "a"
    >Warning message:
    >In if (1:5 < 3) "a" else "b" :
    >  the condition has length > 1 and only the first element will be used
    >
    >
    >instead of what you have:
    >         if(callM <= call0){
    >           sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
    >         }else{
    >           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
    >        }
    >
    >Here are a couple of (untested) possibilities:
    >
    >  M.gt.0 <- callM > call0
    >  sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
    > sig[M.gt.0] <- (1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y)))[M.gt.0]
    >
    >or
    >
    >sig <- 1/sqrt(T)*(sqrt(gamma + y)  + ifelse(callM <= call0, -1, 1) *
    >sqrt(gamma - y))
    >
    >incidentally, I would write
    >   sig <- (sqrt(gamma + y) - sqrt(gamma - y))/sqrt(T)
    >instead of
    >   sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
    >
    >--
    >Don MacQueen
    >Lawrence Livermore National Laboratory
    >7000 East Ave., L-627
    >Livermore, CA 94550
    >925-423-1062
    >Lab cell 925-724-7509
    >
    >
    >
    >On 9/20/18, 8:08 AM, "R-help on behalf of Lynette Chang"
    ><[hidden email] on behalf of [hidden email]> wrote:
    >
    >    Hello everyone,
    >    
    >       I’ve a function with five input argument and one output number.
    >      impVolC <- function(callM, K, T, F, r)
    >    
    >I hope this function can take five vectors as input, then return one
    >vector as output. My vectorization ran into problems with the nested
    >if-else operation. As a result, I have to write another for loop to
    >call this function. Can anyone suggest some methods to overcome it? I
    >put my code below, thanks.
    >    
    >    impVolC <- function(callM, K, T, F, r){
    >    
    >    
    >     if(y >= 0){
    >         call0 <- K*exp(-r*T)*(exp(y)*polya(sqrt(2*y)) - 0.5)
    >         if(callM <= call0){
    >           sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
    >         }else{
    >           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
    >         }
    >     }else{
    >         call0 <- K*exp(-r*T)*(exp(y)/2 - polya(-sqrt(-2*y)))
    >         if(callM <= call0){
    >           sig <- 1/sqrt(T)*(-sqrt(gamma + y) + sqrt(gamma - y))
    >         }else{
    >           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
    >         }
    >     }
    >     sig
    >    }
    >    
    >    for(i in 1:length(call)){
    >sigV[i] <- impVolC(callM = call[i], K = df$Strike[i], T = T, F = F, r =
    >r_m)  
    >    }
    >    
    >    ______________________________________________
    >    [hidden email] mailing list -- To UNSUBSCRIBE and more, see
    >    https://stat.ethz.ch/mailman/listinfo/r-help
    >PLEASE do read the posting guide
    >http://www.R-project.org/posting-guide.html
    >    and provide commented, minimal, self-contained, reproducible code.
    >    
    >
    >______________________________________________
    >[hidden email] mailing list -- To UNSUBSCRIBE and more, see
    >https://stat.ethz.ch/mailman/listinfo/r-help
    >PLEASE do read the posting guide
    >http://www.R-project.org/posting-guide.html
    >and provide commented, minimal, self-contained, reproducible code.
   
    --
    Sent from my phone. Please excuse my brevity.
   

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: How to vectorize this function

Lynette Chang
In reply to this post by R help mailing list-2
Here are the code and data file. I’m not sure if I put too much unrelated information here.

My goal is to factor out volatilities from the data. I hope I can get sigV <- impVolC(callM, K, T, F, r), which has five vectors as input, and one vector as output. The length of all those six vectors are the same. However, I got stuck in the nested if-else sentence, as if-condition cannot handle vectors. I rewrite it as you guys suggestions, however, I still have one layer of if-condition. Any thoughts to improve it? Thanks.

Lynette



df <- read.csv(file = "/S&P500_ETF_Option_0917.csv", header = TRUE,
               colClasses = c("integer", "character", "numeric", "numeric", "numeric",
                              "character", "numeric", "numeric", "numeric"))

call <- (df$callBid + df$callAsk)/2
put <- (df$putBid + df$putAsk)/2

y <- call - put
A <- cbind(rep(1, dim(df)[1]), -df$Strike)

x <- solve(t(A)%*%A)%*%t(A)%*%y
PVF <- x[1]
disc <- x[2]

S <- 2381



library(timeDate)
# Lets work in your environment:
getRmetricsOptions("myFinCenter")
setRmetricsOptions(myFinCenter = "America/New_York")

# define a sequence of days with  timeSequence
t1 <- timeSequence(from = "2017-03-16", to = "2017-09-29")

# Define a calendar for your exchange (use an available one as a template, e.g. holidayNYSE)
# subindex the sequence with isBizday using your calendar as an argument
holidayNYSE(2017)
isBizday(t1, holidayNYSE())
t2 <- t1[isBizday(t1, holidayNYSE(2017))]

T <- length(t2)/252
q_m <- -log(PVF/S)/T
r_m <- log(disc)/(-T)


polya <- function(x){
  1/2 + sign(x)/2* sqrt(1- exp(-2*x^2/pi))
}
impVolC <- function(callM, K, T, F, r){
 
  y <- log(F/K)
  alpha <- callM/(K*exp(-r*T))
  R <- 2*alpha - exp(y) + 1
 
  A <- (exp((1 - 2/pi)*y) - exp(-(1 - 2/pi)*y))^2
  B <- 4*(exp(2/pi*y) + exp(-2/pi*y)) - 2*exp(-y)*(exp((1-2/pi)*y)+exp(-(1-2/pi)*y))*(exp(2*y) + 1 - R^2)
  C <- exp(-2*y)*(R^2 - (exp(y) -1)^2)*((exp(y) + 1)^2 - R^2)                                                
 
  beta <- (2*C)/(B + sqrt(B^2 + 4*A*C))
  gamma <- -pi/2*log(beta)
 
  if(y >= 0){
    call0 <- K*exp(-r*T)*(exp(y)*polya(sqrt(2*y)) - 0.5)
    sig <- (sqrt(gamma + y)  + ifelse(callM <= call0, -1, 1) * sqrt(gamma - y))/sqrt(T)
  }else{
    call0 <- K*exp(-r*T)*(exp(y)/2 - polya(-sqrt(-2*y)))
    sig <-  (ifelse(callM <= call0, -1, 1)*sqrt(gamma + y)  +  sqrt(gamma - y))/sqrt(T)
  }
  sig
}

F <- PVF*exp(r_m*T)
sigV <- rep(0, length(call))

for(i in 1:length(call)){
  sigV[i] <- impVolC(callM = call[i], K = df$Strike[i], T = T, F = F, r = r_m)  
}


> On Sep 20, 2018, at 1:56 PM, MacQueen, Don <[hidden email]> wrote:
>
> In addition to what the other said, if callM is a vector then an expression of the form
>   if (callM <= call0)
> is inappropriate. Objects inside the parentheses of   if()  should have length one. For example,
>
>> if (1:5 < 3) 'a' else 'b'
> [1] "a"
> Warning message:
> In if (1:5 < 3) "a" else "b" :
>  the condition has length > 1 and only the first element will be used
>
>
> instead of what you have:
>         if(callM <= call0){
>           sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>         }else{
>           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
>        }
>
> Here are a couple of (untested) possibilities:
>
>  M.gt.0 <- callM > call0
>  sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>  sig[M.gt.0] <- (1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y)))[M.gt.0]
>
> or
>
>    sig <- 1/sqrt(T)*(sqrt(gamma + y)  + ifelse(callM <= call0, -1, 1) * sqrt(gamma - y))
>
> incidentally, I would write
>   sig <- (sqrt(gamma + y) - sqrt(gamma - y))/sqrt(T)
> instead of
>   sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>
> --
> Don MacQueen
> Lawrence Livermore National Laboratory
> 7000 East Ave., L-627
> Livermore, CA 94550
> 925-423-1062
> Lab cell 925-724-7509
>
>
>
> On 9/20/18, 8:08 AM, "R-help on behalf of Lynette Chang" <[hidden email] on behalf of [hidden email]> wrote:
>
>    Hello everyone,
>
>         I’ve a function with five input argument and one output number.
>      impVolC <- function(callM, K, T, F, r)
>
>         I hope this function can take five vectors as input, then return one vector as output. My vectorization ran into problems with the nested if-else operation. As a result, I have to write another for loop to call this function. Can anyone suggest some methods to overcome it? I put my code below, thanks.
>
>    impVolC <- function(callM, K, T, F, r){
>
>
>     if(y >= 0){
>         call0 <- K*exp(-r*T)*(exp(y)*polya(sqrt(2*y)) - 0.5)
>         if(callM <= call0){
>           sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>         }else{
>           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
>         }
>     }else{
>         call0 <- K*exp(-r*T)*(exp(y)/2 - polya(-sqrt(-2*y)))
>         if(callM <= call0){
>           sig <- 1/sqrt(T)*(-sqrt(gamma + y) + sqrt(gamma - y))
>         }else{
>           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
>         }
>     }
>     sig
>    }
>
>    for(i in 1:length(call)){
>     sigV[i] <- impVolC(callM = call[i], K = df$Strike[i], T = T, F = F, r = r_m)  
>    }
>
>    ______________________________________________
>    [hidden email] mailing list -- To UNSUBSCRIBE and more, see
>    https://stat.ethz.ch/mailman/listinfo/r-help
>    PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>    and provide commented, minimal, self-contained, reproducible code.
>
>

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: How to vectorize this function

Jeff Newmiller
In reply to this post by R help mailing list-2
Sorry, misread your comment, I agree. 4/2 has one arithmetic operation, (1/2)*4 has two to accomplish the same calculation.

On September 20, 2018 1:53:03 PM PDT, "MacQueen, Don" <[hidden email]> wrote:

>You're asking me?
>
>I prefer
>> 4/2
>[1] 2
>
>not
>> 1/2*4
>[1] 2
>
>(I think that's what I said)
>
>And if I did want to multiply by the reciprocal, which does happen from
>time to time, I'd certainly do it this way:
>   (1/2)*4
>
>-Don
>
>--
>Don MacQueen
>Lawrence Livermore National Laboratory
>7000 East Ave., L-627
>Livermore, CA 94550
>925-423-1062
>Lab cell 925-724-7509
>
>
>
>On 9/20/18, 12:36 PM, "Jeff Newmiller" <[hidden email]>
>wrote:
>
>re: your last comment... why do you prefer to multiply by the
>reciprocal?
>    
>On September 20, 2018 10:56:22 AM PDT, "MacQueen, Don via R-help"
><[hidden email]> wrote:
>    >In addition to what the other said, if callM is a vector then an
>    >expression of the form
>    >   if (callM <= call0)
>>is inappropriate. Objects inside the parentheses of   if()  should
>have
>    >length one. For example,
>    >
>    >> if (1:5 < 3) 'a' else 'b'
>    >[1] "a"
>    >Warning message:
>    >In if (1:5 < 3) "a" else "b" :
>>  the condition has length > 1 and only the first element will be used
>    >
>    >
>    >instead of what you have:
>    >         if(callM <= call0){
>    >           sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>    >         }else{
>    >           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
>    >        }
>    >
>    >Here are a couple of (untested) possibilities:
>    >
>    >  M.gt.0 <- callM > call0
>    >  sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>> sig[M.gt.0] <- (1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma -
>y)))[M.gt.0]
>    >
>    >or
>    >
>  >sig <- 1/sqrt(T)*(sqrt(gamma + y)  + ifelse(callM <= call0, -1, 1) *
>    >sqrt(gamma - y))
>    >
>    >incidentally, I would write
>    >   sig <- (sqrt(gamma + y) - sqrt(gamma - y))/sqrt(T)
>    >instead of
>    >   sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>    >
>    >--
>    >Don MacQueen
>    >Lawrence Livermore National Laboratory
>    >7000 East Ave., L-627
>    >Livermore, CA 94550
>    >925-423-1062
>    >Lab cell 925-724-7509
>    >
>    >
>    >
>    >On 9/20/18, 8:08 AM, "R-help on behalf of Lynette Chang"
>><[hidden email] on behalf of [hidden email]> wrote:
>    >
>    >    Hello everyone,
>    >    
>>       I’ve a function with five input argument and one output number.
>
>    >      impVolC <- function(callM, K, T, F, r)
>    >    
>  >I hope this function can take five vectors as input, then return one
>  >vector as output. My vectorization ran into problems with the nested
>   >if-else operation. As a result, I have to write another for loop to
> >call this function. Can anyone suggest some methods to overcome it? I
>    >put my code below, thanks.
>    >    
>    >    impVolC <- function(callM, K, T, F, r){
>    >    
>    >    
>    >     if(y >= 0){
>    >         call0 <- K*exp(-r*T)*(exp(y)*polya(sqrt(2*y)) - 0.5)
>    >         if(callM <= call0){
>    >           sig <- 1/sqrt(T)*(sqrt(gamma + y) - sqrt(gamma - y))
>    >         }else{
>    >           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
>    >         }
>    >     }else{
>    >         call0 <- K*exp(-r*T)*(exp(y)/2 - polya(-sqrt(-2*y)))
>    >         if(callM <= call0){
>    >           sig <- 1/sqrt(T)*(-sqrt(gamma + y) + sqrt(gamma - y))
>    >         }else{
>    >           sig <- 1/sqrt(T)*(sqrt(gamma + y) + sqrt(gamma - y))
>    >         }
>    >     }
>    >     sig
>    >    }
>    >    
>    >    for(i in 1:length(call)){
>>sigV[i] <- impVolC(callM = call[i], K = df$Strike[i], T = T, F = F, r
>=
>    >r_m)  
>    >    }
>    >    
>    >    ______________________________________________
> >    [hidden email] mailing list -- To UNSUBSCRIBE and more, see
>    >    https://stat.ethz.ch/mailman/listinfo/r-help
>    >PLEASE do read the posting guide
>    >http://www.R-project.org/posting-guide.html
>>    and provide commented, minimal, self-contained, reproducible code.
>    >    
>    >
>    >______________________________________________
>    >[hidden email] mailing list -- To UNSUBSCRIBE and more, see
>    >https://stat.ethz.ch/mailman/listinfo/r-help
>    >PLEASE do read the posting guide
>    >http://www.R-project.org/posting-guide.html
>    >and provide commented, minimal, self-contained, reproducible code.
>    
>    --
>    Sent from my phone. Please excuse my brevity.
>    

--
Sent from my phone. Please excuse my brevity.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.