FSEEK error while running Matlab function - matlab

I got this error while running a function in Matlab
"Error using fseek Invalid file identifier. Use fopen to generate a valid file identifier."
May I know what is the possible causes of this error? I am very new to Matlab. Please help me. Thanks a lot
I am sorry if I should not post the overall function. But I am afraid the information I gave is not enough. The overall command of the function is:
function gau_hmm_init_train(traininglist_filename,model_filename,MODEL_NO,STATE_NO, dim )
if nargin == 0
traininglist_filename='training_list.mat' ;
model_filename='models.mat';
MODEL_NO=11;
STATE_NO=4;
dim=12;
end
MIN_SELF_TRANSITION_COUNT=0;
load(traininglist_filename,'list');
% allocate mean, var vectors, transition prob. for the of models
mean_vec_i_m=zeros(dim,STATE_NO,MODEL_NO);
var_vec_i_m=zeros(dim,STATE_NO,MODEL_NO);
A_i_m=zeros(STATE_NO,MODEL_NO);
vector_sums_i_m=zeros(dim,STATE_NO,MODEL_NO);
var_vec_sums_i_m=zeros(dim,STATE_NO,MODEL_NO);
fr_no_i_m=zeros(STATE_NO,MODEL_NO);
self_tr_fr_no_i_m=zeros(STATE_NO,MODEL_NO);
utterance_no=size(list,1);
total_fr_no=0;
for k=1:utterance_no
filename=list{k,2};
m=list{k,1}; % word ID
fid=fopen(filename,'r');
fseek(fid, 12, 'bof'); % skip the 12-byte HTK header
%fopen(fid, 12, 'bof'); % skip the 12-byte HTK header
c=fread(fid,'float','b');
fclose(fid);
fr_no=length(c)/dim;
total_fr_no=total_fr_no+fr_no;
c=reshape(c,dim,fr_no);
for i=1:STATE_NO
begin_fr=round( fr_no*(i-1) /STATE_NO)+1;
end_fr=round( fr_no*i /STATE_NO);
seg_length=end_fr-begin_fr+1;
vector_sums_i_m(:,i,m) = vector_sums_i_m(:,i,m) + sum(c(:,begin_fr:end_fr),2);
var_vec_sums_i_m(:,i,m) = var_vec_sums_i_m(:,i,m) + sum( c(:,begin_fr:end_fr).*c(:,begin_fr:end_fr) , 2);
fr_no_i_m(i,m)=fr_no_i_m(i,m)+seg_length;
self_tr_fr_no_i_m(i,m)= self_tr_fr_no_i_m(i,m) + seg_length-1;
end %for s=1:STATE_NO
end % for k=1:utterance_no
for m=1:MODEL_NO
for i=1:STATE_NO
mean_vec_i_m(:,i,m) = vector_sums_i_m(:,i,m) / fr_no_i_m(i,m);
var_vec_i_m(:,i,m) = var_vec_sums_i_m(:,i,m) / fr_no_i_m(i,m);
A_i_m(i,m)=(self_tr_fr_no_i_m(i,m)+MIN_SELF_TRANSITION_COUNT)/(fr_no_i_m(i,m)+2*MIN_SELF_TRANSITION_COUNT);
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% tying of cov. matrices
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
overall_var_vec=sum(sum(var_vec_sums_i_m(:,:,:),3 ),2)/sum(sum(fr_no_i_m,2 ),1);
for m=1:MODEL_NO
for i=1:STATE_NO
var_vec_i_m(:,i,m)=overall_var_vec;
end
end
%%%%%%%%%%%%%%%% end of cov. matrices tying
save(model_filename, 'mean_vec_i_m', 'var_vec_i_m', 'A_i_m');
fprintf('init. train complete \n');***

Sounds like the line fid=fopen(filename, 'r'). This filename comes from the list variable which is loaded from the file traininglist_filename, so you should check that these files exist. If you're passing it a traininglist_filename you should load this file in MATLAB and look at the contents of list; otherwise it will load the default 'training_list.mat', so you should look in there to make sure all the filenames are valid. Perhaps you're missing a file?

To continue the reply by #Wakjah, the training_list.mat file is missing from the reference path by the code you are using because it is automatically created at MATLAB default path. Therefore, just change the path at the 'Current Folder' to where you had open your current code and it should work.

Related

Create a text file by matlab

