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;endif 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 endend
Best Answer