Y= zeros(3, 354)
for m = 1 : 118
R=GridData.R2(:,3*m-2:3*m);
X=GridData.X2(:,3*m-2:3*m);
B=GridData.B1(:,3*m-2:3*m);
G=GridData.G1(:,3*m-2:3*m);
Y(:,m)= R+ 1j*X;
m=m+1;
end
This is the error: Index in position 2 exceeds array bounds (must not exceed 3). I would like to concatenate the output from a for loop.
Related
I am currently trying to use MATLAB in order to read a matrix that is a .mtx file and calculate the eigenvalues and eigenvectors. However, I do not have an idea on how to start. The entries for the .mtx matrix file are as follows:
1 1 1.451127632665004e+00
1 7 7.249195894283247e-01
7 1 7.249195894283247e-01
1 13 3.622987922604397e-01
13 1 3.622987922604397e-01
1 19 7.249195894283247e-01
19 1 7.249195894283247e-01
1 25 7.249191544766792e-01
25 1 7.249191544766792e-01
1 31 3.622985748812184e-01
...
where the first column represents the line number of the matrix, the second column represents the column number of the matrix, and the third column represents the matrix entry. The matrix size is a 405x405. So I wrote the following code in MATLAB:
fid = fopen('namepath for stiffness matrix');
fid1 = fopen('namepath for mass matrix');
a = fscanf(fid,'%f %f',[2 inf]);
a1 = fscanf(fid1,'%f %f',[2 inf]);
c1=a(:,1);
c2=a(:,2);
c3=a(:,3);
K=zeros(405,405);
fclose(fid);
for i=1:405
K(c1(i),c2(i))=c3(i);
i=i+1;
end
d1= a1(:,1);
d2= a1(:,2);
d3= a1(:,3);
M=zeros(405,405);
fclose(fid1);
for i=1:405 M(d1(i),
d2(i))=d3(i);
i=i+1;
end
[phi, w2]=eig(K,M);
After running the program, I got the following error:
Index in position 2 is invalid. Array indices must be positive integers or logical values at (line 11)
K(c1(i),c2(i))=c3(i);
Does anyone know how to fix this?
Thank you in advance.
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.
I'm executing the following code to get a matrix multiplication between the image and w.
Why do I get the Subscripted assignment dimension mismatch error.
[e,f] = size(outImg);
m = zeros(e,f);
w = [1 2 4 8; 16 32 64 128; 256 512 1024 2048; 4096 8192 16384 32768];
for i = 1:e-3
for j = 1:f-3
I = double(outImg((i:i+3),(j:j+3)));
m(i,j) = I * w;
end
end
This is carrying on from my comment, and now understanding what you're truly after. What you intended to do was perform an element-by-element multiplication of I and w, then sum all of the elements in the matrix. What I mean by element-by-element is that the corresponding values in one matrix get multiplied by the corresponding positions in the other matrix and that's the ending result. As such, you simply have to change the * operator to .*, then do a summation on this entire matrix. In other words, do this:
[e,f] = size(outImg);
m = zeros(e,f);
w = [1 2 4 8; 16 32 64 128; 256 512 1024 2048; 4096 8192 16384 32768];
for i = 1:e-3
for j = 1:f-3
I = double(outImg((i:i+3),(j:j+3)));
m(i,j) = sum(sum(I .* w)); %// Change
end
end
Note the nested sum calls. This is because when summing over a matrix, by default it sums over all of the rows for each column and produces a single row vector that contains this result. If you want to sum every single value in the matrix, you must call sum one more time to sum over the row vector to compute the overall sum of the matrix. This should now equate to a single value, and you shouldn't get the dimension mismatch error anymore.
Good luck!
I have the following matrix which keeps track of the starting and ending points of data ranges (the first column represents "starts" and the second column represents the "ends"):
myMatrix = [
162 199; %// this represents the range 162:199
166 199; %// this represents the range 166:199
180 187; %// and so on...
314 326;
323 326;
397 399;
419 420;
433 436;
576 757;
579 630;
634 757;
663 757;
668 757;
676 714;
722 757;
746 757;
799 806;
951 953;
1271 1272
];
I need to eliminate all the ranges (ie. rows) which are contained within a larger range present in the matrix. For example the ranges [166:199] and [180:187] are contained within the range [162:199] and thus, rows 2 and 3 would need to be removed.
The solution I thought of was to calculate a sort of "running" max on the second column to which subsequent values of the column are compared to determine whether or not they need to be removed. I implemented this with the use of a for loop as follows:
currentMax = myMatrix(1,2); %//set first value as the maximum
[sizeOfMatrix,~] = size(myMatrix); %//determine the number of rows
rowsToRemove = false(sizeOfMatrix,1); %//pre-allocate final vector of logicals
for m=2:sizeOfMatrix
if myMatrix(m,2) > currentMax %//if new max is reached, update currentMax...
currentMax = myMatrix(m,2);
else
rowsToRemove(m) = true; %//... else mark that row for removal
end
end
myMatrix(rowsToRemove,:) = [];
This correctly removes the "redundant" ranges in myMatrix and produces the following matrix:
myMatrix =
162 199
314 326
397 399
419 420
433 436
576 757
799 806
951 953
1271 1272
Onto the questions:
1) It would seem that there has to be a better way of calculating a "running" max than a for loop. I looked into accumarray and filter, but could not figure out a way to do it with those functions. Is there a potential alternative that skips the for loop (some kind of vectorized code that is more efficient)?
2) Is there a completely different (that is, more efficient) way to accomplish the final goal of removing all the ranges that are contained within larger ranges in myMatrix? I don't know if I'm over-thinking this whole thing...
Approach #1
bsxfun based brute-force approach -
myMatrix(sum(bsxfun(#ge,myMatrix(:,1),myMatrix(:,1)') & ...
bsxfun(#le,myMatrix(:,2),myMatrix(:,2)'),2)<=1,:)
Few explanations on the proposed solution:
Compare all starts indices against each other for "contained-ness" and similarly for ends indices. Note that the "contained-ness" criteria has to be for either of these two :
Greater than or equal to for starts and lesser than or equal to for ends
Lesser than or equal to for starts and greater than or equal to for ends.
I just so happen to go with the first option.
See which rows satisfy at least one "contained-ness" and remove those to have the desired result.
Approach #2
If you are okay with an output that has sorted rows according to the first column and if there are lesser number of local max's, you can try this alternative approach -
myMatrix_sorted = sortrows(myMatrix,1);
col2 = myMatrix_sorted(:,2);
max_idx = 1:numel(col2);
while 1
col2_selected = col2(max_idx);
N = numel(col2_selected);
labels = cumsum([true ; diff(col2_selected)>0]);
idx1 = accumarray(labels, 1:N ,[], #(x) findmax(x,col2_selected));
if numel(idx1)==N
break;
end
max_idx = max_idx(idx1);
end
out = myMatrix_sorted(max_idx,:); %// desired output
Associated function code -
function ix = findmax(indx, s)
[~,ix] = max(s(indx));
ix = indx(ix);
return;
I ended up using the following for the "running maximum" problem (but have no comment on its efficiency relative to other solutions):
function x = cummax(x)
% Cumulative maximum along dimension 1
% Adapted from http://www.mathworks.com/matlabcentral/newsreader/view_thread/126657
% Is recursive, but magically so, such that the number of recursions is proportional to log(n).
n = size(x, 1);
%fprintf('%d\n', n)
if n == 2
x(2, :) = max(x);
elseif n % had to add this condition relative to the web version, otherwise it would recurse infinitely with n=0
x(2:2:n, :) = cummax(max(x(1:2:n-1, :), x(2:2:n, :)));
x(3:2:n, :) = max(x(3:2:n, :), x(2:2:n-1, :));
end
>> a = [1 1 2 3 5 8 13 21 13 37];
>> d = [1 2];
>> w = [0 0 0];
for e = d
g = 0;
for f = a
if mod (f, 2) == 0
g = [g f];
end
end
w = [w;g];
end
>> w
The output of W is the matrix
0 0 0
0 2 8
0 2 8
My question is about the for-loops. Do Matlab for-loops take a value, instead of being a logical condition? For example, when looking at 'for f = a' does f take the value of the array A and then the for-loop iterates through F by its columns?
Thanks.
FOR loops have a variable, each pass through the loop the iterator variable takes on the next value in the array. The iterator variable takes on the values of the columns, one at a time. The right hand side of the assignment statement in the foor loop needn't be a numeric array -- it could be a cell array of strings for example, or a structure, etc.
In other words, when you have for
for f=a, ....., end
this is equivalent to writing
for i=1:numel(a)/size(a,1); f=a(:,i); .... ; end
You can easily see this by adding some disp statements into your code:
for e = d
disp(e)
g = 0;
for f = a
disp(f)
if mod (f, 2) == 0
g = [g f];
end
end
w = [w;g];
end
WHILE loops in matlab take a logical condition.
(edit: i forgot that f takes on the value of the columns of a if a is multidimensioned)
Yes, MATLAB loop variables are assigned to "arrays", called vectors in MATLAB parlance. The value of the loop variable automatically iterates over elements of the vector upon each iteration of the loop. A common construct is
for i=1:10 %generates vector of 1,2,...,10
i %will print i=1, i=2, etc.
end
In this case the vector was generated on the fly, and is sequential numbers. But there is no reason you can't pass any arbitrary vector in to iterate over, like "a" in your case. Upon each iteration, "f" takes on the next value in the sequence contained in "a".