Saving binary file in Matlab in a loop? - matlab

Consider a matrix A in Matlab of dimension mxn and suppose I want to save it as a binary file test.dat using
File_id = fopen('test.dat', 'w');
fwrite(File_id, A, 'float32');
fclose(File_id);
Now suppose that A is created within a loop for h=1:100: how can I assign to the binary files the names test1.dat, test2.dat,...,test100.dat? In other words this is what I want to do and my question is related to step 2):
%for h=1:H
%1)do something that creates A
%2) Save A using
%File_id = fopen('test'h'.dat', 'w'); %clearly wrong
%fwrite(File_id, A, 'float32');
%fclose(File_id);
%end

In the code you posted, the line:
%File_id = fopen('test'h'.dat', 'w'); %clearly wrong
should read:
File_id = fopen(strcat('test',num2str(h),'.dat'),'w');
and that should do the trick nicely.

Related

Open .mtx file in MATLAB

I have a .mtx file which contains a vector which I am suppose to use for matrix vector multiplication. I tried to open the file using
fopen('filename') but this does not work, it returns a single number. I have also tried using readmtx but this gives me the following error: File size does not match inputs. Expected a file size of 232316 bytes. Instead the file size is
365 bytes. Could you please advise how I can open and work with this type of file in MATLAB.
fopen('filename') outputs only the fileID, which is typically an integer >3. This fileID can be used with e.g. fscanf(fileID) to get the content of the file.
For the .mtx format, where each line contains [row-number column-number matrix-entry], you could also do something like:
%% file
filename = 'my_matrix.mtx';
%% read Matrix
Mat = read_mtx(filename);
%% function
function Mat = read_mtx(filename)
% open file
fID = fopen(filename,'r');
M = fscanf(fID, '%f');
% reshape M vector into Nx3 matrix
M = reshape(M, [3, length(M)/3])';
% assemble final matrix
Mat = zeros(M(end,1),M(end,1));
for ii = 1:size(M,1)
Mat(M(ii,1),M(ii,2)) = M(ii,3);
end
end

Matlab : How to open several .txt files using their names for variable names

