Read more than 3000 txt files by using loop - matlab

I have more than 3000 Data txt files. I create the name for these file according to special rate by this code
clc;
clear all;
close all;
%%
h=[1];
k_plus =[0.1 0.2 0.4 0.7 1 1.1 1.2 1.5 1.7 2 2.5 3 3.5 4 5];
K_minus_T =[1e-6 0.1 0.2 0.4 0.7 1 1.1 1.2 1.5 1.7 2 2.5 3 3.5 4 5];
K_minus_D = [1e-6 0.1 0.2 0.4 0.7 1 1.1 1.2 1.5 1.7 2 2.5 3 3.5 4 5];
sets = {k_plus, K_minus_T, K_minus_D,h};
[x,y,z r] = ndgrid(sets{:});
cartProd = [x(:) y(:) z(:) r(:)];
nFiles = size(cartProd,1);
filename{nFiles,1}=[];
for i=1:nFiles
filename{i} = ['MTN100_' ...
'k+' num2str(cartProd(i,1)) '_' ...
'k-T_' num2str(cartProd(i,2)) '_' ...
'k-D' num2str(cartProd(i,3)) '_' ...
'h' num2str(cartProd(i,4)) '_' ...
'GTP0.txt'];
end
Now I want to read each file in the loop and do some processing. I tried to use textscan and textread but It is not work.
h=[1];
k_plus =[0.1 0.2 0.4 0.7 1 1.1 1.2 1.5 1.7 2 2.5 3 3.5 4 5];
K_minus_T =[1e-6 0.1 0.2 0.4 0.7 1 1.1 1.2 1.5 1.7 2 2.5 3 3.5 4 5];
K_minus_D = [1e-6 0.1 0.2 0.4 0.7 1 1.1 1.2 1.5 1.7 2 2.5 3 3.5 4 5];
sets = {k_plus, K_minus_T, K_minus_D,h};
[x,y,z r] = ndgrid(sets{:});
cartProd = [x(:) y(:) z(:) r(:)];
nFiles = size(cartProd,1);
filename{nFiles,1}=[];
for i=1:nFiles
filename{i} = ['MTN100_' ...
'k+' num2str(cartProd(i,1)) '_' ...
'k-T_' num2str(cartProd(i,2)) '_' ...
'k-D' num2str(cartProd(i,3)) '_' ...
'h' num2str(cartProd(i,4)) '_' ...
'GTP0.txt'];
file1=fopen(filename{i},'r')
C=textscan(filename{i},'%u');
t1 = C(1,:);
d1 = C(3,:);
plot(t1, d1, 'b*-', 'LineWidth', 2, 'MarkerSize', 3);
fclose(filename{i});
end
I am mainly using C++ and not really familiar with how to do the similar things in MATLAB.Any help would be greatly appreciated. I will be grateful to you.

I'm not sure what the issue is that you're experiencing, but I spotted a couple of errors in your code. fopen returns a file ID, it's this file ID that you should then pass into textscan and fclose, not the file name. The second argument to textscan is the format specifier of a single row of the data that you're scanning. You mentioned in the comments that there are 7 real values, I've set the formatspec to '%f%f%f%f%f%f%f' which will treat the values as doubles. If your values are delimited with anything other than whitespace you'll need to add delimiter information to the textscan call.
h=[1];
k_plus =[0.1 0.2 0.4 0.7 1 1.1 1.2 1.5 1.7 2 2.5 3 3.5 4 5];
K_minus_T =[1e-6 0.1 0.2 0.4 0.7 1 1.1 1.2 1.5 1.7 2 2.5 3 3.5 4 5];
K_minus_D = [1e-6 0.1 0.2 0.4 0.7 1 1.1 1.2 1.5 1.7 2 2.5 3 3.5 4 5];
sets = {k_plus, K_minus_T, K_minus_D,h};
[x,y,z r] = ndgrid(sets{:});
cartProd = [x(:) y(:) z(:) r(:)];
nFiles = size(cartProd,1);
filename{nFiles,1}=[];
for i=1:nFiles
filename{i} = ['MTN100_' ...
'k+' num2str(cartProd(i,1)) '_' ...
'k-T_' num2str(cartProd(i,2)) '_' ...
'k-D' num2str(cartProd(i,3)) '_' ...
'h' num2str(cartProd(i,4)) '_' ...
'GTP0.txt'];
file1=fopen(filename{i},'r')
C=textscan(file1,'%f%f%f%f%f%f%f');
fclose(file1);
t1 = C(1,:);
d1 = C(3,:);
plot(t1, d1, 'b*-', 'LineWidth', 2, 'MarkerSize', 3);
end

Related

Data analysis in Matlab

