Error in Matlab Function Block: Index exceeds array dimensions - matlab

I have some problem during running the code below and it give me the error
Index exceeds array dimensions. Index value 3 exceeds valid range [1-2] for array 'a'. Error in 'TEST/TEST' (line 18) if a(i)> 0
This code is the code for computing the parameter k for the scalar reference governor. and Hx and Hv are the maximal admissible output sets(MAS) with the matrices A,B,C,D hope can get some help to fix this code from your all.
function v = SRG_new(v_previous, r)
A=[0 1;-275.5 -21.22];
B=[0;1];
C=[11.02 275.5];
D=0;
I=eye(2);
Hx=(C*A);
Hv= C*((I-A)*((I-A)^-1)*B+D);
s=350; %s=max_output
a=Hx*(r-v_previous);
b=s-Hx-Hv*v_previous;
k=1;
for i=1:100
if a(i)> 0
k=min(k, b(i)/a(i));
end
end
k=max(k,0);
v=v_previous + k*(r-v_previous);
end

Well this depends mainly on the size your inputs v_previous and r (As The error specifies the range "1-2" i guess, "r" and "v_previous" are scalar values).
The error occurs, because you want to iterate through 100 elements of "a", but as Hx=(C*A); only creates a 1x2 Matrix, a = Hx*(r-v_previous); will result in a Matrix "a" with fewer than 100 entries (Exactly two entries if only multiplied with a scalar value). And this must lead to the "Out of range - Error".
To get rid of the error, simply use
for i=1:numel(a)
if a(i)> 0
k=min(k, b(i)/a(i));
end
end
This way, it will only iterate through the available array elements.

Related

How to obtain the maximum between element-pairs of two 2D matrices?

I have to calculate maximum of every unique pair of elements in matrix. So here is my code:
resultsMat = [
6 4 4;
0 2 6;
7 7 1;
5 1 73
];
copyMat = resultsMat;
for i=1:size(resultsMat,1)
for j=1:size(resultsMat,2)
for q=1:size(resultsMat,1)
for p=1:size(resultsMat,2)
if i== q && j ~= p
a = max(resultsMat(i,j),copyMat(q,p))
end
end
end
end
end
The problem comes when I try to store values in a matrix. For example:
[val ind] = max(resultsMat(i,j),copyMat(q,p))
This throws an error:
Error using max
MAX with two matrices to compare and two output arguments is not supported.
Error in Untitled2 (line 18)
[a, b] = max(resultsMat(i,j),copyMat(q,p))
How to store values from a = max(resultsMat(i,j),copyMat(q,p)) in a matrix?
You need a larger (probably multi-dimensional) matrix, as every (i,j) location has a maximum vs any (q,p) location. This means that for every element in your first matrix, you obtain a full matrix of the same size. Saving as
matrix_with_results(i,j,q,p) = a
would do this. Then, given any combination of i,j,q,p, it returns the maximum.
Be sure to preallocate
matrix_with_results = zeros(size(resultsMat,1),size(resultsMat,2),size(resultsMat,1),size(resultsMat,2))
for speed.
Two notes:
Don't use i or j as indices/variables names, as they denote the imaginary unit. Using those can easily lead to hard to debug errors.
Initialise matrix_with_results, i.e. tell MATLAB how large it will be before going into the loop. Otherwise, MATLAB will have to increase its size every iteration,which is very slow. This is called preallocation.

Performed a smoothing function on a matrix, but now only matching indices give values