I want to create a text file like this with Matlab but i don't know how should I do that.
range(0,25e-9,0+600e-9),range(0+600e-9,1e-4,1.000000e-03),range(1.000000e-03,25e-9,1.000000e-03+600e-9),range(1.000000e-03+600e-9,1e-4,2.000000e-03),range(2.000000e-03,25e-9,2.000000e-03+600e-9),range(2.000000e-03+600e-9,1e-4,3.000000e-03)
for example here I want to create 6 point and I can do it by myself. But if I want create 100 point or 500 point I have to use Matlab. I wrote a code and create a matrix something like this but what I want is different. It's my code but I cant use it.....
clc
clear
close all
stp1=25e-9;
stp2=1e-4;
A=600e-9;
B=1e-3;
i=3;
F=zeros(i,3);
for i=1:i
if i==1
F(i,1)=0;
F(i,2)=stp1;
F(i,3)=A;
else
if mod(i,2)==0
F(i,1)=F(i-1,3);
F(i,2)=stp2;
F(i,3)=(i/2)*B;
else
F(i,1)=F(i-1,3);
F(i,2)=stp1;
F(i,3)=F(i,1)+A;
end
end
end
for example this is my matrix:
` 0.0000e+000 25.0000e-009 600.0000e-009
600.0000e-009 100.0000e-006 1.0000e-003
1.0000e-003 25.0000e-009 1.0006e-003`
I want to put them in one line and this like this:
`range(0.0000e+000,25.0000e-009,600.0000e-009),range(600.0000e-009,100.0000e-006,1.0000e-003),range(1.0000e-003,25.0000e-009,1.0006e-003)`
you know I want to add range(A(1,1),A(1,2),A(1,3)),range(A(2,1),A(2,2),A(2,3)) to my text file.... I hope I have explained well that I want.
I've put some code together below to help move this along. Please comment and I can adjust (or others can post answers based on updated information).
I'm still not sure exactly what outcome you're after.
For reference, you can see examples of file I/O documentation for dlmwrite here and for fprintf here. Notice you can specify the delimiter with dlmwrite and the exact format with fprintf.
A = [0.0000e+000 25.0000e-009 600.0000e-009;
600.0000e-009 100.0000e-006 1.0000e-003;
1.0000e-003 25.0000e-009 1.0006e-003];
dlmwrite('TestFile.txt',A) % Example use of dlmwrite
B = range(A,2); % Range of the rows of A
dlmwrite('TextFile2.txt',B)
C = cell(size(A,1),1);
fileID = fopen('TestFile3.txt','w+');
formatstr = '%12s\r\n';
for k = 1:size(A,1)
C{k}=['range(A(' num2str(k) ',:)'];
fprintf(fileID,formatstr,C{k});
end
fclose(fileID);
Hope this helps.

Change text line in a file by using Matlab

So I have to modify a .dxf file (an Autocad file) by changing some data in it for another one we choose previously. Changing some lines of a .txt file in Matlab is not pretty difficult.
However, I cannot change a specific line when the new input's length is larger than the old one.
This is what I have and I want to change only 1D57:
TEXT
5
1D57
330
1D52
100
AcDbEntity
8
0
If I have as an input BBBB, everything goes right since both strings have the same length. The same does not apply when I try with BBBBbbbbbbbbbb:
TEXT
5
BBBBbbbbbbbbbb2
100
AcDbEntity
8
0
It deletes everything after it until the string stops. It happens the same when the input is shorter: it does not change the line for the new string but it writes until the new input stops. For example, in our case with AAA as an input, the result would be AAA7.
This is basically the code I am using to modify the file:
fID = fopen('copia.dxf','r+');
for i = 1:2
LineToReplace = TextIndex(i);
for k = 1:((LineToReplace) - 1);
fgetl(fID);
end
fseek(fID, 0, 'cof');
fprintf (fID, [Data{i}, '\n']);
end
fclose(fID);
You need to overwrite at least the rest of the file in order to change it (unless exact number of characters is replaced), as explained in jodag's comment. For instance,
% String to change and it's replacement
% (can readily be automated for more replacements)
str_old = '1D52';
str_new = 'BBBBbbbbbbbbbb';
% Open input and output files
fIN = fopen('copia.dxf','r');
fOUT = fopen('copia_new.dxf','w');
% Temporary line
tline = fgets(fIN);
% Read the entire file line by line
% Write it to the new file
% Replace str_old with str_new when encountered - note, if there is more
% than one occurence of str_old in the file all will be replaced - this can
% be handled with a proper flag
while (ischar(tline))
% char(10) is MATLAB's newline character representation
if strcmp(tline, [str_old, char(10)])
fprintf(fOUT, '%s \n', str_new);
else
% No need for \n - it's already there as we're using fgets
fprintf(fOUT, '%s', tline);
end
tline = fgets(fIN);
end
% Close the files
fclose(fIN);
fclose(fOUT);
% Copy the new file into the original
movefile 'copia_new.dxf' 'copia.dxf'
In practice, it is often far easier to simply overwrite the whole file.
As written in the notes - this can be automated for more replacements and it would also need an additional flag to only replace a given string once.

