Importing Data from a .txt file into Matlab - matlab

First of all thank you for reading my question.
I am trying to import data from a file with following format into Matlab:
#Text
#Text: Number
...
#Text: Number
Set1:
1 2
3 4
Set2:
5 6
7 8
...
I would like to get those numbers into two matrices of the form:
(1 5
3 7)
and
(2 6
4 8)
I started by only building the first of those two matrices.
Winkel = 15;
xp = 30;
M = readtable('Ebene_1.txt')
M([1:4],:) = [];
M(:,3) = [];
for i=0:Winkel-1
A = table2array(M((2+i*31:31+i*31),1))
end
But this solution only gave me cell arrays which I could not transform into normal vectors.
I also tried to use the importdata command, but could not find a way to get this to work either. I know there are many other questions similar to mine, but I could not find one where all the data were in a single column. Also, there are many Matlab-commands for importing data into Matlab and I am not sure which would be the best.
First time asking such a question online so feel free to ask me for more details.

You can import the data you provided in your sample using readtable, however because of the format of your file you will need to tweak the function a bit.
You can use detectImportOptions to tell the function how to import the data.
%Detect import options for your text file.
opts = detectImportOptions('Ebene_1.txt')
%Specify variable names for your table.
opts.VariableNames = {'Text','Number'};
%Ignore last column of your text file as it does not contain data you are interested in.
opts.ExtraColumnsRule = 'ignore';
%You can confirm that the function has successfully identified that the data is numeric by inspecting the VariableTypes property.
%opts.VariableTypes
%Read your text file with detectImportOptions.
M = readtable('Ebene_1.txt',opts)
Now that you have table M, simply apply basic Matlab operations to obtain the matrices as you specified.
%Find numerical values in Text and Number variables. Ignore NaN values.
A = M.Text(~isnan(M.Text));
B = M.Number(~isnan(M.Number));
%Build matrices.
A = [A(1:2:end)';A(2:2:end)']
B = [B(1:2:end)';B(2:2:end)']
Output:
A =
1 5
3 7
B =
2 6
4 8

Related

Separating and splitting table by numeric values and writing to multiple files

I have a single CSV with data uploaded from multiple IOT sensors (all within the same file), each device's row distinguished by a unique numeric ID. I convert this into a MATLAB table using the readtable() method. I can then organize the file by grouping device ID's separately by using the sortrows() method on the Device ID column.
However, how would I split the grouped devices into seperate tables? Currently I use the following algorithm:
for g = 1:numDevices %create a new file for each device type
outputFileIndoorData1 = sprintf("C:\Users\Documents\duetTestFile%d",g);
for h = 1:height(indoorDataSorted) %Iterate through entire CSV, splitting by device ID
if strcmp(indoorDataSorted.device_id(h),deviceIDs(g,1))
writelines(indoorDataSorted(h,1:17),outputFileIndoorData1); %Write to individual file specified
end
end
end
This is extremely resource intensive, however. What could be a more efficient way separating each devices data into a different file?
You should be able to do this, fairly efficiently, with a couple of lines based on the unique function.
%Setup a small sample data table to work with.
exampleData = cell2table({...
'd1' 1 2; ...
'd1' 3 4; ...
'd1' 5 6; ...
'd1' 7 8; ...
'd2' 9 10; ...
'd2' 11 12; ...
'd3' 13 14; ...
'd3' 15 16; ...
'd3' 17 18; ...
'd3' 19 20; ...
}, 'VariableNames', { ...
'DeviceName', 'data1', 'data2'} );
% The "unique" built-in function is pretty efficient, and
% outputs some useful secondary outputs. We're going to use
% the 3rd argument, that I have names ixs2
[deviceNames, ixs1, ixs2] = unique( exampleData.DeviceName );
%Now, based on the "deviceNames", and "ixs2" output, we can just loop
% through and save output
for ixDevice = 1:length(deviceNames)
curDevice = deviceNames{ixDevice};
curMask = (ixs2 == curDevice);
curData = exampleData(curMask,:);
%Save data here. Save the whole thing at once.
% Name, if needed, is: curDevice
% Datatable is: curData
end
For anyone that is not running a live version of Matlab on the side, the outputs of the unique call in this case are as follows:
%The standard output, a list of unique names
deviceNames =
3×1 cell array
{'d1'}
{'d2'}
{'d3'}
%A set of indexes, which point from the original set into the new set.
% Strictly speaking, this doesn't have to be unique. But the function
% always points to the first one.
ixs1 =
1
5
7
%A set of indexes, which map each element of the original set to the
% unique set from output argument #1. This is often the most
% useful output. This question is a decent example. It can also
% be used as the fist input to an "accumarray" function call, which
% can be incredibly powerful.
ixs2 =
1
1
1
1
2
2
3
3
3
3

