how to write vector with different length in a file? - matlab

I have 7 vectors (L_mean_argil, L_Min_argil, L_Max_argil, R_mean_argil, R_Min_argil, R_Max_argil, Zero_argil) with different lengths and I want to create a .sae file with all the vectors. Here my code:
fileID = fopen('BN_for_prediciting_zeros_argilliti_v1.sae','w');
fprintf(fileID,'L_mean_argil, L_Min_argil, L_Max_argil, R_mean_argil, R_Min_argil, R_Max_argil, Zero_argil\n');
fprintf(fileID,'%6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f \n', L_mean_argil, L_Min_argil, L_Max_argil, R_mean_argil, R_Min_argil, R_Max_argil, Zero_argil');
fclose(fileID);
It doesn't write vectors properly. Someone can help me?
I expect this:
L_mean_argil(1) L_Min_argil(1) ... Zero_argil(1)
L_mean_argil(2) L_Min_argil(2) ... Zero_argil(2)
...
L_mean_argil(end) L_Min_argil(end) ... Zero_argil(end)
But in the final part of some vectors, there will be empty cells associated to others with values

Here is an answer assuming you want to leave blanks in rows with missing data.
%Sample Data all of different lengths
a = 1:4;
b = (1:6)+1;
c = (1:5)+2;
%Get max length
maxSize = max([numel(a) numel(b) numel(c)]);
%Convert to Cell array if it isn't already
a = num2cell(a,1);
b = num2cell(b,1);
c = num2cell(c,1);
%Initialize a cell to hold everything. Init to the max size
output = cell(3,maxSize);
output(1,1:numel(a)) = a;
output(2,1:numel(b)) = b;
output(3,1:numel(c)) = c;
%Print...
fprintf('%0.1f,%0.1f,%0.1f\n',output{:})
Results in the this:
1.0,2.0,3.0
2.0,3.0,4.0
3.0,4.0,5.0
4.0,5.0,6.0
,6.0,7.0
,7.0,

Related

How to store .csv data and calculate average value in MATLAB

Can someone help me to understand how I can save in matlab a group of .csv files, select only the columns in which I am interested and get as output a final file in which I have the average value of the y columns and standard deviation of y axes? I am not so good in matlab and so I kindly ask if someone to help me to solve this question.
Here what I tried to do till now:
clear all;
clc;
which_column = 5;
dirstats = dir('*.csv');
col3Complete=0;
col4Complete=0;
for K = 1:length(dirstats)
[num,txt,raw] = xlsread(dirstats(K).name);
col3=num(:,3);
col4=num(:,4);
col3Complete=[col3Complete;col3];
col4Complete=[col4Complete;col4];
avgVal(K)=mean(col4(:));
end
col3Complete(1)=[];
col4Complete(1)=[];
%columnavg = mean(col4Complete);
%columnstd = std(col4Complete);
% xvals = 1 : size(columnavg,1);
% plot(xvals, columnavg, 'b-', xvals, columnavg-columnstd, 'r--', xvals, columnavg+columstd, 'r--');
B = reshape(col4Complete,[5000,K]);
m=mean(B,2);
C = reshape (col4Complete,[5000,K]);
S=std(C,0,2);
Now I know that I should compute mean and stdeviation inside for loop, using mean()function, but I am not sure how I can use it.
which_column = 5;
dirstats = dir('*.csv');
col3Complete=[]; % Initialise as empty matrix
col4Complete=[];
avgVal = zeros(length(dirstats),2); % initialise as columnvector
for K = 1:length(dirstats)
[num,txt,raw] = xlsread(dirstats(K).name);
col3=num(:,3);
col4=num(:,4);
col3Complete=[col3Complete;col3];
col4Complete=[col4Complete;col4];
avgVal(K,1)=mean(col4(:)); % 1st column contains mean
avgVal(K,2)=std(col4(:)); % 2nd column contains standard deviation
end
%columnavg = mean(col4Complete);
%columnstd = std(col4Complete);
% xvals = 1 : size(columnavg,1);
% plot(xvals, columnavg, 'b-', xvals, columnavg-columnstd, 'r--', xvals, columnavg+columstd, 'r--');
B = reshape(col4Complete,[5000,K]);
meanVals=mean(B,2);
I didn't change much, just initialised your arrays as empty arrays so you do not have to delete the first entry later on and made avgVal a column vector with the mean in column 1 and the standard deviation in column 1. You can of course add two columns if you want to collect those statistics for your 3rd column in the csv as well.
As a side note: xlsread is rather heavy for reading files, since Excel is horribly inefficient. If you want to read a structured file such as a csv, it's faster to use importdata.
Create some random matrix to store in a file with header:
A = rand(1e3,5);
out = fopen('output.csv','w');
fprintf(out,['ColumnA', '\t', 'ColumnB', '\t', 'ColumnC', '\t', 'ColumnD', '\t', 'ColumnE','\n']);
fclose(out);
dlmwrite('output.csv', A, 'delimiter','\t','-append');
Load it using csvread:
data = csvread('output.csv',1);
data now contains your five columns, without any headers.

Matlab: Looping through an array

This is my one dimensional array A. containing 10 numbers
A = [-8.92100000000000 10.6100000000000 1.33300000000000 ...
-2.57400000000000 -4.52700000000000 9.63300000000000 ...
4.26200000000000 16.9580000000000 8.16900000000000 4.75100000000000];
I want the loop to go through like this;
(calculating mean interval wise) - Interval length of 2,4,8
(a(1)+a(2))/2 - value stored in one block of a matrix say m= zeros(10)
then (a(1)+a(2)+a(3)+a(4))/4 ------ mean-----
then (a(1)+a(2)..... a(8))/8
then shift index;
(a(2)+a(3))/2; - mean
(a(2)+a(3)+a(4)+a(5))/4
(a(2)+a(3)...a(9))/8
SO basically 2^n length interval
You could do this using conv without loops
avg_2 = mean([A(1:end-1);A(2:end)])
avg_4 = conv(A,ones(1,4)/4,'valid')
avg_8 = conv(A,ones(1,8)/8,'valid')
Output for the sample Input:
avg_2 =
0.8445 5.9715 -0.6205 -3.5505 2.5530 6.9475 10.6100 12.5635 6.4600
avg_4 =
0.1120 1.2105 0.9662 1.6985 6.5815 9.7555 8.5350
avg_8 =
3.3467 5.4830 4.7506
Finding Standard Deviation for an example (std_4)
%// each 1x4 sliding sub-matrix is made a column
%// for eg:- if A is 1x6 you would get 1-2-3-4, 2-3-4-5, 3-4-5-6 each as a column
%// ending with 3 columns. for 1x10 matrix, you would get 7 columns
reshaped_4 = im2col(A,[1 4],'sliding'); %// change 4 to 2 or 8 for other examples
%// calculating the mean of every column
mean_4 = mean(reshaped_4);
%// Subtract each value of the column with the mean value of corresponding column
out1 = bsxfun(#minus,reshaped_4,mean_4);
%// finally element-wise squaring, mean of each column
%// and then element-wise sqrt to get the output.
std_4 = sqrt(mean(out1.^2))
Output for the sample Input:
std_4 =
7.0801 5.8225 5.4304 5.6245 7.8384 4.5985 5.0906
Full code for OP
clc;
clear;
close all;
A = [-8.92100000000000 10.6100000000000 1.33300000000000 ...
-2.57400000000000 -4.52700000000000 9.63300000000000 ...
4.26200000000000 16.9580000000000 8.16900000000000 4.75100000000000];
reshaped_2 = im2col(A,[1 2],'sliding'); %// Length Two
mean_2 = mean(reshaped_2);
out1 = bsxfun(#minus,reshaped_2,mean_2);
std_2 = sqrt(mean(out1.^2))
reshaped_4 = im2col(A,[1 4],'sliding'); %// Four
mean_4 = mean(reshaped_4);
out1 = bsxfun(#minus,reshaped_4,mean_4);
std_4 = sqrt(mean(out1.^2))
reshaped_8 = im2col(A,[1 8],'sliding'); %// Eight
mean_8 = mean(reshaped_8);
out1 = bsxfun(#minus,reshaped_8,mean_8);
std_8 = sqrt(mean(out1.^2))

Fill matrix with function values in Matlab

I've got 3 functions, oe1(n), oe2(n) and oe3(n).
I want to create a matrix representing the function values.
The structure of the matrix should be like this:
A = [oe1(0) oe2(0) oe3(0); oe1(1) oe2(1) od3(1); ...... ; oe1(N-1), oe2(N-1), oe3(N-1)];
I've tried filling it with a for loop, but it does not work.
Is there a standard Matlab operation for this? I really can't figure out how to do it.
Anders.
oe1(n1) = sin(2*pi*F*n1+phi)
oe2(n1) = ones(length(n1),1);
oe3(n1) = n1*Ts
pol = (oe2)'
vector_x = [a; b; c];
vector_veardier = [oe1(n1), 1, oe3(n1)]
xi = 1:N-1;
for i = 2:N-1;
for j = 1:3
vector_veardier(i, j) = oe1(j);
end
end
Do your functions accept vectors? If so you can use:
A = [oe1((1:N)'), oe2((1:N)'), oe3((1:N)')];
but otherwise you might have to use arrayfun:
A = [arrayfun(#oe1, (1:N)'), arrayfun(#oe2, (1:N)'), arrayfun(#oe3, (1:N)')];
Note that in your provided code you have not defined oeN as functions, but as some kind of array with a value inserted at position n1.
One way to do it with a for loop would however be:
A = zeros(N,3);
for i = 1:N,
A(i,:) = [oe1(i), oe2(i) oe3(i)];
end

Save a sparse array in csv

I have a huge sparse matrix a and I want to save it in a .csv. I can not call full(a) because I do not have enough ram memory. So, calling dlmwrite with full(a) argument is not possible. We must note that dlmwrite is not working with sparse formatted matrices.
The .csv format is depicted below. Note that the first row and column with the characters should be included in the .csv file. The semicolon in the (0,0) position of the .csv file is necessary too.
;A;B;C;D;E
A;0;1.5;0;1;0
B;2;0;0;0;0
C;0;0;1;0;0
D;0;2.1;0;1;0
E;0;0;0;0;0
Could you please help me to tackle this problem and finally save the sparse matrix in the desired form?
You can use csvwrite function:
csvwrite('matrix.csv',a)
You could do this iteratively, as follows:
A = sprand(20,30000,.1);
delimiter = ';';
filename = 'filecontaininghugematrix.csv';
dims = size(A);
N = max(dims);
% create names first
idx = 1:26;
alphabet = dec2base(9+idx,36);
n = ceil(log(N)/log(26));
q = 26.^(1:n);
names = cell(sum(q),1);
p = 0;
for ii = 1:n
temp = repmat({idx},ii,1);
names(p+(1:q(ii))) = num2cell(alphabet(fliplr(combvec(temp{:})')),2);
p = p + q(ii);
end
names(N+1:end) = [];
% formats for writing
headStr = repmat(['%s' delimiter],1,dims(2));
headStr = [delimiter headStr(1:end-1) '\n'];
lineStr = repmat(['%f' delimiter],1,dims(2));
lineStr = ['%s' delimiter lineStr(1:end-1) '\n'];
fid = fopen(filename,'w');
% write header
header = names(1:dims(2));
fprintf(fid,headStr,header{:});
% write matrix rows
for ii = 1:dims(1)
row = full(A(ii,:));
fprintf(fid, lineStr, names{ii}, row);
end
fclose(fid);
The names cell array is quite memory demanding for this example. I have no time to fix that now, so think about this part yourself if it is really a problem ;) Hint: just write the header element wise, first A;, then B; and so on. For the rows, you can create a function that maps the index ii to the desired character, in which case the complete first part is not necessary.

How to solve the .mat file sorting?

I have three .mat files, A.mat, B.mat and C.mat. And the content of the .mat files look like this:
![enter image description here][1]
It is in r2 = [rs2,cs2,sortedValues2] format. How can I sort rs2(e.g, 3468, 3909...) of the three
.mat files together in increasing order, and count the number of appearance of each element of rs2?
Anyone can give me any suggestion?
Original
First, you're going to want load each files r2, then pull out it's rs(1, :) value into a column vector, then sort that column vector. Once you have the vector, use logical indexing to determine how many times each element repeats. Finally, attach those tow columns together to attach each element to it's corresponding count. The output vector will have duplicate rows, but I assume that won't be a problem.
allData = [load('A.mat',r2); load('B.mat',r2)l; load('C.mat',r2)];
colVector = allData(:, 1);
sortedVec = sort(colVector);
countVec = zeros(size(sortedVec));
for ii = 1:length(sortedVec)
countVec(ii) = sum(sortedVec==sortedVec(ii));
end
outputVec = [sortedVec, countVec]
Edit
Since your edited question is easy, and almost the same as your original, I'll answer it here. Most of the code is the same, you just need to get the data out of the cell array instead of the files. Like so:
colVector = [yourCellArray{:}];
sortedVec = sort(colVector);
countVec = zeros(size(sortedVec));
for ii = 1:length(sortedVec)
countVec(ii) = sum(sortedVec==sortedVec(ii));
end
outputVec = [sortedVec, countVec]
load A
rs2_1 = r2(:,1);
clearvars r2
load B
rs2_2 = r2(:,1);
clearvars r2
load C
rs2_3 = r2(:,1);
clearvars r2
% to combine
rs2_combined = [rs2_1;rs2_2;rs2_3];
% to sort
rs2_sorted = sort(rs2_combined);
% to count for appearance
rs2_count = hist(rs2_combined, min(rs2_combined):1:max(rs2_combined));
EDIT: using cell arrays
% recreate your situation
R = cell(11,10);
R = cellfun(#(x) [randi(3000,50,1),ones(50,1),ones(50,1)*-.008], R,'UniformOutput', false);
% extract rs2
r = cell2mat( reshape(R, [1,1,11,10]) );
rs2 = reshape( r(:,1,:,:), [50*11*10,1] );
% do what you want
rs2_sorted = sort(rs2);
rs2_count = hist(rs2, min(rs2):1:max(rs2));
note - I assumed you have 50x3 arrays. If merely 50x1, then reshape(R, [1,11,10]) and reshape( r, [50*11*10,1] ); also works.
hist put all numbers into different bins of different values. It's equivalent to do
rs2_scale = min(rs2_combined):1:max(rs2_combined);
rs2_count = zeros(1, length(rs2_scale));
for ii = 1:length(rs2_scale)
rs2_count(ii) = sum( rs2_combined == rs2_scale(ii) );
end
To remove zero-count numbers -
rs2_count(rs2_count==0) = [];
Then you can calculate the probability -
rs2_prob = rs2_count / sum(rs2_count);
Validate this answer by
>> sum(rs2_prob)
ans =
1.0000