I have a matrix 1000x1000x50 and I performed a function on each vector along the third dimension in a loop (1,000,000 vectors, 50 elements long). When I try to view any specific element where m=n, i.e. (1000,1000,40) , a nonzero value is displayed. However, when I try to view an element where m =/= n, i.e. (1000,1001,40), only a 0 is returned. I know that (1001,1001,40) has a nonzero value, and I know that the original matrix had a nonzero element at (1000,1001,40).
Here's the loop I used:
mymatrix_new = zeros(size(mymatrix));
for i=1:length(mymatrix)
mymatrix_new(i,i,:) = wdenoise(squeeze(mymatrix(i,i,:)));
end
For the values that DO display, the result is what I expected- a smoothed signal. I just don't understand why certain elements that are nonzero are displaying as zero when the m and n indices are't identical.
You are iterating and updating only the cells that have m == n. This happens because you use a single for loop. All other values are not visited and are never updated, this is why they remain zero.
If you look at your foor loop:
for i=1:length(mymatrix)
In the first iteration i = 1 and it will update:
mymatrix_new(1,1,:) = wdenoise(squeeze(mymatrix(1,1,:)));
In the second iteration i = 2 and it will update:
mymatrix_new(2,2,:) = wdenoise(squeeze(mymatrix(2,2,:)));
As you can see, you never update mymatrix_new(1, 2) or any cell other than the ones that have m == n == i
You need to use two nested for loops, such that you update all combinations of i and j
mymatrix_new = zeros(size(mymatrix));
for i=1:length(mymatrix)
for j=1:length(mymatrix) % Here it assumes the matrix is a square
mymatrix_new(i,j,:) = wdenoise(squeeze(mymatrix(i,j,:)));
end
end

Sum of all values in matrix (Matlab)

So I'm trying to create a matlab function that takes two inputs, a matrix and a value, and returns the sum of all values in the matrix except for all instances of the given value. So far this is the code I have written:
function [total] = sumAllExcept(matrix, except)
total = 0;
for i = 1:size(matrix, 1)
for k = 1:size(matrix, 2)
if(matrix(i, k) ~= except)
total = total + matrix(i,k);
end
end
end
end
The error message that I am receiving when trying to run the program is:
" Undefined function 'sumAllExcept' for input arguments of type 'double'. "
I would greatly appreciate it if you would show me whats wrong with this and fix anything that you can. Thank you!
Sum the array after filtering out except using logical indexing:
total = sum(matrix( matrix ~= except ));
The result of using the logical index matrix ~= except on matrix returns a column vector, so only one sum is required.
The error "Undefined function 'sumAllExcept' for input arguments of type 'double'." is likely due to the function not being on MATLAB's path or the function name sumAllExcept not matching the filename (i.e., sumAllExcept.m).

indices must either be real positive integers or logicals. && Attempted to access f(0,0); index must be a positive integer or logical

I am new in matlab coming from c++ and trying to do 2d convolution. I have done dry run but nothing seems to go wrong but i dont know why this coming
My simple logic if value is lesser equal to zero then place zero. I am using this expression for solving that problem
i am facing 2 errors at
1)at f(q,p)=zeros(q,p);
2) at output_args(x,y)=output_args(x,y) + (W(s, t)* f(q,p));
function output_args = convo(img,k )
//skipped the portion of code---
z=s;i=t;
for x=1:row
for y=1:col
for s=s:a+2
% disp(s);
for t= t:b+2
q=z-s;
p=i-t;
if q<=0
if p <=0
f(q,p)=0; %// trying to place zero at index so help needed which is 1st error i have said
end
end
% disp(f(q,p));
output_args(x,y)=output_args(x,y) + (W(s, t)* f(q,p)); %//2nd error is comin (as i have told you above.
end
end
w=w+1;
end
z=z+1;
end
end
at console:(error occur when i apply
1) Subscript indices must either be real positive integers or logicals at f(q,p)=0
2) Attempted to access f(0,0); index must be a positive integer or logical. output_args(x,y)=output_args(x,y) + (W(s, t)* f(q,p));
so any idea?
if q<=0
if p <=0
f(q,p)=0; % p and q will always be invalid!
end
end
Well, that is begging for that error. In MATLAB, Indices must be greater than zero. While you can invert the if-condition to ensure that the index is positive, that will change the mending of your code.
if q > 0
if p > 0
f(q,p)=0; % p and q will always be valid.
end
end
If you need to index from -5 to 5 (for example) you could instead index from 1 to 11 instead. Just remember that you subtract 6 every time you display values. Alternatively, store the "real" indices in another vector.

Matlab Function with Varying parameters

