Apply function row-wise on a tall array
Mostra commenti meno recenti
Hi,
I have a tall array T with some variables, let's say A, B and C. I also have a function f(a,b,c), that only works with scalars a, b and c and cannot be vectorized.
Now I would like to run this function on every row of the tall array yielding a column D.
I tried something like:
% Fill D with nans.
nanLike = @(in) nan(size(in),'like',in);
T.D = matlab.tall.transform(nanLike, T.A);
% Iterate through rows and overwrite nan with function value.
for i = 1:gather(size(T,1))
a = T.A(i);
b = T.B(i);
c = T.C(i);
[a,b,c] = gather(a,b,c);
T.D(i) = f(a,b,c);
end
But that neither works, nor can be efficient.
Do you have any idea?
Here is my real function f just that you see, that it cannot be vectorized so easily (of course, if you can help my vectorize it, the problem would also be solved):
function [opprice] = opprice(S, K, r, TtM, sigma, d, Type, ExerciseType, steps, inputcheck)
%OPPRICE calculates the price of a stock option given the specified
%parameters using BS for European and CRR for American options.
% S: stock price
% K: strike price
% r: risk-free rate
% TtM: time to Maturity in years
% sigma: volatility, (0, inf)
% d: dividend yield, [0, inf)
% Type: {'C', 'P'}
% ExerciseType: {'A', 'E'}
% steps: height of the binomial tree
% inputcheck: if input validity should be checked {true, false}
%% Input Validity Check.
if nargin <= 9
inputcheck = true;
end
if inputcheck == true
if nargin < 9
error('Not enough inputs specified.');
end
if numel(S)~= 1 || ~isnumeric(S) || isnan(S) || S <= 0
opprice = NaN;
return;
end
if numel(K)~= 1 || ~isnumeric(K) || isnan(K) || K <= 0
opprice = NaN;
return;
end
if numel(r)~= 1 || ~isnumeric(r) || isnan(r)
opprice = NaN;
return;
end
if numel(TtM)~= 1 || ~isnumeric(TtM) || isnan(TtM) || TtM <= 0
opprice = NaN;
return;
end
if numel(sigma)~= 1 || ~isnumeric(sigma) || isnan(sigma) || sigma <= 0
opprice = NaN;
return;
end
if numel(d)~= 1 || ~isnumeric(d) || isnan(d) || d < 0
opprice = NaN;
return;
end
if ~any([strcmp(Type,'P'), strcmp(Type,'C')])
opprice = NaN;
return;
end
if ~any([strcmp(ExerciseType,'A'), strcmp(ExerciseType,'E')])
opprice = NaN;
return;
end
if strcmp(ExerciseType,'A')
if steps < 1 || floor(steps) ~= steps
opprice = NaN;
return;
end
end
end
%% Do Pricing.
switch ExerciseType
case {'American', 'A'}
% Precalculate components.
dT = TtM ./ steps;
u = exp(sigma .* sqrt(dT));
p0 = (u.*exp(-d .* dT) - exp(-r .* dT)) ./ (u.^2 - 1);
p1 = exp(-r .* dT) - p0;
% Stock prices at time T.
S_T = S.*u.^(2*(0:steps)'-steps);
% Option type related binomial calculations.
switch Type
case {'Call','C'}
% Option prices at time T.
p = max(S_T - K, 0);
% Move from latest to earliest node.
for j = steps:-1:1
% Binomial value.
p = p0 * p(2:j+1) + p1 * p(1:j);
% Exercise value.
exercise_value = S.*u.^(2*(0:(j-1))'-(j-1)) - K;
p = max(p, exercise_value);
end
case {'Put','P'}
% Option prices at time T.
p = max(K - S_T, 0);
% Move from latest to earliest node.
for j = steps:-1:1
% Binomial value.
p = p0 * p(2:j+1) + p1 * p(1:j);
% Exercise value.
exercise_value = K - S.*u.^(2*(0:(j-1))'-(j-1));
p = max(p, exercise_value);
end
end
% Get price today from tree
opprice = p(1);
case {'European', 'E'}
divisor = sigma * sqrt(TtM);
d_1 = (log(S/K) + (r - d ...
+ sigma^2/2) * TtM) / divisor;
d_2 = d_1 - divisor;
switch Type
case {'Call','C'}
opprice = exp(-d*TtM) * S * normcdf(d_1) ...
- exp(-r*TtM) * K * normcdf(d_2);
case {'Put','P'}
opprice = exp(-r*TtM) * K * normcdf(-d_2) ...
- exp(-d*TtM) * S * normcdf(-d_1);
end
end
end
Risposta accettata
Più risposte (0)
Categorie
Scopri di più su Tables in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!