How to write multiple matrixes in a textfile in MATLAB? - matlab

I have three matrixes and their sizes are different. I need to write them in a textfile. I've tried to do that writing these:
fileID = fopen('results.txt','w');
fprintf(fileID,'HEADER\n');
fprintf(fileID,'\nmatrix1 = ');
fprintf(fileID,'%d',m1,'\n');
fprintf(fileID,'\nmatrix2 = ');
fprintf(fileID,'%d',m2,'\n');
fprintf(fileID,'\nresult = ');
fprintf(fileID,'%d',m3,'\n');
fclose(fileID);
The result is:
HEADER
matrix1 = 1111121121111111111132133113132333223333213233222212112411442341243123122112323313342431432334132434333341241424433334334333412414244333343321321212221211211222213213122212112112222132232232222231222222344333342243323232333224333343324223233443243343433343333334432433434333433333233443443434443444443444344343433443434443244224343444344444443341442444434434333413133242131123132234344433432434334433124313312212222124222241243323223113222323323343212434321111433213223121241442414334232433243434434412211241211113211121224333412141433122334444444444444444444492110
matrix2 = 1221314111312212211134432433434333433333211212122212112112224334432434244434444492110
result = 1041111041031091131061021111001071031011021061081001091059792110
But this isn't what I need. matrix1's size is 20x28, matrix2's size is 20x4 and matrix3's size is 1x20. They should look like matrixes in the textfile.
I should also write many more matrixes in the same file, so when I need to write something in the file, the previous data shouldn't be deleted.

Here's a function that wraps MathWorks' existing dlmwrite, which represents matrices in a file in the way you want. The wrapper is necessary to allow different naming of multiple variables in the file:
function mwrite(filename, variableName, data, mode)
if nargin < 4, mode = 'w'; end % pass mode 'w' to overwrite or 'a' to append
f = fopen(filename, mode);
fprintf(f, '%s = [', variableName);
if numel(data) == size(data, 2)
fprintf(f, '%s];\n', num2str(data) );
else
fprintf(f, '\n');
fclose(f);
dlmwrite(filename, data, '-append');
f = fopen(filename, 'a');
fprintf(f, '];\n\n');
fclose(f);
end

Related

Load a dataset in matlab for knn classification

Hello guys actually i want to load this dataset in matlab for executing knn classification on it but i dont know how to do so .i have tried load and readtable and ... but it didnt work then i have tried this code
FID=fopen('file','rt');
a=textscan(FID,''...);
But actually i could not find out what is text format to take data that i wanted so it was a dead end does any one can help me with this.please
This is how inside of my data file looks like
enter image description here
this is the dataset file http://lms.ui.ac.ir/public/group/a7/b2/06/6a5fb_24fb.gz
Maybe you can try something as the following:
EDIT: code now imports file correctly
FID = fopen('toy.m','rt');
data = {};
i = 1;
while ~feof(FID)
line = fgetl(FID);
line = fgetl(FID);
if feof(FID)
break;
end
%sprintf('%d %s', i, line) %debug
if (isempty(line))
headers = 3;
elseif (line(1) ~= '#')
headers = 2;
else
headers = 1;
end
rows = textscan(FID, '%s %s %d', 1, 'headerlines', headers);
data{i} = cell2mat(textscan(FID, '', rows{3}, 'headerlines', 2));
i = i + 1;
end
fclose(FID);
fprintf('File contained %d blocks of data\n', i);
fprintf('To access a value in cell "data", for example value (1,2) inside the second matrix, digit "data{2}(1,2)": ');
data{2}(1,2)

How to read a single character in file using MATLAB?

In my file data.txt, I have a string abcdefgh. Now I want to take just 1 character without read whole string. How can I do this in MATLAB?
For example, I want to take the first character, I use c = fscanf(data.txt, '%c'); and c = textscan(data.txt, '%c'); but it read whole line in data.txt. I know that c(1) is my answer but I don't want to do that.
You can limit the number of characters that are read in using the third input to either fscanf or textscan.
fid = fopen('data.txt', 'r');
c = fscanf(fid, '%c', 1);
c = textscan(fid, '%c', 1);
You could also just use a lower-level function such as fread to do this.
fid = fopen('data.txt', 'r');
c = fread(fid, 1, '*char');

Appending data to a file in Matlab, removing before a symbol