I have several .txt files of 2 columns, that I’d like to import and use the second column for subsequent operations. My text files are name as: profileA1.txt, profileA2.txt, etc… and my variables corresponding to the data of the second column are named in the subsequent code are A1, A2, A3, etc…
The code works but currently I have to open manually each .txt file with the Import data wizard, change the name of the second column and click on the import the selection. I tried to write a code (see below) to automatize these steps but it doesn’t work? Anyone has any idea to fix this code?
Thanks
for k = 1:5
myfilename = sprintf('profileA%d.txt', k);
mydata = importdata(myfilename);
Aloop = ['A' num2str(k)];
A{k} = load(myfilename.data(:,2), k);
end
You're example is a little off because you convert myfilename from a character array to a structure magically. I would approach this by reading the entire text file into a cell array of characters then using cellfun and textscan to read in the columns. Like this:
function C = ReadTextFile(infile)
if (exist(infile, 'file') ~= 2)
error('ReadTextFile:INFILE','Unknown file: %s.\n', infile);
end
fid = fopen(infile, 'r');
C = textscan(fid, '%s', 'delimiter','\n');
C = C{1};
fclose(fid);
end
% assign an output file
outFile = 'SomeRandomFile.mat';
for k = 1:5
C = ReadTextFile(sprintf(‘profileA%d.txt’, k));
val = cell2mat(cellfun(#(x) textscan(x, '%*f %f','CollectOutput',1),C));
varName = sprintf('A%d', k);
assignin('base', varName, val);
save(outFile, varName, '-append')
end
You can skip the whole reading as a character array first but I have that function already so I just reused it.

Matlab: Import multiple numeric csv .txt files into single cell array

I have multiple (say N of them) .txt files consisting of numeric csv data in matrix form. I would like to import each of these data files into one (1 x N) cell array, whilst preserving the original matrix form. If the original data is small, say 3x3, then textscan does the job in the following manner:
fileId = fopen('data1.txt');
A{1} = textscan(fileID, '%d %d %d', 'delimiter',',','CollectOutput',1);
(This will be part of a function.) But what if my .txt files have 100 columns of data? I could write '%d' 100 times in the formatSpec, but there must be a better way?
This seems to be an easy problem, but I'm quite new to Matlab and am at a loss as to how to proceed. Any advice would be much appreciated, thanks!!
For such cases with consistent data in each of those text files, you can use importdata without worrying about format specifiers. Two approaches are discussed here based on it.
Approach 1
filenames = {'data1.txt' 'data2.txt' 'data3.txt'}; %// cell array of filenames
A = cell(1,numel(filenames)); %// Pre-allocation
for k = 1:numel(filenames)
imported_data = importdata(char(filenames(k)));
formatted_data = cellfun(#str2num, imported_data, 'uni', 0);
A{k} = vertcat(formatted_data{:})
end
Approach 2
Assuming those text files are the only .txt files in the current working directory, you can directly get the filenames and use them to store data from them into a cell array, like this -
files = dir('*.txt');
A = cell(1,numel(files)); %// Pre-allocation
for k = 1:numel(files)
imported_data = importdata(files(k).name);
formatted_data = cellfun(#str2num, imported_data, 'uni', 0)
A{k} = vertcat(formatted_data{:})
end

Reading CSV with mixed type data

I need to read the following csv file in MATLAB:
2009-04-29 01:01:42.000;16271.1;16271.1
2009-04-29 02:01:42.000;2.5;16273.6
2009-04-29 03:01:42.000;2.599609;16276.2
2009-04-29 04:01:42.000;2.5;16278.7
...
I'd like to have three columns:
timestamp;value1;value2
I tried the approaches described here:
Reading date and time from CSV file in MATLAB
modified as:
filename = 'prova.csv';
fid = fopen(filename, 'rt');
a = textscan(fid, '%s %f %f', ...
'Delimiter',';', 'CollectOutput',1);
fclose(fid);
But it returs a 1x2 cell, whose first element is a{1}='ÿþ2', the other are empty.
I had also tried to adapt to my case the answers to these questions:
importing data with time in MATLAB
Read data files with specific format in matlab and convert date to matal serial time
but I didn't succeed.
How can I import that csv file?
EDIT After the answer of #macduff i try to copy-paste in a new file the data reported above and use:
a = textscan(fid, '%s %f %f','Delimiter',';');
and it works.
Unfortunately that didn't solve the problem because I have to process csv files generated automatically, which seems to be the cause of the strange MATLAB behavior.
What about trying:
a = textscan(fid, '%s %f %f','Delimiter',';');
For me I get:
a =
{4x1 cell} [4x1 double] [4x1 double]
So each element of a corresponds to a column in your csv file. Is this what you need?
Thanks!
Seems you're going about it the right way. The example you provide poses no problems here, I get the output you desire. What's in the 1x2 cell?
If I were you I'd try again with a smaller subset of the file, say 10 lines, and see if the output changes. If yes, then try 100 lines, etc., until you find where the 4x1 cell + 4x2 array breaks down into the 1x2 cell. It might be that there's an empty line or a single empty field or whatever, which forces textscan to collect data in an additional level of cells.
Note that 'CollectOutput',1 will collect the last two columns into a single array, so you'll end up with 1 cell array of 4x1 containing strings, and 1 array of 4x2 containing doubles. Is that indeed what you want? Otherwise, see #macduff's post.
I've had to parse large files like this, and I found I didn't like textscan for this job. I just use a basic while loop to parse the file, and I use datevec to extract the timestamp components into a 6-element time vector.
%% Optional: initialize for speed if you have large files
n = 1000 %% <# of rows in file - if known>
timestamp = zeros(n,6);
value1 = zeros(n,1);
value2 = zeros(n,1);
fid = fopen(fname, 'rt');
if fid < 0
error('Error opening file %s\n', fname); % exit point
end
cntr = 0
while true
tline = fgetl(fid); %% get one line
if ~ischar(tline), break; end; % break out of loop at end of file
cntr = cntr + 1;
splitLine = strsplit(tline, ';'); %% split the line on ; delimiters
timestamp(cntr,:) = datevec(splitLine{1}, 'yyyy-mm-dd HH:MM:SS.FFF'); %% using datevec to parse time gives you a standard timestamp vector
value1(cntr) = splitLine{2};
value2(cntr) = splitLine{3};
end
%% Concatenate at the end if you like
result = [timestamp value1 value2];

Add "x,y,z," to first line of .txt file in Matlab

I am working with Matlab code that writes coordinates to a text file as follows:
838959.41800,4713239.59000,1.00000,841305.41800,4708452.59000,1.00000,839175.41800,4712582.59000,1.00000
In the past, I've had to open each file individually and add the following to the first line of the .txt document:
x,y,z,
838959.41800,4713239.59000,1.00000,841305.41800,4708452.59000,1.00000,839175.41800,4712582.59000,1.00000
Any ideas on how to automate this process by embedding code which will write "x,y,z," to the first line of the Matlab output?
Thanks much,
-Aaron
Here is an example:
x = rand(1,3);
y = rand(1,3);
z = rand(1,3);
fid = fopen('data.txt','wt');
fprintf(fid, 'x,y,z,\n');
fprintf([repmat('%.6f,',[1 8]) '%.6f\n'], x,y,z)
fclose(fid);
The output file:
data.txt
x,y,z,
0.694829,0.317099,0.950222,0.034446,0.438744,0.381558,0.765517,0.795200,0.186873