Matlab file name with zero-padded numbers - matlab

I have 11x11 matrices and I saved them as .mat files from F01_01 to F11_11.
I have to run a function Func on each file. Since it takes a long time, I want to write a script to run the function automatically:
for i=01:11
for j=01:11
filename=['F',num2str(i), '_', num2str(j),'.mat'];
load(filename);
Func(Fi_j); % run the function for each file Fi_j
end
end
But it doesn't work, Matlab cannot find the mat-files.
Could somebody please help ?

The problem
i=01;
j=01;
['F',num2str(i), '_', num2str(j),'.mat']
evaluates to
F1_1.mat
and not to
F01_01.mat
as expected.
The reason for this is that i=01 is a double type assignment and i equals to 1 - there are no leading zeros for these types of variables.
A solution
a possible solution for the problem would be
for ii = 1:11
for jj= 1:11
filename = sprintf('F_%02d_%02d.mat', ii, jj );
load(filename);
Func(Fi_j); % run the function for each file Fi_j
end
end
Several comments:
Note the use of sprintf to format the double ii and jj with leading zero using %02d.
You can use the second argument of num2str to format its output, e.g.: num2str(ii,'%02d').
It is a good practice to use string formatting tools when dealing with strings.
It is a better practice in matlab not to use i and j as loop counters, since their default value in matlab is sqrt(-1).

Here is an alternate solution, note that the solution by #Shai is more easily expanded to multiple digits but this one requires less understanding of string formatting.
for i=1:11
for j=1:11
filename=['F',num2str(floor(i/10)),num2str(mod(i,10)) '_', num2str(floor(j/10)),num2str(mod(j,10)),'.mat'];
load(filename);
Func(Fi_j); % run the function for each file Fi_j
end
end

The num2str can do zeropadding to fill the field. In the example below 4 is the desired field width+1.
num2str(1,'% 04.f')
Ans = 001

Related

Add a delimiter to end of each line of csv file MATLAB

I am appending to a csv file. The current code outputs a line: a;b;c;d
I need it to output a;b;c;d;
notice the extra ';' at the end of d. That is essential
matrix = [a,b,c,d]
dlmwrite('matrix.csv', matrix, 'delimiter',';','-append','roffset',0, 'precision',14)
any help would be appreciated.
I have had to keep variables a,b,c and d as numbers, or it makes it a character vector (or something) which makes my csv look funny
I've always had problems with the MatLab inbuild CSV writing methods. Why don't you code your own .CSV writing method?
Here, you could make a function something like:
function write_to_csv(filepath, matrix)
csv = fopen(filepath, 'a+'); % check what sort of open you'd like : https://uk.mathworks.com/help/matlab/ref/fopen.html#inputarg_permission
for ii = 1 : numel(matrix) % this loop depends on the dimensions of your matrix
fprintf(csv, '%s;', matrix(ii)); % check fprintf return type, depending on the data in the matrix : https://uk.mathworks.com/help/matlab/ref/fprintf.html?searchHighlight=fprintf&s_tid=doc_srchtitle#inputarg_formatSpec
end
fclose(csv);
end
This works for a 1D matrix you've supplied, run with:
write_to_csv('matrix.csv',matrix)

Showing command line output without all of the newlines

Let's just say I type 2+3 in MATLAB. It gives me this output :
>> 2+3
ans =
5
Why is the output coming after 2 newlines? How do I correct this ?
Ideally, I would get the following output
ans = 5
You can use the format command to change how the display of variables when printed. In your case, you'll likely want to use the 'compact' option
format compact
This will remove all of the unnecessary newlines.
2+3
% ans=
% 5
Unfortunately, there is no built-in way to display it all on the same line because MATLAB's display is built to deal with multi-dimensional data. You could overload the display command if you really wanted. You can create a folder named #double and then a function named display inside of that
#double/
display.m
Then inside of display.m you could do something like this
function display(x)
% If it's a scalar, then show it all on one line
if isscalar(x)
fprintf('%s = %g\n', inputname(1), x);
else
% Otherwise use the built-in display command
builtin('display', x)
end
end
Then it will automatically be used when you have a double variable
>> 2 + 3
% ans = 5
If you wanted to overload the display of other types of data (uint16, int8, uint8), you would need to do the same as above except put a copy within their # folders as well.

Outputting a word file using Matlab