I have a file which is written via Matlab from a vector M with binary data values. This file is written with Matlab's fwrite in the following script myGenFile.m of the form function myGenFile(fName, M):
% open output file
fId = fopen(fName, 'W');
% start by writing some things to the file
fprintf(fId, '{DATA BITLENGTH:%d}', length(M));
fprintf(fId, '{DATA LIST-%d:#', ceil(length(M) / 8) + 1);
% pad to full bytes
lenRest = mod(length(M), 8);
M = [M, zeros(1, 8 - lenRest)];
% reverse order in bytes
M = reshape(M, 8, ceil(length(M) / 8));
MReversed = zeros(8, ceil(length(M) / 8));
for i = 1:8
MReversed(i,:) = M(9-i,:);
end
MM = reshape(MReversed, 1, 8*len8);
fwrite(fId, MM, 'ubit1');
% write some ending of the file
fprintf(fId, '}');
fclose(fId);
Now I want to write a file myAppendFile.m, which appends some values to the existing file and has the following form: function myAppendFile(newData, fName). To do this I will have to remove the trailing '}':
fId = fopen(nameFile,'r');
oldData = textscan(fId, '%s', 'Delimiter', '\n');
% remove the last character of the file; aka the ending '}'
oldData{end}{end} = oldData{end}{end}(1:end-1);
The problem is now when trying to write oldData into the file (writing newData should be trivial, since it is also a vector of binary data like M), since it is a cell of cell arrays, containing strings.
How could I overcome this issue and append the new data correctly?
Instead of using textscan which copies the file to your memory, then writes it back, you could use fseek to set the pointer where you want to continue writing. Just put it one char before end of file and continue writing.
fseek(fid, -1, 'eof');

matlab reading variables with varying lengths into the workspace

