I have 3 vectors of variable lengths but bounded between 1 and 5 (both inclusive). I need to print them out (in a "nice" way) while the code runs.
Nice := I want to let all the vectors be printed in such a way that the starting value of each vector in each iteration is aligned.
What I have tried:
Current Bad Version
for it=1:length(a)
fprintf(' %4.4f ',a(it))
end
and similar for other two.
This makes them misaligned. If the first vector is only length 1, everything gets messed up.
Sloppy Output Version
I filled up the empty locations with 0 and printed
for it=1:5
fprintf(' %4.4f ',a(it))
end
but this is sloppy since it gives the reader the wrong impression. The reader will believe that the vector is full length with values 0.
However, this prints it out correctly. All the vectors are appropriately aligned.
Sample
In my code a,b,c are numbers but suppose a,b,c were list of strings. a is the animals I saw today, b is what i ate for lunch and c is where i went today. They vary from day to day.
EDIT : On the last line, Elephant should be RED (in the correct version).
Modifying your "sloppy version", you can just print spaces rather than zeros:
for it=1:5
if a(it) == 0
% print 11 spaces
fprintf(' ')
else
fprintf(' %4.4f ',a(it))
end
end
Related
I'm using a numerical integration method to approximate an integral. I need to use a minimum number of iterations that give an answer correct to 5 decimal places.
I cannot seem to find a generalised way of doing this. I've only been able to get it working for some cases.
Here is what I'e tried:
%num2str(x,7) to truncate the value of x
xStr = num2str(x(n),7);
x5dp(n) = str2double(xStr); %convert back to a truncated number
%find the difference between the values
if n>1 %cannot index n-1 = 0
check = x5dp(n)-x5dp(n-1);
end
This will find the first instance at which the first 5dp are the same, it doesn't take into account that changes might occur beyond that point, which has happened, the iteration I am looking for was about 450, but it stopped at 178 due to this.
Then I tried this
while err>errLim & n<1000
...
r = fix(x(j)*1e6)/1e1 %to move the 6th dp to the 1stplace
x6dp = rem(r,1)*10 %to 'isolate' the value of the 6th dp
err = abs(x(j)-x(j-1)) % calculate the difference between the two
%if the 6th decimal place is greater than 5 and err<1e-6
% then the 6th decimal place won't change the value of the 5th any more
if err<errLim && x6dp<5
err=1;
end
...
end
This works for one method and function I tested it one. However when I pasted it into another method for another function, I get the iteration ending before the final result is achieved. the final 4 results are:
4.39045203734423 4.39045305948901 4.39045406364900 4.39045505024365
However, the answer I need is actually 4.39053, this has stopped the iteration about 300 steps too early.
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:
Below is my matlab code snippet for generating first order markov chain. I am having trouble with extending to 2nd order markov chain. Can some one help me in doing so? Any suggestions, hints, links, pseudo-code, algorithm, python or matlab snippets would be helpful.
cdist is the cumulative distribution vector (size-28*1) my 27 symbols. I am writing the output to file called chain.p and q are uniform random numbers. CTRANS is the cumulative matrix corresponding to my first order transition matrix TRANS (which is not shown here, its size is 729*27). CTRANS besides being the cumulative version also has a row vector of zeros appended on top for programming ease. cols is the column size of CTRANS.
%generate sequence according to distribution and transition matrix
fileID = fopen('chain','w');
for k=1:10000
p=rand;
for l=2:numel(cdist)%2 to 28
if ((p >= cdist(l-1)) && (p <= cdist(l)))
fprintf(fileID,'%s\n',num2str(l-1));
q=rand;
for m=2:cols%2 to 28
if ((q >= CTRANS(l,m-1)) && (q <= CTRANS(l,m)))
fprintf(fileID,'%s\n',num2str(m-1));
end
end
end
end
end
fclose(fileID);
I am struggling with the second order case. I can provide more details if required. My input data from where I extract the statistics is english text of length around 4000 characters. I have removed the punctuations etc and converted capital letters to small letters, so now there are 27 symbols where number 1 represents 'a' till 26 represents 'z' and 27 for space. Also I have created the bi-gram distribution vector for the second order case.
Here is my code:
m is the length of the vector y.
1 c=1;
2 cMax=1;
3
4 while c<=m
5
6 if abs((y(c)-y(c+1)))>0.001
7 cMax=cMax+1;
8 end
9
10 c=c+1;
11 end
Essentially, vector y is a vector with a set of integers which has been organised from smallest to greatest, I'm trying to find out how many different values of y there are.
I'm comparing the current value of y to the next value of y and saving how many changes there are in cMax.
I've changed the if logic statement a few times. It has been:
if y(c)~=y(c+1)
And I reversed the if statement like this:
if y(c)==y(c+1)
%do nothing
;
else
cMax=cMax+1;
I'm not sure what I'm doing wrong but the error message is always the same:
error: A(I): Index exceeds matrix dimension.
error: called from:
error: C:\Users\dickweed\Documents\Study\Machine
Learning\Tutorials\ex3\oneVsA ll.m at line 57 [6], column 3 [way before if statement]
error: C:\Users\dickweed\Documents\Study\Machine
Learning\Tutorials\ex3\ex3.m at line 58 [7] , column 14 [after the letter c]
I've bolded where the code indicates the errors in my supplied code.
The columns are wacky, that may be because of the text editor I'm using, but I'm assuming the actual columns mean before the if statement and before the end statement.
Any help would be greatly appreciated.
PS. I'm actually using Octave, and Notepad++. The language is exactly the same, for all intents and purposes, as Matlab hence why I've labelled it Matlab.
I think that your index exceeds matrix dimensions.
Specificaly in the following line:
y(c)-y(c+1)
on the last iteration, when c=m, the second term y(c+1) tries to access an element that doesn't exist.
Suggestion: change your stop condition to:
c<m
Could somebody explain the following code snippet? I have no background in computer science or programming and just recently became aware of Matlab. I understand the preallocation part from data=ceil(rand(7,5)*10)... to ...N*(N-1)/2).
I need to understand every aspect of how matlab processes the code from kk=0 to the end. Also, the reasons why the code is codified in that manner. There's no need to explain the function of: bsxfun(#minus), just how it operates in the scheme of the code.
data=ceil(rand(7,5)*10);
N = size(data,2);
b=cell(N-1,1);
c=NaN(size(data,1),N*(N-1)/2);
kk=0;
for ii=1:N-1
b{ii} = bsxfun(#minus,data(:,ii),data(:,ii+1:end));
c(:,kk+(1:N-ii)) = bsxfun(#minus,data(:,ii),data(:,ii+1:end));
kk=kk+N-ii;
end
Start at zero
kk=0;
Loop with ii going from 1 up to N-1 incrementing by 1 every iteration. Type 1:10 in the command line of matlab and you'll see that it outputs 1 2 3 4 5 6 7 8 9 10. Thuis colon operator is a very important operator to understand in matlab.
for ii=1:N-1
b{ii} = ... this just stores a matrix in the next element of the cell vector b. Cell arrays can hold anything in each of their elements, this is necessary as in this case each iteration is creating a matrix with one fewer column than the previous iteration.
data(:,ii) --> just get the iith column of the matrix data (: means get all the rows)
data(:, ii + 1:end) means get a subset of the matrix data consisting of all the rows but only of columns that appear after column ii
bsxfun(#minus, data(:,ii), data(:,ii+1:end)) --> for each column in the matrix data(:, ii+1:end), subtract the single column data(:,ii)
b{ii} = bsxfun(#minus,data(:,ii),data(:,ii+1:end));
%This does the same thing as the line above but instead of storing the resulting matrix of the loop in a separate cell of a cell array, this is appending the original array with the new matrix. Note that the new matrix will have the same number of rows each time but one fewer column, so this appends as new columns.
%c(:,kk + (1:N-ii)) = .... --> So 1:(N-ii) produces the numbers 1 up to the number of columns in the result of this iteration. In matlab, you can index an array using another array. So for example try this in the command line of matlab: a = [0 0 0 0 0]; a([1 3 5]) = 1. The result you should see is a = 1 0 1 0 1. but you can also extend a matrix like this so for example now type a(6) = 2. The result: a = 1 0 1 0 1 2. So by using c(:, 1:N-ii) we are indexing all the rows of c and also the right number of columns (in order). Adding the kk is just offsetting it so that we do not overwrite our previous results.
c(:,kk+(1:N-ii)) = bsxfun(#minus,data(:,ii),data(:,ii+1:end));
Now we just increment kk by the number of new columns we added so that in the next iteration, c is appended at the end.
kk=kk+N-ii;
end;
I suggest that you put a breakpoint in this code and step through it line by line and look at how the variables change in matlab. To do this click on the little dashed line next to k=0; in the mfile, you will see a red dot appear there, and then run the code. The code will only execute as far as the dot, you are now in debug mode. If you hover over a variable in debug mode matlab will show its contents in a tool tip. For a really big variable check it out in the workspace. Now step through the code line by line and use my explanations above to make sure you understand how each line is changing each variable. For more complex lines like b{ii} = bsxfun(#minus,data(:,ii),data(:,ii+1:end)); you should highlight code snippets and ruin these in the command line to see what each part is doing so for example run data(:,ii) to see what that does and then try data(:,ii+1:end)) or even just ii+1:end (well in that case it wont work, replace end with size(data, 2)). Debugging is the best way to understand code that confuses you.
bsxfun(#minus,A,B)
is almost the same as
A-B
The difference is that the bsxfun version will handle inputs of different size: In each dimension (“direction,” if you find it easier to think about that way), if one of the inputs is scalar and the other one a vector, the scalar one will simply be repeated sufficiently often.
http://www.mathworks.com/help/techdoc/ref/bsxfun.html