簡體   English   中英

R 到 Python 隨機過程轉換

[英]R to Python stochastic process translation

我想將下面的 R 代碼翻譯成 Python。

這主要是一個隨機過程,我需要將其轉換為 Python。

該代碼實現了具有兩個波動階段的跳躍過程的馬爾可夫鏈模擬。

set.seed(42)

nSim   <- 1E5
tau    <- 3
K      <- 105
S0     <- 100
rf     <- 0.05
vol_lo <- 0.25
vol_hi <- 0.75
lambda <- c(3,2) # away-from-lo, away-from-hi

sim_time_in_lo <- function(state0){
  t <- 0
  s <- state0
  time_lo <- 0
  while (t<tau){
    dt <- rexp(n=1,lambda[s])
    if ((t+dt)>tau){ dt <- tau - t}
    if (s==1){time_lo <- time_lo + dt }
    if (s==1){s<-2} else {s <-1}
    t <- t+ dt
  }
  time_lo
}
tau_lo     <- sapply(1:nSim,function(i){sim_time_in_lo(1)})
tau_hi     <- tau - tau_lo
total_var  <- tau_lo * vol_lo^2 + tau_hi * vol_hi^2
drift      <- rf * tau-0.5*total_var
randomness <- sqrt(total_var)*rnorm(nSim,)

Python 嘗試如下:

我認為我在 pandas 中使用了像 function 這樣的 sapply。

import numpy as np
import pandas as pd


np.random.seed(42)

nSim   = 1000
tau    = 3
K      = 105
S0     = 100
r      = 0.05
vol_lo = 0.25
vol_hi = 0.75
lambd = [3,2] # away-from-lo, away-from-hi

def sim_time_in_lo(state0):
    t = 0
    s = state0
    time_lo = 0
    while (t<tau):
        dt = np.random.exponential(scale = lambd[s],size = nSim)
        if (t+dt)>tau:
            dt = tau - t
        elif s == 1:
                time_lo = time_lo + dt
        elif s == 1:
            s = 2
        else : s = 1
        t = t+ dt
        time_lo

df = pd.DataFrame([sim_time_in_lo(1) for i in range(1,nSim)]);df
tau_hi     = tau - tau_lo
total_var  = tau_lo * vol_lo**2 + tau_hi * vol_hi**2
drift      = r * tau-0.5*total_var
randomness = np.sqrt(total_var)*np.random.normal(size=nSim)

但我收到一個錯誤

df = pd.DataFrame([sim_time_in_lo(1) for i in range(1,nSim)]);df

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

我的錯誤是什么?

您的錯誤是if (t+dt)>tau dt是一個數組,它使(t+dt)>tau成為 boolean 值的數組。

使用((t+dt)>tau).any()((t+dt)>tau).all()來賦予 if 語句的含義。 .all()表示您希望t+dt的每個值都大於 tau,而.any()表示如果只有一個值更大,這就足夠了。

以下是使其運行的一些改進:

nSim = int(1e5)
tau = 3
K = 105
S0 = 100
r = 0.05
vol_lo = 0.25
vol_hi = 0.75
lambd = [3, 2]  # away-from-lo, away-from-hi


def sim_time_in_lo(state0):
    t = 0
    s = state0
    time_lo = 0
    while t < tau:
        dt = np.random.exponential(size=1, scale=1/lambd[s])
        if (t + dt) > tau:
            dt = tau - t
        if s == 0:
            time_lo = time_lo + dt
            s = 1
        else:
            s = 0
        t = t + dt
    if isinstance(time_lo, np.ndarray):
        return time_lo[0]
    return time_lo


tau_lo = np.array([sim_time_in_lo(0) for i in range(nSim)])
tau_hi = tau - tau_lo
total_var = tau_lo * vol_lo ** 2 + tau_hi * vol_hi ** 2
drift = r * tau - 0.5 * total_var
randomness = np.sqrt(total_var) * np.random.normal(size=nSim)
  1. nSim是 1e5,而不是 1000。此語法也適用於 Python,但您需要轉換為 int。
  2. Python 使用零索引,與 R 不同,因此狀態需要為 0 和 1 才能從lambd獲取值。
  3. 指數的size參數應該是 1,返回一個標量,而不是nSim - 這就是你得到錯誤的原因。
  4. 您必須使用顯式return語句,這與 R 不同(否則 Python 函數返回None )。
  5. 修復了一些奇怪的縮進,這也導致了我認為的問題。
  6. time_lo初始化為大小為 1 的數組,否則有時會返回標量。 然后稍后從 size-1 arrays 中提取標量(在列表理解中)
  7. 使用數組代替 Dataframe。
  8. 注意np.random.exponentialscale參數是 $\Beta$,即 $\frac{1}{\lambda}$。 R 的rexprate是 $\lambda$。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM