Я пишу программу, которая может оценить вариант корзины. Обобщая ключ к решению моей проблемы, я рисую много случайных величин ~ 70'000'000 и выполняю с ними определенные вычисления. Прямо сейчас я рисую случайные выборки в матрице с размерностью (10,100000)и повторяя шаг около 700, чтобы получить достойное приближение.Общее время вычислений: 99 секунд.
После профилирования моего кода с помощью cProfile я понял, что 51% моего вычислительного времени тратится на рисование этих случайных выборок ,что я и сделал, используя np.random.normal
[d = 10, N = 100000].
def getZ(h_n):
# Get A Matrix (d,N) consisting of Gaussian N(0,h_n) Variables
return np.random.normal(0, h_n, (d, N))
Поэтому мой вопрос касается вопроса, существует ли более эффективный способ рисования моих случайных выборок.
Большое спасибо за вашу помощь:)
Приложение (код, который я использую + общий cProfile, может быть полезен длячитатель интереса):
Код без предварительных определений:
"""Implementation of Approximation"""
"Construct Covariance Matrix and Decomposition"
# Create Matrix Eta which is the matrix of Covariances
Eta = np.eye(d) + rho * (np.ones(d) - np.eye(d))
# Use the Cholesky Decomposition to derive L, which has the value that Eta = L*L'
L = np.linalg.cholesky(Eta)
"Construct price Processes"
# Generate Delta_W trough sqrt(T)*L*Z with Z~N(0,1), Delta_W is a matrix of dim = (d,N)
# For the generation of Z define getZ
def getZ(h_n):
# Get A Matrix (d,N) consisting of Gaussian N(0,h_n) Variables
return np.random.normal(0, h_n, (d, N)) # np.random.normal(loc = 0.0, scale = np.sqrt(delta_t))
"Construct EM Method"
# d relates to the dimension of the problem, therefore, is the no. of assets in the market
Y = S_0*np.ones([d, N]) # initialisiere Y0! und dann überschreibe Y ständig
for i in range(0, (T+1) * n):
# Y = Y + np.diag(mu) @ Y * dt + np.multiply(np.diag(sigma) @ Y, L @ getZ(dt))
Y = Y + mu[:, None] * Y * dt + np.multiply(sigma[:, None] * Y, L @ getZ(dt))
if i % 100 == 0:
print('Progress: ' + str(i) + '/' + str((T+1)*n) + ' of all EM steps, while ' + str(np.round((time.time() - start_time), 2)) + ' secs passed.' )
"Construct Payoff"
Payoff = np.matmul(alpha, Y)-K
Payoff = np.sum(Payoff[(Payoff > 0)])/N # other entries would be 0 anyway, therefore its okay to use Payoff[(Payoff>0)]
V = np.exp(-r*T)*Payoff # Discount Payoff to get the fair price of the Option
"Output"
print('\nIn a market consisting of ' + str(d) + ' stocks, \nwe evaluated a classical basket option, \nusing ' + str(N) + ' MC samples.')
print('The true price of the Option is ' + str(round(V, 5)) + '\nusing the Euler Maruyama Method with ' + str((T+1) * n) + ' steps for approximation')
print("--- %s seconds ---" % np.round((time.time() - start_time), 2))
cПрофиль:
1708 function calls in 46.562 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
784 0.004 0.000 46.555 0.059 Monte_Carlo_EM.py:45(getZ)
1 0.000 0.000 0.000 0.000 fromnumeric.py:1966(sum)
9 0.000 0.000 0.001 0.000 fromnumeric.py:2940(around)
9 0.000 0.000 0.001 0.000 fromnumeric.py:3373(round_)
9 0.000 0.000 0.001 0.000 fromnumeric.py:41(_wrapit)
9 0.000 0.000 0.001 0.000 fromnumeric.py:54(_wrapfunc)
1 0.000 0.000 0.000 0.000 fromnumeric.py:69(_wrapreduction)
1 0.000 0.000 0.000 0.000 fromnumeric.py:70(<dictcomp>)
1 0.000 0.000 0.000 0.000 linalg.py:111(get_linalg_error_extobj)
1 0.000 0.000 0.000 0.000 linalg.py:116(_makearray)
2 0.000 0.000 0.000 0.000 linalg.py:121(isComplexType)
1 0.000 0.000 0.000 0.000 linalg.py:134(_realType)
1 0.000 0.000 0.000 0.000 linalg.py:144(_commonType)
1 0.000 0.000 0.000 0.000 linalg.py:203(_assertRankAtLeast2)
1 0.000 0.000 0.000 0.000 linalg.py:209(_assertNdSquareness)
1 0.000 0.000 0.000 0.000 linalg.py:678(cholesky)
2 0.000 0.000 0.006 0.003 numeric.py:175(ones)
10 0.000 0.000 0.000 0.000 numeric.py:469(asarray)
2 0.000 0.000 0.000 0.000 twodim_base.py:154(eye)
19 0.000 0.000 0.000 0.000 {built-in method builtins.getattr}
1 0.000 0.000 0.000 0.000 {built-in method builtins.isinstance}
3 0.000 0.000 0.000 0.000 {built-in method builtins.issubclass}
11 0.000 0.000 0.000 0.000 {built-in method builtins.print}
1 0.000 0.000 0.000 0.000 {built-in method builtins.round}
12 0.000 0.000 0.000 0.000 {built-in method numpy.array}
2 0.006 0.003 0.006 0.003 {built-in method numpy.copyto}
2 0.000 0.000 0.000 0.000 {built-in method numpy.empty}
2 0.000 0.000 0.000 0.000 {built-in method numpy.zeros}
10 0.000 0.000 0.000 0.000 {built-in method time.time}
1 0.000 0.000 0.000 0.000 {method '__array_prepare__' of 'numpy.ndarray' objects}
1 0.000 0.000 0.000 0.000 {method 'astype' of 'numpy.ndarray' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects}
1 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects}
784 46.550 0.059 46.550 0.059 {method 'normal' of 'mtrand.RandomState' objects}
1 0.000 0.000 0.000 0.000 {method 'reduce' of 'numpy.ufunc' objects}
9 0.000 0.000 0.000 0.000 {method 'round' of 'numpy.ndarray' objects}