如何模拟一个随机过程,直到路径的所有元素都为正?

How to simulate a stochastic process until all elements of a path are positive?

我想使用Python模拟连续时间内某个随机过程的路径。我写了下面的函数来模拟一下(np当然是指numpy):

def simulate_V(v0, psi, theta, dt, xsi, sample, diff = False):

    _, dB = independent_brownian(dt, 1, sample, diff = True)
    path_lenght = len(dB) + 1
    V = np.zeros(path_lenght)
    dV = np.zeros(len(dB))
    V[0] = v0
    for i in range(len(dV)):
        dV[i] = psi * (theta - V[i]) * dt + xsi * np.sqrt(V[i]) * dB[i]
        V[i+1] = V[i] + dV[i]
    
    if diff == True:
        return(V, dV)
    else:
        return(V)

independent_brownian函数只是为标准布朗运动创建了一条路径。为了完整起见,这里是:

def independent_brownian(dt, n, sample, diff=False):
    '''
    Creates paths of independent Brownian motions. Returns increments if diff == True.
    --------
    dt -> variance of increments\
    n -> how many paths\
    sample -> length of sampled path\
    diff -> return increments or not?\

    Returns a (n, sample)-shaped array with the paths
    '''
    increments = np.sqrt(dt) * np.random.randn(n, sample)
    paths = np.cumsum(increments, axis=1)
    b = np.zeros((n, sample + 1))
    b[:, 1:] = paths

    if n==1:
        b = b.flatten()
        increments = increments.flatten()

    if diff == True:
        return(b, increments)
    else:
        return(b)

碰巧我的模型背后的数学暗示过程 $V_t$(在上面的代码中由其离散化 V 表示)必须是正的。但是,数组 dB 可能包含绝对值较大的负元素。我想自动执行以下“选择”过程:

  1. 尝试按照 simulate_V;
  2. 中描述的循环
  3. 在某些时候,如果 V[i] 低于零,则中断该过程,采样另一个序列 dB 并重新开始;
  4. V的所有元素都为正时停止;

自动执行此过程的好方法是什么?现在,我明白,如果 V[i] 低于零,我会在 numpy 中得到一个 nan 但它不会抛出任何错误或停止进程。

为了一般性,并且由于我对布朗运动不是很熟悉,我将针对我们有一个变量 dB 的情况实现一个通用机制,我们用它来创建另一个变量V,我们需要重复这一代V,直到满足某个条件。

import numpy as np
dB = np.random.normal(size=3) # initializing dB
found_sufficient_v_flag = False # we define a flag that would tell us when to stop
while not found_sufficient_v_flag: # while this flag is False, we continue searching
  v = np.zeros(3) # initializing v
  for i in range(3): # for loop
    v[i] = dB[i] + np.random.normal() # we change the v[i] element
    if v[i] < 0: # if it is negative, there is no point in continuing, so we break the loop
      dB = np.random.normal(size=3) # but we need to instantiate a different dB
      break 
  if np.all(v > 0): # we arrive here if either v[i] < 0, or all v[i] > 0. in the latter case we stop
    found_sufficient_v_flag = True
print(dB)
print(v)

这为我提供了以下输出:

[2.27582634 0.77008881 0.28388536]
[2.55101104 3.10944337 0.55829105]

你可以看到 V 的条件确实成立。

如果需要任何其他说明,请告诉我。