This is a follow up question to
Reading parameters from a text file into the workspace
I am wondering, how would I read the following:
% ---------------------- details --------------------------
%---------------------------------------------------------------
% location:
lat = 54.35
lon = -2.9833
%
Eitan T suggested using:
fid = fopen(filename);
C = textscan(fid, '%[^= ]%*[= ]%f', 'CommentStyle', '%')
fclose(fid);
to obtain the information from the file and then
lat = C{2}(strcmp(C{1}, 'lat'));
lon = C{2}(strcmp(C{1}, 'lon'));
to obtain the relevant parameters. How could I alter this to read the following:
% ---------------------- details --------------------------
%---------------------------------------------------------------
% location:
lat = 54.35
lon = -2.9833
heights = 0, 2, 4, 7, 10, 13, 16, 19, 22, 25, 30, 35
Volume = 6197333, 5630000, 4958800, 4419400, 3880000, 3340600,
3146800, 2780200, 2413600, 2177000, 1696000, 811000
%
where the variable should contain all of the data points following the equal sign (up until the start of the next variable, Volume in this case)?
Thanks for your help
Here's one method, which uses some filthy string hacking and eval to get the result. This works on your example, but I wouldn't really recommend it:
fid = fopen('data.txt');
contents = textscan(fid, '%s', 'CommentStyle', '%', 'Delimiter', '\n');
contents = contents{1};
for ii = 1:length(contents)
line = contents{ii};
eval( [strrep(line, '=', '=['), '];'] ) # convert to valid Matlab syntax
end
A better method would be to read each of the lines using textscan
for ii = 1:length(contents)
idx = strfind(contents{ii}, ' = ');
vars{ii} = contents{ii}(1:idx-1);
vals(ii) = textscan(contents{ii}(idx+3:end), '%f', 'Delimiter', ',');
end
Now the variables vars and vals have the names of your variables, and their values. To extract the values you could do something like
ix = strmatch('lat', vars, 'exact');
lat = vals{ix};
ix = strmatch('lon', vars, 'exact');
lon = vals{ix};
ix = strmatch('heights', vars, 'exact');
heights = vals{ix};
ix = strmatch('Volume', vars, 'exact');
volume = vals{ix};
This can be accomplished using a 2-step approach:
Read the leading string (first element), equals sign (ignored), and the rest of the line as a string (second element)
Convert these strings-of-the-rest-of-the-lines to floats (second element)
There is however a slight drawback here; your lines seem to follow two formats; one is the one described in step 1), the other is a continuation of the previous line, which contains numbers.
Because of this, an extra step is required:
Read the leading string (first element), equals sign (ignored), and the rest of the line as a string (second element)
This will fail when the "other format" is encountered. Detect this, correct this, and continue
Convert these strings-of-the-rest-of-the-lines to floats (second element)
I think this will do the trick:
fid = fopen('data.txt');
C = [];
try
while ~feof(fid)
% Read next set of data, assuming the "first format"
C_new = textscan(fid, '%[^= ]%*[= ]%s', 'CommentStyle', '%', 'Delimiter', '');
C = [C; C_new]; %#ok
% When we have non-trivial data, check for the "second format"
if ~all(cellfun('isempty', C_new))
% Second format detected!
if ~feof(fid)
% get the line manually
D = fgetl(fid);
% Insert new data from fgetl
C{2}(end) = {[C{2}{end} C{1}{end} D]};
% Correct the cell
C{1}(end) = [];
end
else
% empty means we've reached the end
C = C(1:end-1,:);
end
end
fclose(fid);
catch ME
% Just to make sure to not have any file handles lingering about
fclose(fid);
throw(ME);
end
% convert second elements to floats
C{2} = cellfun(#str2num, C{2}, 'UniformOutput', false);
If you can get rid of the multi-line Volume line, what you have written is valid matlab. So, just invoke the parameter file as a matlab script using the run command.
run(scriptName)
Your only other alternative, as others have shown, is to write what will end up looking like a bastardized Matlab parser. There are definitely better ways to spend your time than doing that!

Outputing cell array to CSV file ( MATLAB )

I've created a m x n cell array using cell(m,n), and filled each of the cells with arbitrary strings.
How do I output the cell array as a CSV file, where each cell in the array is a cell in the CSV 'spreadsheet'.
I've tried using cell2CSV, but I get errors ...
Error in ==> cell2csv at 71
fprintf(datei, '%s', var);
Caused by:
Error using ==> dlmwrite at 114
The input cell array cannot be converted to a matrix.
Any guidance will be well received :)
Here is a somewhat vectorized solution:
%# lets create a cellarray filled with random strings
C = cell(10,5);
chars = char(97:122);
for i=1:numel(C)
C{i} = chars(ceil(numel(chars).*rand(1,randi(10))));
end
%# build cellarray of lines, values are comma-separated
[m n] = size(C);
CC = cell(m,n+n-1);
CC(:,1:2:end) = C;
CC(:,2:2:end,:) = {','};
CC = arrayfun(#(i) [CC{i,:}], 1:m, 'UniformOutput',false)'; %'
%# write lines to file
fid = fopen('output.csv','wt');
fprintf(fid, '%s\n',CC{:});
fclose(fid);
The strings:
C =
'rdkhshx' 'egxpnpvnfl' 'qnwcxcndo' 'gubkafae' 'yvsejeaisq'
'kmsvpoils' 'zqssj' 't' 'ge' 'lhntto'
'sarlldvig' 'oeoslv' 'xznhcnptc' 'px' 'qdnjcdfr'
'jook' 'jlkutlsy' 'neyplyr' 'fmjngbleay' 'sganh'
'nrys' 'sckplbfv' 'vnorj' 'ztars' 'xkarvzblpr'
'vdbce' 'w' 'pwk' 'ofufjxw' 'qsjpdbzh'
'haoc' 'r' 'lh' 'ipxxp' 'zefiyk'
'qw' 'fodrpb' 'vkkjd' 'wlxa' 'dkj'
'ozonilmbxb' 'd' 'clg' 'seieik' 'lc'
'vkpvx' 'l' 'ldm' 'bohgge' 'aouglob'
The resulting CSV file:
rdkhshx,egxpnpvnfl,qnwcxcndo,gubkafae,yvsejeaisq
kmsvpoils,zqssj,t,ge,lhntto
sarlldvig,oeoslv,xznhcnptc,px,qdnjcdfr
jook,jlkutlsy,neyplyr,fmjngbleay,sganh
nrys,sckplbfv,vnorj,ztars,xkarvzblpr
vdbce,w,pwk,ofufjxw,qsjpdbzh
haoc,r,lh,ipxxp,zefiyk
qw,fodrpb,vkkjd,wlxa,dkj
ozonilmbxb,d,clg,seieik,lc
vkpvx,l,ldm,bohgge,aouglob
Last commment was written in "pure" C. So It doesnt work in Matlab.
Here it is the right solution.
function [ ] = writecellmatrixtocsvfile( filename, matrix )
%WRITECELLMATRIXTOCSVFILE Summary of this function goes here
% Detailed explanation goes here
fid = fopen(filename,'w');
for i = 1:size(matrix,1)
for j = 1:size(matrix,2)
fprintf(fid,'%s',matrix{i,j});
if j~=size(matrix,2)
fprintf(fid,'%s',',');
else
fprintf(fid,'\n');
end
end
end
fclose(fid);
end
easy enough to write your own csv writer.
-- edited to reflect comments --
fid = fopen('myfilename.csv','w');
for i = 1:size(A,1)
for j = 1:size(A,2)
fprintf(fid,'%s',A{i,j});
if(j!=size(A,2)
fprintf(fid,',',A{i,j})
else
fprintf(fid,'\n')
end
end
end
fclose(fid);