Indexing Error - can't get for loop to function because indices are incorrect
1 vue (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Caleb Nickens
le 2 Fév 2021
Commenté : Caleb Nickens
le 2 Fév 2021
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.
0 commentaires
Réponse acceptée
Walter Roberson
le 2 Fév 2021
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 commentaires
Walter Roberson
le 2 Fév 2021
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)
size(A2)
max(abs(A1(:) - A2(:)))
isequal(A1, A2)
Bit. For. Bit. Identical.
What led you to suspect that the vectorized version might be less accurate?
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Logical dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!