How to create matrices that are subsets of larger matrices

I'm learning matlab. I'd like to create a smaller array from a larger one. I know how to do this with simple columns or rows, but I get lost in the nomenclature for m x n arrays / matrices.
Original matrix = 10 x 9
mat_original=ones(10,9) in fact, rather than use all ones.. this may make more sense.. lets use mat_original = magic(10)
How do I create a component matrix say with rows 5 to 8 (all columns)?
mat_rows5to8 = mat_original[5 thru 8; :]
How do I create a component matrix, say with columns 2 to 5, (all rows?)
mat_cols2to5 = mat_original[: ; 2 thru 5 ]
and finally how would I create a sub-component array... say rows 4 thru 7, and columns 5 thru 9 ?
mat_small = mat_original[ 4 thru 7; 5 thru 9 ]
How do you remember this stuff?
No need to remember things when you have Google: Matrix Indexing in MATLAB.
Answers to your questions:
mat_rows5to10 = mat_original(5:8,:)
mat_cols2to5 = mat_original(:,2:5)
mat_small = mat_original(4:7,5:9)
In other words:
output = input(<row_first>:<row_last>,<col_first>:<col_last>)
Leave any of the parameters out to include all.

Matlab complex matrix magnitude

I have a matrix S something like:
1 4 7
2 5 8
3 6 9
Then I make a=complex(S{2},S{3}) and wanted to find the abs(a);. This is not possible in MATLAB as a is not an integer - it is a matrix. How can I get the magnitude of each row of matrix a?
PS: the matrix is read from a text file using textscan() as S = textscan(fileID,'%d %d %d', 'delimiter','\t');.
Second question:
Assuming again hav the following S matrix.
1 4 7 2 1
2 5 8 3 4
3 6 9 6 8
Now I wanted to arrange them in such way that column 2,3 and 4,5 alternate like this:
4 2
7 1
5 3
8 4
6 6
9 8
How can I do that without using a loop?
Thanks.
Going with my assumption in the comments, I'm going to assume that the second column consists of your real component of your matrix while the third column consists of your imaginary components. Your matrix S is actually a cell array of elements. You don't need to use complex then abs. You can simply take each of the columns, individually square them, add them together and take the square root. What I would do is convert the cell array into a 2D matrix, cast it to double to allow for floating point precision when finding the magnitude, and do what I just did above. This is necessary because abs and sqrt will only work for floating-point numbers. Your elements in S are already int32 due to the %d delimiter from textread. In other words:
Smat = double(cell2mat(S));
realComp = Smat(:,2);
imagComp = Smat(:,3);
mag = sqrt(realComp.^2 + imagComp.^2);
mag will thus return the magnitude of each row for you, assuming that the second column is the real component and the third component is the imaginary component as we specified.
However, if you're dead set on using complex and abs, you can do it like so:
Smat = double(cell2mat(S));
imagNumbers = complex(Smat(:,2), Smat(:,3));
mag = abs(imagNumbers);
This should still give you the same results as we talked about above.
Edit
Seeing your edit in your post above, we can achieve that quite easily by subsetting the matrix, then applying reshape to each part of the matrix you want. In other words:
Smat = double(cell2mat(S));
realMat = Smat(:,2:3); %// Grab second and third columns
imagMat = Smat(:,4:5); %// Grab fourth and fifth columns
realCol = reshape(realMat.', [], 1); % // Form the columns like you specified
imagCol = reshape(imagMat.', [], 1);
finalMatrix = [realCol imagCol];
finalMatrix should contain those two columns that you specified above in a single matrix.

Writing to a text file in Matlab

I've come across numerous ways to write matlab data to a .txt file but I am unsure which way would be best suited for my needs - I have two sets of data labelled 'x' and 'y' within which data simply runs down 1 column (A1....An) and I need a tab delimited .txt file made with the format:
Name X X Y
Test 2 2 5.5
Test 3 3 6.5
Test 4 4 7.5
etc...
Whereby I can have 2 identical columns of the X data, followed by the Y data. I also need to be able to input something for the 'Name' column which will copy itself down until the data in X/Y stops. I don't need any column headers in it i.e. 'X' 'Y' or 'Name' just the data itself.
What would be the best way to go about this?
Run this code example and you can check that it does what you want:
% Example data:
x = [1:5];
y = rand(1,5);
fileID = fopen('yourfile.txt','w');
for i = 1:length(x)
fprintf(fileID,'%s\t%d\t%d\t%f\n', 'Test', x(i),x(i),y(i));
end
fclose(fileID);
Opening the text file you will see something like:
Test 1 1 0.655741
Test 2 2 0.035712
Test 3 3 0.849129
Test 4 4 0.933993
Test 5 5 0.678735
If you want the value for string 'Test' to change in each row, simply pass in an array with those string values, similar to how the x and y variables are passed to the fprintf() statement.
One way is to first put everything into a single cell:
Name = repmat({'Test'}, [1 DataSize]); % A Cell containing n 'Test' string
C = [Name num2cell(X') num2cell(X') num2cell(Y')]; % Concatenating cells
Then use fprintf to write the cell into a file:
fid = fopen('data.txt', 'wt');
fprintf(fid, '%s\t%d\t%d\t%d\n', C{:});
fclose(fid);
Hope it helps.

for loop in matlab

Hi I have the following code which I believe have indexed wrongly and so Im not getting the answer I am looking for
Diesel_matrix = xlsread('test_diesel.xlsx','Sheet2');
Diesel_supply = Diesel_matrix(:,1); % Power output of diesel generator
hourly_cost = Diesel_matrix(:,2); % Diesel cost of running genreator at that output
for z = 1:21
A = [-PV_supply -WT_supply -Diesel_supply(z)*ones(24,1)];
f = [CRF_PV*CC_PV; CRF_WT*CC_WT; (CRF_Diesel_generator*CC_Diesel)+sum(hourly_cost(1:z))] ;
b = -Demand;
[x,fval,exitflag] = linprog(f,A,b,[],[],lb,ub)
end
I am trying to loop only for the third column of matrix A.
I would like to loop for all the rows in "Diesel_supply" per row of matrix A
at the moment, the code works for 21 sets of x outputs but column 3 is either row 1,2,3 etc up to row 21 of "Diesel_supply". Wheras I am trying to get it for row 1 and 2 and 3 and 4 etc up to row 21 of "Diesel_supply".
This will allow me to examine all the elements in "Diesel_Supply"
Per the conversation #user643469 and I had in chat (see link in comments section) and looking at the documentation for linprog afterwards, I think you need to store the results of each z-iteration in a data structure and then pick the best one after the loop has finished.
As I understand, the generator has 21 different modes you can run it in and it is subject to 24 different constraints. Each mode changes the constaints a little.
Instead of
[x,fval,exitflag] = linprog(f,A,b,[],[],lb,ub)
use
val = linprog(f,A,b,[],[],lb,ub)
results(z) = val;
After the loop has finished, you will be left with a results matrix with the dimensions 4x21 where the first column contains x-values, second contains fval values and third contains exitflag values. You can then you through this 'results' matrix to determine which of the 21 modes you have available to run the generator in.