Indexing Error - can't get for loop to function because indices are incorrect
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
Caleb Nickens
el 2 de Feb. de 2021
Comentada: Caleb Nickens
el 2 de Feb. de 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 comentarios
Respuesta aceptada
Walter Roberson
el 2 de Feb. de 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 comentarios
Walter Roberson
el 2 de Feb. de 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?
Más respuestas (0)
Ver también
Categorías
Más información sobre Matrix Indexing en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!