Indexing Error - can't get for loop to function because indices are incorrect

1 回表示 (過去 30 日間)
function basis = regbas(CorrectionType)
basisN0 = @(x)[ 1 ];
basisN1 = @(x)[ 1, x ];
basisN2 = @(x)[ 1, x, x^2 ];
basisN3 = @(x)[ 1, x, x^2, x^3 ];
if strcmp(CorrectionType,'Constant')
basis = basisN0
elseif strcmp(CorrectionType,'Linear')
basis = basisN1
elseif strcmp(CorrectionType,'Quadratic')
basis = basisN2
elseif strcmp(CorrectionType,'Cubic')
basis = basisN3
else
disp("Error - CorrectionType should be either 'Constant', 'Linear', 'Quadratic' or 'Cubic'.")
end
end
This function defines "basis"
function coef = alsqr(arr,basis)
x = arr(:,1); % time is column 1
y = arr(:,2); % change second value for column based on which acceleration data you're using
if length(x) ~= length(y); disp('Error - The dimensions of the x and y value lists in the data are not the same')
end
order = length(basis(1));
n = length(x);
A = ones(n,order);
for ORD = 1:order
vec = basis(ORD);
for dat = 1:n
A(dat, ORD) = vec(x(dat)); % ERROR OCCURS HERE
end
end
AT = A';
AA = AT*A;
Ay = AT*y;
w = AA\Ay;% same as inv(AA)*Ay;
coef = round(w,9);
end
I am looking to create a matrix "A" that has length(x) rows and the same number of columns as basis. When I run this function (alsqr), I get an error inside the second for loop telling me "Array indices must be positive integers or logical values." I have tried many different formats and can't get it to run correctly. These functions are to solve for a least squares regression.

採用された回答

Walter Roberson
Walter Roberson 2021 年 2 月 2 日
regbas returns a function handle. Presumably it is that function handle that is being passed into alsqr
x = arr(:,1); % time is column 1
So x is expected to be a vector of times.
order = length(basis(1));
Invoking the function handle on scalar input 1 returns a vector, and you are calculating the length of the vector returned. Reasonable code.
for ORD = 1:order
vec = basis(ORD);
You are passing the current order, such as 1, 2, 3, to basis(), which is accepting those as x values and returning a vector of values. ORD = 1 might return [1, 1, 1^2], ORD = 2 might return [1, 2, 2^2] and so on. So vec will be a numeric vector of length order
for dat = 1:n
A(dat, ORD) = vec(x(dat)); % ERROR OCCURS HERE
x is a vector of times. x(dat) is a scalar time, such as 0.013 . You then use that scalar time, which will not generally be a positive integer, to try to index vec, which is numeric vector of integers like [1, 3, 9] . But those times are not valid subscripts.
Reminder that your basis is not a vector of function handles to be indexed and individually applied to data: your basis is a function handle to something that returns a vector. As in
A = cell2mat(arrayfun(basis, x(:), 'uniform', 0));
  5 件のコメント
Walter Roberson
Walter Roberson 2021 年 2 月 2 日
format long g
x = randn(50,1) * 1000;
basisN3 = @(x)[ 1, x, x^2, x^3 ];
basisN3v = @(x) [ones(size(x(:))), x(:), x(:).^2, x(:).^3];
A1 = cell2mat(arrayfun(basisN3, x, 'uniform', 0));
A2 = basisN3v(x);
size(A1)
ans = 1×2
50 4
size(A2)
ans = 1×2
50 4
max(abs(A1(:) - A2(:)))
ans =
0
isequal(A1, A2)
ans = logical
1
Bit. For. Bit. Identical.
What led you to suspect that the vectorized version might be less accurate?
Caleb Nickens
Caleb Nickens 2021 年 2 月 2 日
I must have run it incorrectly. Following what you provided here, I see that it does work very well. Thank you again.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

製品


リリース

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by