I have a time vector in Matlab which does not have consistent sampling time, ex. t = [0.1 0.2 0.3 0.4 0.5 0.6 0.7 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.9 3 3.1], I have another vector which is time based as a = [2 5 2 4 5 7 8 0 10 1 0 25 6 14 5 2 7 98], when I plot(t,a) there is straight line connecting the two points with larger sampling time, how can I remove these gaps where the sampling time is not consistent and it jumps to larger value? I know defining NaN between 0.7 and 1.3 and also 2 and 2.9 in t and also in a for the same interval might help, but how to distinguish if sampling time changes?
Maybe you can try the following codes, and here are two approaches that you can make it:
Approach 1: adding nan
clc;
clear;
close all;
t = [0.1 0.2 0.3 0.4 0.5 0.6 0.7 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.9 3 3.1]
a = [2 5 2 4 5 7 8 0 10 1 0 25 6 14 5 2 7 98]
dt = diff(t);
idx = find(dt > mode(dt));
tC = mat2cell(t',[idx(1),diff([idx,length(t)])]);
aC = mat2cell(a',[idx(1),diff([idx,length(t)])]);
nadd = dt(idx)/mode(dt);
T = [];
A = [];
for i = 1:length(nadd)
T = [T; tC{i};ones(int32(nadd(i)),1)*nan];
A = [A; aC{i};ones(int32(nadd(i)),1)*nan];
endfor
T = [T;tC{end}];
A = [A;aC{end}];
plot(T,A)
Approach 2: dividing vector by intervals
clc;
clear;
t = [0.1 0.2 0.3 0.4 0.5 0.6 0.7 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.9 3 3.1]
a = [2 5 2 4 5 7 8 0 10 1 0 25 6 14 5 2 7 98]
dt = diff(t);
idx = find(dt > mode(dt));
tC = mat2cell(t',[idx(1),diff([idx,length(t)])]);
aC = mat2cell(a',[idx(1),diff([idx,length(t)])]);
hold on;
arrayfun(#(k) plot(tC{k},aC{k}),1:(length(idx)+1));

Matlab - finding solution for scaling a curve

Consider two curves, for example:
x = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = [0 -0.2 -0.3 -0.8 -2 1 2.8 2.4 1.5 1.1 2.3 -0.4 -0.2 1 1.1 1.2 1.3 0.5 -0.1 0];
I'd like to write a generalized algorithm that takes in x, y1, and y2, and scales y1 by a global scale factor, f, such that the new value of y2-y1 is as close as possible to 0. That is, y2-f*y1 is as close to 0 as possible.
How can I do this?
Try this:
% Create a function that you want to minimize
func = #(f, y1, y2)abs(sum(y2 - f*y1));
% Your example data
x = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = [0 -0.2 -0.3 -0.8 -2 1 2.8 2.4 1.5 1.1 2.3 -0.4 -0.2 1 1.1 1.2 1.3 0.5 -0.1 0];
% Plot the before
figure()
plot(x, y2); hold all;
plot(x, y1)
% Find the optimum scale factor
f_start = 0; % May want a different starting point
f = fminsearch(#(f) func(f, y1, y2), f_start);
disp(['Scale factor = ' num2str(f)]) % print to the output
% Plot the after (scaled data)
figure()
plot(x, y2); hold all;
plot(x, f*y1)
For more information see the docs on anonymous functions and fminsearch (see example #2).
EDIT
Here is the output of the above script:
Scale factor = -2.9398
Before
After
As you can see the difference between the functions is minimized (area where y1 is greater than y2 is about the same as the area where y1 is less than y2). If you want the lines to match up as close as possible then you need to modify the minimization function like so:
func = #(f, y1, y2)sum(abs(y2 - f*y1));
I had to modify the test data for this case as it appears the data was already lined up optimally.
y1 = [0 0 -0.3 -0.8 -1.1 -1 -0.5 1 1.1 1 -0.3 -0.8 -1.1 -1 -0.5 0.1 0.05 0 0 0];
y2 = -2*y1 +1;
which gives the following output:
Scale factor = -2.9091
Before
After

how can transform a matrix matlab into file .txt?

I have a matrix proba (size :10 * 5).
proba=[0.5 0.3 0.8 0.9 0.8;
0.50 0.36 0.58 0.58 0.98;
0.1 0.25 0.6 0.8 0.9;
0.5 0.3 0.8 0.9 0.8;
0.2 0.9 0.58 0.58 0.69;
0.58 0.14 0.1 0.2 0.3;
0.25 0.9 0.8 0.7 0.5;
0.58 0.69 0.25 0.1 0.1;
0.1 0.25 0.36 0.2 0.3;
0.5 0.3 0.8 0.9 0.8 ];
I want to transform this matrix into a text file (proba.txt) with which the index column is written and the value of the column for each line as follows :
1 0.5 2 0.3 3 0.8 4 0.9 5 0.8
1 0.50 2 0.36 3 0.58 4 0.58 5 0.98
.
.
.
1 0.5 2 0.3 3 0.8 4 0.9 5 0.8
Please I need help, how can I do it?thanks in advance
You can use this function, it is useful for every matrix.
function data = addIndex(X)
[r, c] = size(X);
index = ones(r, 1);
data = zeros(r, 2 * c);
for i = 1:c
data(:, 2 * i - 1) = i .* index;
data(:, 2 * i) = X(:, i);
end
dlmwrite('proba.txt', data, '\t')
end
you can easily do this using dlmwrite, but first you want to add the column of indexes in front of your matrix:
function result = writematrix(proba)
rowind = 1:size(proba,2);
for t = 1:size(proba,1);
C(t,:,:) = [rowind',proba(t,:)']';
D(t,:) = C(t(:),:);
end
dlmwrite('filename.txt',D,'\t') %//I assume you want tab delimiter, if you want space, it is ' ' instead
%//dlmwrite('filename.txt',D,' ')
end
Note that this will write the text file into your local directory, and that it only works for numerical values, not strings, for strings, it is better to use csvwrite.
EDIT : Ops, didn't read the question fully, this should now work fine.

reshape matrix in matlab

I don't see the bug anymore...maybe (very probably :-) ) there's even a much more easier and faster way of doing it...
I summarized the important columns of my huge data frame in a little expData (see below).
The problem is actually quite easy, but I'm just blind for the easy idea of solving it..
My objective is to reshape columns b,c,d into one column that expData afterwards looks like expData2.
I would be really happy, if someone could help me out.
My code so far:
a = [1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5]';
b = [0.3 0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.9 0.9 0.9 0.9 0.9]';
c = [0.4 0.4 0.4 0.4 0.4 0.6 0.6 0.6 0.6 0.6 0.8 0.8 0.8 0.8 0.8 0.9 0.9 0.9 0.9 0.9 0.1 0.1 0.1 0.1 0.1]';
d = [0.5 0.5 0.5 0.5 0.5 0.1 0.1 0.1 0.1 0.1 0.7 0.7 0.7 0.7 0.7 0.2 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.3]';
e = rand(25,1);
f = rand(25,1);
a2 = [2 3 4 2 3 4 2 3 4 2 3 4 2 3 4]';
b2 = [0.3 0.4 0.5 0.4 0.6 0.1 0.5 0.8 0.7 0.8 0.9 0.2 0.9 0.1 0.3]';
c2 = rand(15,1);
d2 = rand(15,1);
expData = horzcat(a,b,c,d,e,f);
expData2 = horzcat(a2,b2,c2,d2); % for explanation of my objective
k = horzcat(expData(:,2),expData(:,3),expData(:,4))'; % How I wanted to do it
expData(:,2:4) = [];
k = reshape(k,[],1);
for index = 1:size(expData,1)
if expData(index,1) == 1
expData(index,:) = [];
end
if expData(index,1) == 5
expData(index,:) = [];
end
end
k = k(1:size(expData,1),:);
expData2 = [expData k];
Your current code throws an error, since the number of loop iterations gets determined at the beginning of the loop. As you are removing rows of expData, you run out of rows to index at some point.
The quick fix would be to start looping from the back, i.e. use for index = size(expData,1):-1:1. This way, you can safely remove rows without running into indexing problems.
The elegant fix is to use ismember to identify rows to remove:
rows2remove = ismember(expData(:,1),[1 5]);
expDate(rows2remove,:) = [];

scale part of an axis in matlab

I have the following image which I want to have the depth axis range like below :
(10 9.5 9 8.5 8 7.5 7 6 5 3 2 1 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0) to show the data between depth 1 and 0 in larger scale, and I have the following code
depths = [10 5 1 0.5 0; 10 5 1 0.5 0] % these are the real depths in meter
contourf(points,depths,RFU15102013_BloomAsMainPoint);
set(gca, 'XTick', points(1) : points(2), 'XTickLabel',{ 'LSB1', 'LSB2'});
ylabel('Depth(m)');
xlabel('Points');
title('Date: 15.10.2013');
this is the image :
how can I do that?
EDIT1
Real Data:
RFU15102013_BloomAsMainPoint = [ 2.71 1.23 1.30 1.20 14.37 ; 2.51 1.36 1.01 1.24 1.15];
points = [1 1 1 1 1; 2 2 2 2 2 ];
depths = [10 5 1 0.5 0; 10 5 1 0.5 0];
As most of a data changes around zero it could be enough to change scaling of Y axis. Here is an example
close all; clear all;
z = [ 2.71 1.23 1.30 1.20 14.37 ; 2.51 1.36 1.01 1.24 1.15];
x = repmat([1; 2], 1, 5);
y = repmat([10 5 1 0.5 0], 2, 1);
% plotting with equally spaced y-s
h = subplot(1,2,1);
contourf(x,y,z);
y2 = log(y + 0.25);
yTicks = linspace(min(y2(1,:)), max(y2(1,:)), 10);
% plotting with logarithmically spaced y-s
h = subplot(1,2,2)
contourf(x,y2,z);
set(h,'YTick', yTicks)
set(h,'YTickLabel', exp(yTicks) - 0.25);
print('-dpng','scaling.png')
The result
This way any monotonic continuous function for axis scaling can be applied.
You could use UIMAGE - UIMAGESC from the mathworks file exchange and set the y values to emphaisize points in 1 to 0 range.