Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am trying to find the coordinates of all non zero elements in a matrix, in MATLAB. I know that find makes this very easy. The problem is that I need to define the length of my matrix before I can fill it up. I believe this is impossible using find, since it will make its own vector.
So I have to find another way. If I'm looking for 1 element it will be easy as well. Let me use an example. Say I have a matrix M of 500×500, with 60 ones somewhere. I want to find the coordinates. So I can start with:
for i = 1:500
for j = 1:500
if M(i,j) == 1
row = i;
col = j;
end
end
end
But I want more then one point, and I need to define the length of a vector before filling it. So I'll make the gamble that there are less then 100 ones in the matrix:
v = zeros(1,100)
w = zeros(1,100)
And how I essentially want to fill this vector is as follows. Let's say I have already filled N elements of the vector, so the next one will be:
for i = 1:500
for j = 1:500
if M(i,j) == 1 && i ~= v(1) && i ~= v(2) && ... && i ~= v(N) && j ~= v(1) && ... && i ~= v(N)
v(N+1) = i
w(N+1) = j
end
end
end
So I need another for loop containing all this, which will run through the elements of the vectors v and w, and I need some loop that will make sure the right if statement is being used.
Does anyone have any idea of how to do this?
Kind regards,
Jesse
Here's another way, nice & wasteful:
[jj,ii] = meshgrid(1:size(M,2),1:size(M,1));
inds = M~=0;
ii = ii(inds);
jj = jj(inds);
I honestly cannot understand what's wrong with find.
But, if you insist on your own implementation using nested loop, then
v = NaN(100,1);
w = NaN(100,1); % pre-allocate
ii=1;
for row=1:size(M,1)
for col=1:size(M,2)
if M(row,col) == 1
v(ii)=row;
w(ii)=col;
ii=ii+1; %counts howmany elements were found
end
end
end
v(isnan(v))=[]; %discard redundent elements
w(isnan(w))=[];
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have being supplied an mxn random generated binary matrix which allows flow through the value 1 but not through the value 0. I need to determine if there is a path of flow from the top to the bottom of the random generated matrix. The 1s have to be adjacent to one another. It is for programming in Matlab.
Any reference to helpful resources on how to code the problem, or algorithm examples will be greatly appreciated.
I have some code which initially searches for the first 1 in the top row.
The code therafter searches all the surrounding positions, below and adjacent to the current 1. The flow can only move diagonally down, directly left or directly right.
The purpose i to see if there is a way, given the above restrictions, to traverse from the top to the bottom of the matrix following only the 1's
Random=randi([0 1],6,6)
n =0;
while Random[0,n] ~= 1
n=n+1;
end
CoOrds = [0,n];
for i = 0:5
if Random[i+1, n-1] == 1
n=n-1;
elseif Random [i,n-1] == 1
i = i-1;
n = n-1;
elseif Random [i+1,n] ==1
n=n;
elseif Random [i+1,n+1] ==1
n=n+1;
elseif Random[i,n+1] == 1
i = i-1;
n=n+1;
end
end
You can use bwlabel and regionprops to check if a path exists:
lb = bwlabel(Random, 8); %// find 8-connected regions of the random mask
st = regionprops(lb, 'BounbdingBox'); %// find bounding boxes for all regions
b = vertcat(st.BounbdingBox);
A valid path is a path that its boundingbox height (4-th entry in 'BoundingBox') equals size(Random,1):
validPathRegion = find( b(:,4) == size(Random,1) );
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
(edited, i have changed the code) Well i have compound equations that i need to solve in matlab and find the result.
I have tried different techniques but have failed.
the equations are:
u(j-1)-2(u(j))+u(j+1)= -4*h^2*pi^2 * sin(2*pi*xj)
where
n=100
j=1 to n
xj=jh
h=1/n
u(0)==u(n)==0
I need to solve the equation and plot the results. so that i can compare the results with
the exact solution.
This is the code i have written so far...
function c= prob1()
n=100;
c=(0); % variable to store all results
u = linspace(1,n-1);
for k=3:90
jay=k;
h=1/k;
syms xj
eqn6 = u(jay-1) -2*u(jay)+u(jay+1)==-4*(h^2)*(pi^2)*sin(2*pi*xj);
A = solve(eqn6, xj); % solving the equation with xj as unknown
if(~(A==0))
c=vertcat(c,A); % just filtering out the results with 0 output
end
end
end
Now i GET answers in A like this " (625*asin(1/9877545463176224))/3927 ".
which i cannot plot.
Setting up the system of equations Au = b is done by translation the math into MATLAB language as follows:
n = 100;
h = 1/n;
j = 0:n; % include zero for the boundary condition
xj = j*h;
% set up right hand side
b = (-4*h^2*pi^2*sin(2*pi*xj))';
% overwrite the first and last value of b with the right hand side of the boundary conditions:
b([1 end]) = 0;
% This is the interesting part:
% set up A: 1*u(j-1) -2*u(j) + 1*u(j+1) and include the boundary conditions
main = [1; -2*ones(n-1,1); 1];
upper = [0; ones(n-1,1)];
lower = [ones(n-1,1); 0];
A = gallery('tridiag', lower, main, upper);
If you dont see why this works, I would suggest to write out the equations for at least j = 0, n/2 and n based on A and b, and to compare them with your equations.
Now, we are ready to solve the system. The system is small so I use the backslash operator (which is a direct method), but you could also pick iterative methods like bicgstab, gmres, qmr:
u = A\b;
Plot the resulting u:
plot(xj,u)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
please any one help me to shift 1 element towards right in a loop of 32 elements and on the first entry of an array,everytime it gets new rand number either +1,-1 and shifts the remaining elements towards right.
i am doing in this way but it's not working properly
clc
clear all
near_input=zeros(1,32); %vector of 32 elements with all zeros
y=2*round(rand(1,1))-1; % random bernoulli sequence (+1,-1)
z=[y near_input(1:end-1)];
I suggest you insert all the number at once, avoiding the shifting. You can do this simply like this:
z = 1-2*round(rand(1,32))
The inputs to rand is the number of rows and columns. Therefore, rand(1,32) is the same as putting 32 rand(1,1) next to each other. And for the record, rand(1,1) == rand().
However, if you really have to do it your way, you need to do some changes. The following works (but is really bad code).
near_input = zeros(1,32);
for ii = 1:numel(near_input)
y = 2*round(rand(1,1))-1;
near_input = [y, near_input(1:end-1)]
end
% z = near_input;
You can generate the entire sequence like this:
y = sign(2*(rand(1, 32) - 0.5)); % 1x32 array of +-1's
Or, if you insist on creating them one-by-one with 'push-right' (or more accurately 'concat-left'):
y = [];
for unused = 1:32
y = [sign(rand() - 0.5), y];
end
Which has the disadvantage of changing y's size in a loop (a real performance hit if you use large arrays). A better approach would be to pre-allocate y, and assign by index:
y = zeros(1, 32);
for index = 32:-1:1
y(index) = sign(rand() - 0.5);
end
Running the index from 32 down to 1, assigns the values into y from right to left as you put it.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
for X = 0: 0.00001 : 100;
M=(((sqrt(2*X)-(1/3))^2)*(2*X-1));
N=(( 10.99743/sqrt(X)-(23/30))^2)*(( 53.75263/X)-1);
if M == N
Y=X;
end
end
this code is for an equation with two sides M&N,,, it must be solved using try and error or Matlab Numerical
why this code is false?
Your problem is (as nkjt points out) with comparing floating point values with ==.
FYI: If your objective is to find for which X, M == N, then you could do it much simpler using for instance fzero:
f = #(X) (((sqrt(2.*X)-(1/3))^2)*(2.*X-1))- ...
(( 10.99743./sqrt(X)-(23/30))^2)*(( 53.75263./X)-1);
y = fsolve(f,1)
y = 6.0304
This gives:
M - N = -1.3743e-05
Which is quite close to zero (as close as you will get).
If you absolutely want try and fail, see if you can decipher this (based on the idea of nkjt):
step = 1;
X = 1:step:100
M=(((sqrt(2*X)-(1/3)).^2).*(2*X-1));
N=(( 10.99743./sqrt(X)-(23/30)).^2).*(( 53.75263./X)-1);
[Y, idx] = min(abs(N-M))
err = 1e-10; % Arbitrary tolerance > 1e-14 (typically)
it = 0;
while Y > err && it < 10
step = step / 10;
it = it + 1;
X = X(idx) + (-step*10:step:step*10);
M=(((sqrt(2*X)-(1/3)).^2).*(2*X-1));
N=(( 10.99743./sqrt(X)-(23/30)).^2).*(( 53.75263./X)-1);
[Y, idx] = min(abs(N-M))
end
The perils of floating point comparison could be one factor. When comparing two floating point numbers, you should not use == but check if the difference between them is less than some tolerance (can use eps or something else, depending on your requirements).
Rather than looping at very small steps across your entire range of possible values, you can vectorise, start with a coarser range of X values and get a much better idea of where your solution probably lies, for example:
X = 0:1:100
M=(((sqrt(2*X)-(1/3)).^2).*(2*X-1));
N=(( 10.99743./sqrt(X)-(23/30)).^2).*(( 53.75263./X)-1);
Y = abs(M-N);
plot(X,Y);
Then find the minimum difference between M and N, reduce your step size and range, and continue until you get to a value for X for which the value of abs(M-N) is below your tolerance (required accuracy of your solution).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Following is a part of a code I am writing in matlab, here I want to carry out the following simple mathematical operation [A][X]=[B], where [X] is unknown. In my case I have length of k around 1600000. So all I want is to get the values for g1,g2 and g3 for each element on the array. I have tried the following
k31 = omega3./(d)
k32 = omega3_2./(d)
A = [2,1,5;-2,-1,-5];
X = [g1;g2;g3];
for ii = 1:length(k31)
B = [k31(ii); k32(ii)];
X = pinv(A).*B;
end
display(g1,g2,g3)
I am using pseudo-inverse so basically I can get a solution for each X and I have made some edit there....and x is unknown, MATHEMATICALLY it can be done, but am not able to code it
Also how do I plot the values of g1 g2 g3 with x and y as follows scatter(x(1:end-1), y(1:end-1), 5, g1); scatter(x(1:end-1), y(1:end-1), 5, g2) and scatter(x(1:end-1), y(1:end-1), 5, g3)
I have to make a few assumptions here, so bear with me.
I suspect you want to do this:
k31 = omega3./(d)
k32 = omega3_2./(d)
A = [2,1,5;-2,-1,-5];
X = cell(length(k31),1);
for ii = 1:length(k31)
X{ii} = A\[k31(ii); k32(ii)];
end
which uses the backslash operator instead of inv or pinv. Type help slash to get more information.
The backslash operator will usually be much faster and more accurate than inv or pinv. It is also a lot more flexible -- your case is underdetermined (you are 1 equation short of being able to solve explicitly), in which case the backslash operator will find you a least-squares solution.
Note how I save all results in a cell-array X. This means that the nth solution will be accessible via
X{n} % == [g1(n) g2(n) g3(n)]
In my opinion you are better off creating a pseudo inverse from the singular value decomposition. Moore-Penrose pseudo inverse will work, but I think it gives some weird results sometimes. The least squares can be unstable, especially since the rank of your example matrix is not full.
Also; don't calculate the inverse for every iteration!
Here is an example, where rank-deficiency of A is taken care of:
A = [2,1,5;-2,-1,-5];
% pseudo inverse of A
[m,n] = size(A);
% get SVD
[U,S,V] = svd(A);
% check rank
r = rank(S);
SR = S(1:r,1:r);
% make complete if rank is not full
SRc = [SR^-1 zeros(r,m-r);zeros(n-r,r) zeros(n-r,m-r)];
% create inverse
A_inv = V*SRc*U.';
X=[];
for i = 1:1600
% this actually takes most of the time
k31 = rand(1000, 1);
k32 = rand(1000, 1);
B = [k31';k32'];
% X is overwritten on every loop...
X = [X A_inv*B];
end
N_xy = 1000;
x = rand(N_xy,1);
y = rand(N_xy,1);
g1 = X(1,1:N_xy);
figure(1), clf
scatter(x,y,5,g1)
I didn't plot all 1600000 points since that can't be what you want