I need help figuring out how to code the following problem. Any help would be greatly appreciated!
Create a function that will take a vector/array input for x (1 by n) and a scalar input for a, and produce the output defined by the following equation:
y(x,a)=((xsin(ax-2))/(sqrt(1+(ax)^2)
-π ≤ x ≤ π
a={.5 1 1.5 2}
The equation must be vectorized in terms of x and the output from the function is the array y which has the same dimension as the array x.
Write a script that calls this function to compute y(x,a) for the range of x defined above and each value of the parameter a. Results should be stored in a solution matrix using a different row of the solution matrix for each value of a.
So far for my function I have:
function [y] = part1(a,x)
y=((x*sin(a*x-2))/(sqrt(1+(a*x).^2)));
end
I'm not sure how to output this into the solution matrix
For my script I have:
%%
clear,clc
a={0.5 1 1.5 2};
x=-pi:0.1:pi;
for
part1(x,a)
end
I'm getting the following errors when I run this now:
Undefined function 'mtimes' for input arguments of type 'cell'.
Error in part1 (line 4)
y=((x*sin(a*x-2))/(sqrt(1+(a*x).^2)));
Error in labtest2 (line 8)
y(i,:)=part1(x,a(i));
EDIT
I've made some changes and am still getting some errors that I cannot resolve.
Here is my full code for function followed by full code for script:
Function
function [y] = part1(x,a)
nx=numel(x);
na=numel(a);
y=((x.*sin(a.*x-2))./(sqrt(1+(a.*x).^2)));
size(y)=[nx na]
end
Script
%%
clear,clc
a={0.5 1 1.5 2};
x=-pi:0.1:pi;
for i = 1:length(a)
y(i,:)=part1(x,a(i));
end
Errors
Undefined function 'times' for input arguments of type 'cell'.
Error in part1 (line 6)
y=((x.*sin(a.*x-2))./(sqrt(1+(a.*x).^2)));
Error in labtest2 (line 8)
y(i,:)=part1(x,a(i));
The reason you're getting Undefined function 'times' for input arguments of type 'cell' is because your variable a is a cell array. You need to change your assignment of a from
a={0.5 1 1.5 2};
to
a=[0.5 1 1.5 2];
which will make it just a normal array. Alternatively, you need to reference it with cell array notation: a{i} instead of a(i).
You're almost there. Note that you've written
function [y] = part1(a,x)
but you call it in your script as
part1(x,a)
so you should probably correct that.
A few things jump out at me:
You never assign the output of part1(x,a) to anything. You're told that
Results should be stored in a solution matrix using a different row of the solution matrix for each value of a.
What I take this to mean is that the 1st row corresponds to part1() evaluated for the 1st element of a. Since we're operating on x which is a vector, that row will have multiple columns. Your output is indeed a matrix. In your case, length(-pi:0.1:pi) == 63, therefore size(y) == [4 63], where y is your output matrix.
Your for loop is backwards. You're told to accept scalar a and vector x. Therefore, your script should be something like:
a = 0.5:0.5:2;
x = -pi:0.1:pi;
for i = 1:length(a)
y(i,:) = part1(x, a(i));
end
Note the use of length and the : operator. I want to iterate between 1 to length(a) (in this case, length(a) == 4) so that I can use the current a(i) value as an index into my output matrix, y. The : operator in y(i,:) signifies "The ith row and all columns of y will take the value output by part1(x,a(i))."
Your function needs to be changed up for element-by-element operations. Notice that, for instance, x*sin(a*x-2) works for scalar x but not vectors. This is because x is a vector and sin(a*x-2) is also a vector (since the sin call will operate element-by-element and a is a scalar). Trying to multiply two vectors together will result in errors since MATLAB will try to perform a matrix multiplication. Resolve this by replacing * with .*. This way it is unambiguous that you are going to multiply these two vectors element-by-element. You'll also need to change / to ./.
On another note, thank you for attempting to do your homework before asking SO for help. We've been getting a huge influx of questions from students that have made no attempt to do their own work before dumping it on us, so it's refreshing that we regulars of the MATLAB tag get to actual help out instead of telling people to do their own work.
Finally got the whole thing worked out.
Function
function [y] = part1(x,a)
y=((x.*sin(a.*x - 2))./(sqrt(1 + (a.*x).^2)));
end
Script
%%
clear all;
clc;
close all;
x=[-pi:.1:pi];
a=[.5:.5:2];
for i=1:length(a)
y(i,:)=part1(x,a(i));
plot(x,y)
end
Sol=[y]