I want to write a function that takes number n as input, then outputs a tab separated word document that looks like 5 rows of:
1 2 3...n n n-1 n-2 ..1
Let me tell you what I have tried already: It is easy to create a vector like this with the integers I want, but if I save a file in an ascii format, in the output the integers come out in a format like " 1.0000000e+00".
Now I googled to find that the output can be formatted using %d and fprintf, but given the row length is part of the input, what would be the most efficient way to achieve it?
maybe something like this:
Nrow = 5;
N = 10;
dlmwrite('my_filename.txt', repmat([1:N, N:-1:1], Nrow, 1), 'delimiter', '\t', 'precision', '%d');
If you mean a normal *.txt kind of file, I would normally use a for loop with fprintf(fileid,'%d things to print',5), with the appropriate fopen(.) statement. You'd be surprised what a good job fopen with 'w' and 'a' does. Try it and let us know!
In response to rayryeng: You are right! Here is a sample of code for writing a matrix to file using fprintf, without a for-loop.
A=rand(5);
fid=fopen('Rand_mat.txt','w');
fprintf(fid,'%0.4f %0.4f %0.4f %0.4f %0.4f\n',A');
fclose (fid);
where A is transposed because MATLAB reads the columns of the matrix first.
Thanks!

csvwrite in loop with numbered filenames in matlab

kinda new to matlab here, searching the csvwrite tutorial and some of the existing webportals regarding my question couldn't find a way to pass my variables by value to the output file names while exporting in csv; providing my bellow scripts, i would like to have the output files something like output_$aa_$dd.csv which aa and dd are respectively the first and second for counters of the scripts.
for aa=1:27
for dd=1:5
M_Normal=bench(aa,dd).Y;
for j=1:300
randRand=M_Normal(randperm(12000,12000));
for jj = 1:numel(randMin(:,1)); % loops over the rand numbers
vv= randMin(jj,1); % gets the value
randMin(jj,j+1)=min(randRand(1:vv)); % get and store the min of the selction in the matix
end
end
csvwrite('/home/amir/amir_matlab/sprintf(''%d%d',aa, bb).csv',randMin);
end
end
String concatenation in MATLAB is done like a matrix concatenation. For example
a='app';
b='le';
c=[a,b] % returns 'apple'
Hence, in your problem, the full path can be formed this way.
['/home/amir/amir_matlab/',sprintf('%d_%d',aa,bb),'.csv']
Furthermore, it is usually best not to specify the file separator explicitly, so that your code can be implemented in other operating systems. I suggest you write the full path as
fullfile('home','amir','amir_matlab',sprintf('%d_%d.csv',aa,bb))
Cheers.

In Matlab, how do you execute an fprintf command on an arbitrarily large matrix

I am working on analysis of a large data set using matlab. I would like to be able to run something along the lines of the fprintf command on this matrix, which has about 22000 columns. So, here is what I had in mind so far:
j=22;
for i = 1:j;
fname = fopen(strcat('chr', num2str(i), '.out'), 'r');
A = fscanf(fname, '%d', [1000,inf]);
FIDW = fopen(strcat('chrproc', num2str(i), '.out'), 'w+');
fprintf(FIDW, '%d\t%d\t%d\t%d\t%d\t%d\t\n', B);
end
there are 22 files this size that will be turned into matrices via lines 1-4. However, the tricky part (at least for me) is that fprintf asks you for the FORMAT. Because these files are so large, there is no real way to enter in %d\t.
Perhaps the fgetl command is better? But fgetl does not print to a file, and more importantly, fgetl returns a string, which does not work well for me. Really, something like the fscanf command would be great, except that reads instead of printing...
Thank you very much for your help and advice.
You may use one of the options described in this matlab doc. The possibilities are:
save -ascii (beware of the scientific notation)
dlmwrite
fprintf as you mentionned, with having format defined as fmt = repmat('%d\t',1,8); (8 to be replaced by your actual number of columns)
Alternatively, you can use the following File Exchange function called saveascii.
Marsei's answer is correct. However in matlab coder I had to take a different approach (works in regular matlab also):
function printmatrix(matrix)
matrix = matrix';%transpose
[rows, cols] = size(matrix);
format=['%-10g ' 0];
for i=1:cols
for j=1:rows
fprintf(format,matrix(j,i));%Flipped because of matlab
end
fprintf('\n');
end
fprintf('Size of matrix: %g x %g\n', cols, rows);%Backwards because we invert it.
end
See:
https://stackoverflow.com/questions/38601352/how-to-print-a-matrix-in-matlab-coder
This also works (but not in matlab coder):
m=magic(5);
[rows cols] = size(m);
x = repmat('%4.0f\t',1,(cols-1));
fprintf([x,'%4.0f\n'],m');