I want to calculate L = laplacian(G) from a graph dataset. I imported the dataset which contains two columns: FromNodeId and ToNodeId:
# Nodes: 3997962 Edges: 34681189
# FromNodeId ToNodeId
0 1
0 2
0 31
0 73
0 80
0 113619
0 2468556
0 2823829
0 2823833
0 2846857
0 2947898
0 3011654
0 3701688
0 3849377
0 4036524
0 4036525
0 4036527
0 4036529
0 4036531
0 4036533
0 4036534
0 4036536
0 4036537
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
To do so, I need to find G first so I use G = graph(FromNodeId, FromNodeId). When I did that, I got this error:
>> G = graph(fromNodeId,toNodeId)
Error using matlab.internal.graph.MLGraph
Source must be a dense double array of node indices.
Error in matlab.internal.graph.constructFromEdgeList (line 125)
G = underlyingCtor(double(s), double(t), totalNodes);
Error in graph (line 264)
matlab.internal.graph.constructFromEdgeList(...
I don't know why! Can I get a solution of that? Thank you.
Turns out the problem lies in the fact that no zeros are allowed when using the Graph function in this manner. (See: Target must be a dense double array of node indices. How to Solve?)
I downloaded the dataset and ran it successfully with the following code. Note that this code uses a system command and is not compatible with all operating systems, but it should be simple enough to rewrite to whatever operating system you use. It also assumes the .txt file to be in the working directory.
% Removes first lines with comments in them; this system command was tested on Linux Ubuntu 14.04 and is probably not portable to Windows.
% If this system command doesn't work, manually remove the first four lines from the text file.
system('tail -n +5 com-lj.ungraph.txt > delimitedFile.txt');
% Read the newly created delimited file and add 1 to all nodes.
edges=dlmread('delimitedFile.txt')+1;
% Build the graph
G=graph(edges(:,1),edges(:,2));
Assuming you've build your arrays similarly to how I did it, adding 1 to FromNodeIdFull and ToNodeIdFull should resolve your problem. In other words, the following code snippet should solve your problem; if it doesn't I advise you to rewrite based on the code presented above.
G=graph(FromNodeIdFull+1,ToNodeIdFull+1);
Leaving my old answer here, as deleting it may cause confusion for others reading both this answer and the comments to it. Note that the answer below did NOT resolve the issue.
Just putting the comments by myself and NKN into an answer:
The problem lies in the fact that the arrays are sparse but graph() seems to expect full arrays. The following should work:
FromNodeIdFull=full(double(FromNodeId));
ToNodeIdFull=full(double(ToNodeId));
G=graph(FromNodeIdFull,ToNodeIdFull);
Depending on whether your input arrays are already doubles or not you may be able to remove the double() from the first two lines.
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:
I need some help of solving that issue: I have 5 different voltage values that change every single tick time - that mean every single moment. I need to sort them and after they been sorted I want to go to another matrix(like this one at the bottom) and to pull out(read) specific column from it, for every state pre define(timing that I am designing..) That mechanism change every single states/moment. How can I do this ?
The Matrix look like(and could be greater...):
0 0 0 1 1 1...
0 1 1 0 0 1...
1 0 1 0 1 0...
1 1 0 1 0 0...
.. .. .. .. .. ..
Thanks, Henry
I am not sure I understood it correctly. So I will edit my answer after you make your question a bit more clear.
I see two separate things:
Reading 5 voltage values which change at each step. You want to sort these values. To do this you can use the sort function of matlab. It is really easy to use and you can look at it here.
This is the part I didn't understand well. After sorting the voltage readings what do you want to do with the matrix ? If you want to access just a specific column of the matrix and save it in a variable you can do it in this way. Let's assume you have a matrix A which is N x N, if you want to access the 10th column of the matrix and store it in a variable called column10 you will do something like: column10 = A(:,10)
I hope this will help you but let me know if this is what you wanted and I will edit my answer according to it.
Fab.
The problem is to check if sequence is palindrome using Brainfuck.
input is a sequance of numbers
output 0 if it is not palindorme, else 1.
I have one idea:
Say, we have sequance 1 2 3 2 1. We can memorise first cell from our array in variable(do this using operation '!'),
then change 1 to 0(do this using operation '0'),array will be 0 2 3 2 1,
then we go to the end of array until we meet 0 (do this using
'>[>]'),
then we take number from variable and get sequance 0 2 3 2 1 1.
Next step should be to compare two last numbers, if they are equal continue algo from begining else do something...
I do not know how to implement last step.
please excuse me if I won't write the entire program in brainfuck,
This is the main idea:
Read input (pointer should be at last character afterwards)
memorize character
Set value to 0
Go to first [<]
Compare to memorized character (see Brainfuck compare 2 numbers as greater than or less than)
If not equal, print 1
If the next (>) cell array is 0, print 0
Move to pointer to end [>]
Go back to step 2
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.