0

I have a devised a function in matlab that allows me (or so I thought) to extract data from a textfile that looks like this (at least the beginning)

G1 50
G2 50
M-0.35 0
M-0.05 0.013
M3.3 0.1
M9.75 0.236
M17.15 0.425
M25.85 0.666
M35.35 0.958

The idea is to match the letter I have with its position with a vector (because only the values next to M are really interesting to me), and get the two other numbers in a vector. The end of the treatment works well, but the values I get by the end of my code are sometimes far from the real ones.

For instance, instead of [0 0.013 0.1 0.236 0.425 0.666 0.958] I get [0 0.013 0.1010 0.237 0.426 0.666 0.959]. This is not such an issue, the problem is much worse for the first column : instead of a maximum at 119, it doesn't reach 90. I had a code that worked properly with integers, but now I'm using floats it fails everytime.

I will try and display only the interesting parts of the code :

nom_essai='test.txt'     
fid1 = fopen(nom_essai, 'rt');
tableau = textscan(fid1, '%s %.5f ', 'HeaderLines', 1, 'CollectOutput', true); %There are a few lines that I skip because they give the parameters, I get them with another line of the code
colonne_force=tableau{1}; %on recupere la premiere colonne
colonne_deplacement=tableau{2}; %on recupere la seconde colonne


indice=2*found_G+found_F+3*found_R; %this is the result of the treatment on colonne_force to match an index with the letter, which helps me keep the period next to G and the 2 values next to M.

force=linspace(0,0,length(n_indices)); %initialisation
    deplacement=linspace(0,0,length(n_indices)); %initialisation
    temps=linspace(0,0,length(n_indices)); %initialisation


    for k=1:length(colonne_force) %%%%k is for the length of my vectors, while j is for the length of the columns
        if indice(k)==2 %un G est trouve => temps d'echantillonnage
            T=colonne_deplacement(k); %to keep the period next to G
            end
        elseif indice(k)==1 %an F is found : skip it
        elseif indice(k)==3 %an R is found : skip it
        else %an M is found : I need to get the values on these lines
            j=j+1;
            deplacement(j)=colonne_deplacement(k); %I keep the value on the second column
            M=strsplit(colonne_force{k},'M'); %I get the string 'MXXX'
            force(j)=str2double(M{2}); %I recover this string without the M, and convert the number to double                 
        end
    end

The kind of precision I would like to have is to keep values like [M108.55 23.759] with up to 3 digits.

Thank you in advance, feel free to ask for any information if I failed to give only the part of the code that contains the problem.

F.D
  • 3
  • 3
  • Try just using `%f` as your format specifier rather than `%.5f` – Suever May 31 '16 at 13:10
  • Thank you for your reply. If kept %.5f instead of %f as a failed attempt to change something, but I got the same wrong values as I told before, except with one more digit of precision (a 0) – F.D May 31 '16 at 13:50

1 Answers1

0

Modifying a bit your code as:

nom_essai='test.txt';     
fid1 = fopen(nom_essai, 'rt');
tableau = textscan(fid1, '%s %f ', 'HeaderLines', 1, 'CollectOutput', true); % Change to %f not to miss significative figures
colonne_force = tableau{1}; %on recupere la premiere colonne
colonne_deplacement=tableau{2}; %on recupere la seconde colonne

% Check if has M

hasM = cellfun(@(x) any(x == 'M'), colonne_force);

column2 = colonne_deplacement(hasM);

column1 = colonne_force(hasM);
column1 = cellfun(@(x) str2double(x(2:end)), column1); % delete M and convert to double

The precision is retained:

Values of vectors

  • Thank you very much for this reply, it took me quite some time to adapt the rest of my code because I used to build all my vectors (time, strain, stress) at the same time. I changed this because building my time vector still requires a "for" loop, and now everything works perfectly. – F.D May 31 '16 at 16:06