I'm trying to create a random "path" on a coordinate system on Matlab. I am doing this by creating a for loop where for each iteration it fills in a new value on a matrix that has initial values of zeros.
For example, I have 5 points so I have an initial matrix a=[0 0 0 0 0; 0 0 0 0 0] (row1 = x values, row2 = y values).
The path can move right/left or up/down (no diagonals). In my for loop, I call randi(4) and say something like "if randi(4)=1, then move 1 point to the left (x-1). if randi(4)=2, then move to the right (x+1), etc."
The problem is that you cannot visit a specific point more than once. For example, the path can start at (0,0), then go to (0,1), then (1,1), then (1,0), and then it CANNOT go back to (0,0).. in my current code I don't have this restriction so I was hoping I could get some suggestions..
Since in this example the matrix would look something like a=[0 0 1 1 0; 0 1 1 0 0].
I was thinking of maybe subtracting each new coordinate (here (0,0)) from each column on the matrix a and if any of the columns give me values of zero for both rows (since it's the same coordinate subtracted from itself), then go back one step and let randi(4) run again.. but
How could I tell it to "go back one step" (or two or three)?
How do you compare one column against each column of the already established matrix?
This was just an idea.. are there any functions in Matlab that would let me do this? or maybe compare if two columns are the same within a matrix?
To your questions.
to go back - I suppose this means just throwing away the rightmost columns in your matrix.
to find if it is present you could use ismember
unfortunately it only takes rows so you will need to transpose. Snippet:
a = [1:10; repmat(1:2,1,5)]'
test = ismember(a,[3,2],'rows')
any(test) % not found
test = ismember(a,[3,1],'rows')
any(test) % found
Of course your idea would also work.
I can answer this:
How do you compare one column against each column of the already
established matrix?
Use two different matrices. Compare them using the setdiff() function: http://www.mathworks.com/help/matlab/ref/setdiff.html
Related
I have a struct like this mesh.m_1_0.Deformation_Entformung;
the second field is a struct from m_1_0 till m_3_5 in 6 steps;
the Deformation_Entformung is a matrix with 6 columns and 325562 rows, whereby the first 3 columns contain coordinates (x,y,z).
Now I'm interested in the coordinates that are the closest to (33.5 -88.7801,-0.4480).
This is my code:
SNames = fieldnames(mesh); % SName = m_1_0,m_1_5...m_3_5
for loopIndex = 1:numel(SNames)
stuff = mesh.(SNames{loopIndex}).Deformation_Entformung;
mesh.(SNames{loopIndex}).('Deformation_Entformung_Koordi')=...
stuff(min(stuff(:,1)-33.5) & min(stuff(:,2)--88.7801) & ...
min(stuff(:,3)-0.4480), :);
end
The code runs, but the problem is that the answer is always the first row of the matrix Deformation_Entformung.
I would be glad, if someone could give me a hint.
Well, first of all you mix up indices with values.
min(stuff) returns the minimal value of stuff. So when you write stuff(min(stuff)) that's certainly not doing what you want it to do.
Secondly, if min(stuff(:,1)-33.5) would actually return an index (which it doesn't), then the index would be the same whether you searched for min(stuff(:,1)+100) or min(stuff(:,1)-500000). So the program would still not be doing what you want it to do.
Additionally, the way you are trying to search for the closest point does not even work from a mathematical point of view (even if your programming had no errors). The closest point is not necessarily the closest in each single coordinate. For example, [1 1 1] is certainly closer to [0 0 0] than [20 0 0], [0 20 0] and [0 0 20]. But it is not the closest one in each single coordinate. In fact it is not the closest one in any coordinate.
There might be even more issues with your code, but for starters you should work on how to determine distances. After you master that you should try to pick points with minimal distance. And only after you master both of these should you try to integrate everything into the rest of your stuff. No point in trying to do everything at once.
I would like to highlight or identify a column in a matrix with a specific value in MATLAB. Suppose I have a matrix A = [1 0 1 1 0 1; 1 1 0 0 0 1; 1 0 1 1 0 1; 0 1 1 0 0 1].
The result of the above matrix is a 5th column, as it contains all zeroes. I am also wondering if I could highlight the resulting column for identification. Please help me. I have a very large matrix to work on applying this principle.
How about combining find and all to get the column index of the all-zero column like this?
A = [1 0 1 1 0 1; 1 1 0 0 0 1; 1 0 1 1 0 1; 0 1 1 0 0 1];
ind = find(all(A==0,1))
ind =
5
The second input argument to all is to specify that it's along the first dimension, i.e. rows. It's not really necessary here, but I find that it's a good practice as you're always sure it's the right dimension. This is especially important if there are scenarios where you might get a 1xn vector instead of mxn.
Create a colored matrix:
This is a hack, and I don't necessarily recommend it, but if you really want to do this in MATLAB, this is an alternative. Also, I think you might learn quite a lot about MATLAB when doing this, so it might be worth the time.
You can create a colored plot with all values 1 except those in column 5 that will be 0 (or the other way around, doesn't matter) using imagesc. This will give a plot with only two colors, one for those values that are 1, and one for those that are 0. You can select which colors you want with colormap. Then you create a mesh to determine the location of all the values you want to show, convert the matrix to strings using num2str, and combine it all. You need to experiment some to get the correct locations, as you probably want less padding between the rows than the columns. You can use this answer as a guide. In the end, remove the axes. It should be fairly simple to adapt if you read and try to understand each line of the referenced answer.
The simple approach:
I have a very large matrix...". Such matrices are often not a good idea to include in a report. However, if you really want to, I actually suggest you copy paste it from the variable explorer and into MS Excel (or use xlswrite if you're doing this more than once). Since you know which column you want to color, it should be fairly simple to click the "color button".
The following displays the matrix in the command window with the matching columns in boldface. There may be several matching columns, and arbitrary column values can be matched.
A = [1 0 1 0 0 1; 1 1 0 1 0 1; 1 0 1 0 0 1; 0 1 1 1 0 1]; %// matrix
c = [0;1;0;1]; %// column to be matched
nn = find(all(bsxfun(#eq, A, c),1)); %// indices of matching columns
s = cellstr(num2str(A)); %// cell array of strings, one for each row; all same length
for n = nn %// for each matching column, with index n
s = regexprep(s, '\S+', '<strong>$0</strong>', n); %// make bold n-th value of each cell
end
s = vertcat(s{:}); %// convert back into a char array; all strings have the same length
disp(s); %// display
The result in this example is
Highlighting with red (stderr)
Just for proof of concept, you could highlight some of your data in the command window, although I wouldn't suggest actually doing this. Consider the following code:
A=randi(10,8);
%ind = find(all(A==0,1),1) %for actual data
ind = 5; %manual choice for demonstration
for k=1:size(A,1)
fprintf('%5d ',A(k,1:ind-1));
fprintf(2,'%5d ',A(k,ind));
fprintf('%5d ',A(k,ind+1:end));
fprintf('\n');
end
First we create a dummy matrix for demonstration purposes, and select column ind to highlight. Then we go along from line to line in A, we use fprintf(...) to write the non-highlighted values with a given format, then use fprintf(2,...) to write to stderr in red, then write the rest of the line, then newline. Note that for some reason fprintf(2,...) will not highlight the final character, I guess because usually this is \n and nobody noticed that highlighting is missing there.
Also, you can play around with the formats inside fprintf to suit your needs. If you need to print floating points, something like '%10.8f' might work. Or '%g'. The main point is to have a fixed width+precision for your print in order to get pretty columns.
For the sake of completeness, you can make it even a bit more messy to treat multiple highlightable columns:
A=randi(10,8);
%ind = find(all(A==0,1)) %for actual data
ind=[5 2];
fprintf('A = \n\n');
for k1=1:size(A,1)
for k2=1:size(A,2)
if ismember(k2,ind)
fprintf(2,'%5d ',A(k1,k2));
else
fprintf('%5d ',A(k1,k2));
end
end
fprintf('\n');
end
fprintf('\n');
I also added some extra printouts to make it prettier. Result:
Highlighting with blue (links)
As an afterthought, after some discussion with Luis Mendo, I decided that it's worth overdoing a bit while we're at it. You can turn your numbers into blue-and-underlined hyperlinks, making use of the built-in parsing of the link HTML tag implemented both in disp and in fprintf. Here's the corresponding code:
A=randi(10,8);
ind=[5 2];
fieldlen=5; %width of output fields, i.e. 5 in '%5d'
fprintf('A = \n\n');
for k1=1:size(A,1)
for k2=1:size(A,2)
if ismember(k2,ind)
fprintf([repmat(' ',1,fieldlen-length(num2str(A(k1,k2)))) '%d '],A(k1,k2));
else
fprintf('%5d ',A(k1,k2));
end
end
fprintf('\n');
end
fprintf('\n');
This will turn the elements of the highlighted column(s) into strings of the form '3' for an example value of 3.
Another trick here is that hyperlinks starting with matlab: are parsed as proper matlab commands, which are activated when you click the link. You can try it by typing disp('link') in your command window. By setting ... we make sure that nothing happens when someone clicks on the now-link-valued highlighted numbers.
And on a technical note: we only want to include the actual number in the links (and not the preceding spaces), so we have to manually check the length of the string we are about to print (using length(num2str(A(k1,k2)))) and manually include the rest of the spaces before the number. This is done via the parameter fieldlen which I set at the beginning: this specifies the total width of each printing field, i.e. if we originally had fprintf('%5d',...) then we need to set fieldlen=5; for the same effect. Result:
Introduction to problem:
I'm modelling a system where i have a matrix X=([0,0,0];[0,1,0],...) where each row represent a point in 3D-space. I then choose a random row, r, and take all following rows and rotate around the point represented by r, and make a new matrix from these rows, X_rot. I now want to check whether any of the rows from X_rot is equal two any of the rows of X (i.e. two vertices on top of each other), and if that is the case refuse the rotation and try again.
Actual question:
Until now i have used the following code:
X_sim=[X;X_rot];
if numel(unique(X_sim,'rows'))==numel(X_sim);
X(r+1:N+1,:,:)=X_rot;
end
Which works, but it takes up over 50% of my running time and i were considering if anybody in here knew a more efficient way to do it, since i don't need all the information that i get from unique.
P.S. if it matters then i typically have between 100 and 1000 rows in X.
Best regards,
Morten
Additional:
My x-matrix contains N+1 rows and i have 12 different rotational operations that i can apply to the sub-matrix x_rot:
step=ceil(rand()*N);
r=ceil(rand()*12);
x_rot=x(step+1:N+1,:);
x_rot=bsxfun(#minus,x_rot,x(step,:));
x_rot=x_rot*Rot(:,:,:,r);
x_rot=bsxfun(#plus,x_rot,x(step,:));
Two possible approaches (I don't know if they are faster than using unique):
Use pdist2:
d = pdist2(X, X_rot, 'hamming'); %// 0 if rows are equal, 1 if different.
%// Any distance function will do, so try those available and choose fastest
result = any(d(:)==0);
Use bsxfun:
d = squeeze(any(bsxfun(#ne, X, permute(X_rot, [3 2 1])), 2));
result = any(d(:)==0);
result is 1 if there is a row of X equal to some row of X_rot, and 0 otherwise.
How about ismember(X_rot, X, 'rows')?
I'm very new to Matlab and am creating a simple Tic Tac Toe game where a user plays against the computer. I have 3x3 push buttons in a GUI and for each button's callback I have set it up so that an 'X' will appear if the square is empty, and set a '1' value into a 3x3 zeros matrix in the corresponding spot.
I want to put a 'player2' function after this in each callback so that the computer will find any spot in the matrix that is a zero, randomly pick one and give me the coordinates which I will then translate over to its corresponding push button to place an 'O' there.
The matrix is handles.move=zeros(3,3).
I know I'll probably need to use an 'if' statement, and '[i,j] = find(move==0);' but I don't know what random command to use with this to pick from the zeros that will give me back the coordinates. Any suggestions?
Calling find(move==0) will return linear indices of elements in move which are equal to zero. For example:
move =
1 0 1
0 0 0
0 1 0
>>indices = find(move==0)
indices =
2
3
4
5
8
9
You can take this result and scramble the indices randomly using...
>>scrambled = indices(randperm(length(indices)))
scrambled =
9
2
8
4
3
5
Then choose the first element, scrambled(1), as the computer's next choice. There are probably several ways to go about this. The nice thing about this one is that it can be called until the very end of the game to retrieve the computer's next move.
EDIT:
computerMove = indices(randperm(length(indices),1));
This will return the first element automatically as Dennis pointed out.
Apparently it's a very popular game - have a look here, here, here, here, here, here, here, here, here, here, here.
I have a line of code in matlab for which i am selecting a subset of a matrix:
A(3:5,1:3);
Now i want to adapt this line, to only select rows for which all three values are larger than zero:
(A(3:5,1:3) > 0);
But apparently i am not doing this right. How do i select part of the matrix, and also make sure that only the rows (for which all three values are) larger than zero are selected?
EDIT: To clarify: lets say that i have a matrix of coordinates called A, that looks like this:
Matrix A [5,3]
3 4 0
0 1 0
0 3 1
0 0 0
4 8 7
Now i want to select only part [3:5,1:3], and of that part i only want to select row 3 and 5. How do i do that?
The expression:
A(find(sum(A(3:5,:),2)~=0),:)
will return only the rows of A(3:5,:) which have a row-sum not equal to zero.
If you had posted syntactically correct Matlab it would have been easier for me to cut and paste your test data into my Matlab session.
I'm modelling this answer off of A(find( A > 0 ))
distances = pdist(find( pdist(medoidContainer(i,1:3)) > 0 ));
This will give you a vector of values in the distances variable. The reason the pdist(medoidContainer(i,1:3) > 0) does not work is because it first, finds the indices specified by i,1:3 in medoidContainer. Then it finds the indices in medoidContainer(i,1:3) that are greater than 0. However, since medoidContainer(i,1:3) and pdist now likely have different dimensions, the comparison does not give the right indexes.