Parsing a data file in matlab

I have a text file with two columns of data. I want to split this file and save it as two individual strings in matlab, but I also need to stop copying the data when I meet an identifier in the data then stat two new strings.
For example
H 3
7 F
B B
T Y
SPLIT
<>
Where SPLIT <> is where I want to end the current string.
I'm trying to use fopen and fscanf, but struggling to get it to do what I want it to.
I tried the following script on the example you provided and it works. I believe the comments are very self explanatory.
% Open text file.
fid = fopen('test.txt');
% Read the first line.
tline = fgetl(fid);
% Initialize counter.
ii = 1;
% Check for end string.
while ~strcmp(tline, 'SPLIT')
% Analyze line only if it is not an empty one.
if ~strcmp(tline, '')
% Read the current line and split it into column 1 and column 2.
[column1(ii), column2(ii)] = strread(tline, ['%c %c']);
% Advance counter.
ii = ii + 1;
end
% Read the next line.
tline = fgetl(fid);
end
% Display results in console.
column1
column2
% Close text file.
fclose(fid);
The key functions here are fgetl and strread. Take a look at their documentation, it has some very nice examples as well. Hope it helps.

How to read numbered sequence of .dat files into MATLAB

I am trying to load a numbered sequence of ".dat" named in the form a01.dat, a02.dat... a51.dat into MATLAB. I used the eval() function with the code below.
%% To load each ".dat" file for the 51 attributes to an array.
a = dir('*.dat');
for i = 1:length(a)
eval(['load ' a(i).name ' -ascii']);
end
attributes = length(a);
I ran into problems with that as I could not easily manipulate the data loaded with the eval function. And I found out the community is strongly against using eval. I used the csvread() with the code below.
% Scan folder for number of ".dat" files
datfiles = dir('*.dat');
% Count Number of ".dat" files
numfiles = length(datfiles);
% Read files in to MATLAB
for i = 1:1:numfiles
A{i} = csvread(datfiles(i).name);
end
The csvread() works for me but it reads the files but messes up the order when it reads the files. It reads a01.dat first and then a10.dat and a11.dat and so on instead of a01.dat, a02.dat... The contents of each files are signed numbers. Some are comma-delimited and single column and this is an even split. So a01.dat's contents are comma-delimited and a02.dat's content are in a single column.
Please how do I handle this?
Your problem seems to be sorting of the files. Drawing on a question on mathworks, this should help you:
datfiles = dir('*.mat');
name = {datfiles.name};
[~, index] = sort(name);
name = name(index);
And then you can loop with just name:
% Read files in to MATLAB
for i = 1:1:numfiles
A{i} = csvread(name{i});
end

How to save multi-dimensional array in matlab?

I have an array M=(1000000,12,2,2).
How do I write it to a file to work on later?
save('filename.txt','M','-ASCII')
doesn't seem to work...
Regards,
Why not save it as a mat file (binary) ?
save('filename.mat', 'M' );
afterwards you simply load it
% some code ...
M = [];
load( 'filename.mat' );
% now you have M
% code handling multi-dim M
1) just like the answer from #Shai, you can save it to be mat file
2) if you want to save it to be txt file, you can do it in this way:
clear;clc;
M=[1000000,12,2,2];
dlmwrite('a.txt',M); % save M to file--a.txt
type a.txt; % print content in a.txt
M = dlmread('a.txt'); % load content of a.txt to M and then you will have 'M=[1000000,12,2,2]'
3) you can also use fopen, fprintf, fclose to save a matrix to a file. check this post: How to save data in .txt file in MATLAB
4) for the code you have, I tested it. It works. The Matlab version I have is R2011b. please check your code again. The code I used to test is as follows:
clear;clc;
M=[1000000,12,2,2];
save('b.txt','M','-ASCII');
clear;clc;
M = load('b.txt','-ASCII');