Reading multiple text files with two columns in MATLAB - matlab

I want to read multiple text files. Each text file has two columns. All the two columns of all text files have same rows. I want to know, in MATLAB, how to read each text file then read each column one by one, subtract one column data from the other column and then read the next file and so on. I have written the following code but I am missing some step in the code. I appreciate your support. Thank you all.
for k = 1:9
filename = sprintf('Data_F_Ind000%d.txt',k);
a(:,k) = load(filename);
x = a(:,1)};
y = a(:,2);
z = x - y;
end

data = cell(9,1) ;
diff_data = cell(9,1) ;
for k = 1:9
filename = sprintf('Data_F_Ind000%d.txt',k);
a = load(filename);
data{i} = a ;
x = a(:,1)};
y = a(:,2);
diff_data{i} = x - y;
end

You can do this multiple ways. I imagine that you want to do something with z instead of just throwing it away every time. I would do this by taking advantage of an access pattern.
numFiles = 9;
numRows = ....; % not required but used to preallocate the a matrix
pattern = 1:2:numFiles * 2; % create a vector of 1 3 5 ...
a = zeros(numRows, numFiles * 2);
z = zeros(numRows, numFiles);
for k = 1:numFiles
fileName = sprintf('Data_F_Ind000%d.txt, 'k');
a(:,pattern(k):pattern(k) + 1) = load(fileName);
z(:,k) = a(:,pattern(k)) - a(:,pattern(k) + 1);
end
This is untested and is clearly missing some data but the intent should be clear. You don't need to preallocate variables but it helps speed calculations so I try to do it whenever possible.

Related

How to plot Data From an Excel File in MATLAB? fplot Please

I am trying to plot data from an Excel file. I am reading from the second sheet, which has names of machines (machine numbers, but it needs to be flexible), on the top and then numbers underneath.
Machine1
1
2
3
4
5
6
etc.
The first row, which has the names, needs to be the name of each graph.
Here is what I have so far. Also, please no advanced functions.
clear variables
clc
close all
i = 0;
n = 1;
% All the code to do the first part of the graphing
inputFile = xlsread('machineOutput.xlsx', 'Sheet2');
[rows, cols] = size(inputFile);
for c = 1: cols
clear tempVar;
clear tempName;
count = 0;
i = 1;
for r = 1: rows
if(isnan(inputFile(r, c)) == 1)
inputFile(r, c) = 0;
end
tempVar{n} = inputFile(r, c);
tempName{i} = inputFile(r, c);
end
fplot(tempVar, [-2 2])
title(tempName)
grid on
xlabel('Number of Days')
ylabel('All machines')
figure
xlim tight
n = n + 1;
end

How can I read specific images from TID2013 dataset in MATLAB?

How can I read specific images from TID2013 dataset in MATLAB? I written the following code but it start from first to end of the list. The images are in this format: ixx.yy.z.bmp means xx is the number of image, yy is the model of the noise and z is the level of the noise. I just want to work with models 1,2 in level 4,5 but I don't know how to do it. please someone help me! By the way there are 25 reference images, 24 models of noise and 5 level of each model of noise that I wrote them vertically in info1.txt , info2.txt , info3.txt respectively.
clc; clear; close all;
% read Original images
cd 'C:\Users\Desktop'
for NO1 = 1:25
in1 = fopen('info1.txt');
xx = fgets(in1);
A = imread(strcat('C:\Users\Desktop\reference_images\',xx,'.bmp'));
A = rgb2gray(A);
end
% read distorted images
for NO1 = 1:25
in1 = fopen('info1.txt');
xx = fgets(in1);
for NO2 = 1:24
in2 = fopen('info2.txt');
yy = fgets(in2);
for NO3 = 1:5
in3 = fopen('info3.txt');
z = fgets(in3);
B = imread(strcat('C:\Users\Desktop\distorted_images\',xx,yy,z,'.bmp'));
B = rgb2gray(B);
C = imadjust(B);
% Write restored images
imwrite(C,['C:\Users\Desktop\restored_images\','i',sprintf('%02d',NO1),'_',sprintf('%02d',NO2),'_',num2str(NO3),'.bmp']);
end
end
end
The only thing you need to do is to change values of your for loops. Note that in matlab, in contrast with most other languages, for-loops are not restricted to specific step length and can be any vectors.
imageNames = textread('info1.txt', '%s');
noiseModels = textread('info2.txt', '%s');
noiseLevels = textread('info3.txt', '%s');
imageIndices = 1:25;
modelIndices = [1, 2, 7:8];
levelindices = [4 5];
sourceDir = 'C:\Users\Desktop\distorted_images\';
destDir = 'C:\Users\Desktop\restored_images\';
for ii = imageIndices
name = imageNames{ii};
for jj = modelIndices
model = noiseModels{jj};
for kk = levelindices
level = noiseLevels{kk};
sourcePath = sprintf('%s%s%s%s.bmp', sourceDir, name, model, level)
destPath = sprintf('%si%02d_%02d_%02d.bmp', destDir, ii, jj, kk)
B = imread(sourcePath);
B = rgb2gray(B);
C = imadjust(B);
imwrite(C, destPath);
end
end
end

Turning a plot3 into a surf in MATLAB

I have several csv files and I plotted them using plot3 to create the following image:
Now I would like to turn this into a surface plot because I would like to colour the plot according to height. I made the following with scatter3:
clearvars;
files = dir('*.csv');
name = '\epsilon_{y} over time for Vertical section';
des_col_1 = 'Vertical section.epsY []';
des_col_2 = 'Length [mm]';
set(gca,'FontSize',20)
a = gca;
ii = 1;
x_data = [];
y_data = [];
z_data = [];
tStart = tic;
for file = files'
csv = xlsread(file.name);
[n,s,r] = xlsread(file.name);
des_cols = {des_col_1,des_col_2};
colhdrs = s(1,:);
[~,ia] = intersect(colhdrs, des_cols);
colnrs = flipud(ia);
file.name = n(:,colnrs);
file.name = file.name(1:end,:);
x_data = [x_data; file.name(:,2)];
y_data = [y_data; ones(size(file.name(:,2))).*ii];
z_data = [z_data; file.name(:,1)];
ii = ii+1;
end
tEnd = toc(tStart);
fprintf('%d minutes and %f seconds\n',floor(tEnd/60),rem(tEnd,60));
view(40,40);
zlabel({'True strain (%)'});
xlabel({'Length along sample (mm)'});
ylabel({'Stage'});
title({name});
scatter3(a,x_data,y_data,z_data,10,z_data);
colormap(jet); %# or other colormap
which gives me this
That was made with a smaller set of data than the first one as a test. It does almost what I want but I was wondering if there was a way to generate a true 3D surface from all my data. I can create a matrix with x, y, and z values for all points and I tried to replace scatter3(a,x_data,y_data,z_data,10,z_data); with
[X,Y] = meshgrid(x_data,y_data);
f = scatteredInterpolant(x_data,y_data,z_data);
Z = f(X,Y);
surf(a,X,Y,Z);
but the plot that I get does not look very good
I'm pretty sure there's something wrong with the interpolation but I'm not very good with surfaces so I don't know how to correct it.
The reason surf is giving you the error is you are creating long nx1 arrays Where n = number of points per file times number of files. For x,y,& z_data and you need them into a matrix instead. So try the following changes:
for file = files'
<snipped out for length>
x_data = [x_data; file.name(:,2).'];
y_data = [y_data; ones(1,numel(file.name(:,2))).*ii];
z_data = [z_data; file.name(:,1).'];
ii = ii+1;
end
This should make x, y, and z_data the size nxm (n = number of files, m = number points per file).
Then you should be able to just do
surf(x_data,y_data,z_data)

Basic for loop in Matlab

I have a simple question in Matlab. How can I creat a for loop that will choose the value from a vector for which the result is smallest and write the chosen value from vector into .txt file? For example , if I have:
T = 100;
W = 20;
h = [h1 h2 h3 ... ];
y = 2*T*W/h;
I want to create loop that will search vector h for a value that will provide minimum value of y and write the chosen h into .txt file.
Any help would be greatly appreciated. Thanks
For loop:
min_y = 2*T*W/h(1);
h_chosen = 1;
for i = 2:length(h)
if min_y > 2*T*W/h(i)
min_y = 2*T*W/h(i);
h_chosen = i;
end
end
Much faster than for-loop:
[~, idx] = min(arrayfun(#(i) 2*T*W/h(i), 1:length(h)));
h_chosen = h(idx);
Write to .txt file: (http://www.mathworks.com/help/matlab/ref/fprintf.html)
fileID = fopen('min_h.txt','w');
fprintf(fileID, '%d\n', h_chosen);

How to add character to numeric matrix in matlab?

In matlab usually we add a header using fprintf command.
This is a problem when the size of the table depends on the input and when it exceeds a certain range (more than total number of column able to be presented in the command window).
When this occurs the header which we specified previously using the fprintf command will not be compatible with the current output data.
I would like to know is there a way like adding a character string into the 1st row of the matrix during some kind of iteration process. I had tried hardly but still can't find a proper way to solve this issue.
Or it is actually cannot be done in matlab for this purpose.
Eg
clear;clc
A = [2 8 3 1;0 2 -1 4;7 -2 1 2;-1 0 5 2]
B = [-2;4;3;5]
Es = 1e-5
n = length(B);
x = zeros(n,1);
Ea = ones(n,1);
iter = 0;
while max(Ea) >= Es
if iter <= 30
iter = iter + 1;
x_old = x;
for i = 1:n
j = 1:n;
j(i) = [];
x_cal = x;
x_cal(i) = [];
x(i) = (B(i) - sum(A(i,j) * x_cal)) / A(i,i);
end
else
break
end
x_ans(:,iter) = x;
Ea(:,iter) =abs(( x - x_old) ./ x);
end
result = [1:iter; x_ans; Ea]'
for the coding above..how could I add the heading like iteration for 1st column, x1...x2...x3..xn for nth column and error x1..error x2..error xn for another n column. I would like to make this heading can be automated generated based on the input matrix
If the size of the table depends on the input, use a cell array, using c = cell(...).
In each iteration simply call c{i,j} instead of c[i,j].