Save cell with numbers to text file - matlab

I have cell arrays A and B with different lengths and numbers.
A={1:0.5:5;1:0.5:2};
B={1:0.5:6;1:0.5:9};
C= [A;B];
I want to combine these cell arrays into a cell array C, which would then look like this:
C =
4×1 cell array
{1×9 double}
{1×3 double}
{1×11 double}
{1×17 double}
Then, I want to save this into a text file, that should look like this:
1.0000 1.5000 2.0000 2.5000 3.0000 3.5000 4.0000 4.5000 5.0000
1.0000 1.5000 2.0000
1.0000 1.5000 2.0000 2.5000 3.0000 3.5000 4.0000 4.5000 5.0000 5.5000 6.0000
1.0000 1.5000 2.0000 2.5000 3.0000 3.5000 4.0000 4.5000 5.0000 5.5000 6.0000 6.5000 7.0000 7.5000 8.0000 8.5000 9.0000
So far, I have only found code for text or same size arrays. This is my attempt, which doesn't work:
fid = open('filename.txt', 'wt');
fprintf(fid, '%f',C{:})
close(fid)

I believe the problem might be in the format you're specifying for the fprintf, as I believe using only '%f' will print one number on each row.
One way to do this would then be:
fid = fopen('filename.txt', 'wt');
for i = 1:length(C)
fmt = repmat('%f ',size(C{i})); % this only adds one whitespace in between numbers
fmt = [fmt,'\n']; % remember to add a new line
fprintf(fid,fmt,C{i});
end
fclose(fid);

Related

implementing "not equal to " loop in matlab

i have a simple problem i am quite new to matlab so i am having problem in implementing it i have two 64x2 matrices u and h.i have to check if a single row in u is not equal to all of the rows in h.then the row which is not equal should be saved in a separate matrix meanwhile i have written this code but what it does is that r(i,:) get all the values of u(i,:) when this code runs, what i want is that only those values of u(i,:) should be stored in r which are not similar to any row in h matrix.
h=[];
for j=1:8
for i=1:8
h=[h; i j];
end
end
u=[5.3,1.4;6,8;2,3;3,5.5;2.6,8;3.7,2;4,2;5,3;1.9,8;5.4,4;3.2,3;2,2;2,4;2,3;8,2.2;8,4;7.3,1.5;6.2,5.1;2.4,1.5;3,5;2,7.1;1.8,2.7;3,4;6,5;6,1;5,4;4,6;3.5,2;5,7;7.2,8;7,7;5,5;6,3;6,6;1,2;5,8;3,5;1,5;2,2;2,1;6,3;4,7;6,8;3,6;1,6;5,2;3,5;8,7;8,4;4,8;1,1;6,3;7,5;8,1;1,6;4,5;5,5;6,7;6,7;6,7;6,3;3,4;5,7;1,1]
for i=1
for j=1:64
if u(i,:)==h(j,:)
c=1
else
c=0
if c==0
r(i,:)=u(i,:)
end
end
end
end
can anyone help me please
You can do it in one line with ismember:
r = u(~ismember(u,h,'rows'),:);
With your example data, the result is
>> r
r =
5.3000 1.4000
3.0000 5.5000
2.6000 8.0000
3.7000 2.0000
1.9000 8.0000
5.4000 4.0000
3.2000 3.0000
8.0000 2.2000
7.3000 1.5000
6.2000 5.1000
2.4000 1.5000
2.0000 7.1000
1.8000 2.7000
3.5000 2.0000
7.2000 8.0000
use setdiff with 'rows' option to compute r. Please avoid unnecessary loops. pre-allocate when possible.
% construct h without loop
[h{1} h{2}]=ndgrid(1:8,1:8);
h=[h{1}(:) h{2}(:)];
% get r using setdiff
r = setdiff( u, h, 'rows')
Results with
r =
1.8000 2.7000
1.9000 8.0000
2.0000 7.1000
2.4000 1.5000
2.6000 8.0000
3.0000 5.5000
3.2000 3.0000
3.5000 2.0000
3.7000 2.0000
5.3000 1.4000
5.4000 4.0000
6.2000 5.1000
7.2000 8.0000
7.3000 1.5000
8.0000 2.2000
Solution of you question in NlogN complexity (N=64):
N=size(h,1);
[husorted,origin_husorted,destination_hu]=unique([h;u],'rows','first');
iduplicates=destination_hu(N+1:end)<=destination_hu(N),:);
r=u;
r(iduplicates,:)=0;
destination_uh is the only output of unique that is useful; It verifies [h;u]=husorted(destination_uh,:)]. 'first' ensures that if line i of u is equal line j of h, then destination_uh(i+N) is equal to destination_uh(j).
Solution for your particular h, with complexity N:
r=u;
r(all(u==round(u)&u>=1&u<=8,2),:)=0;

Indexing during assignment

Say I have this sample data
A =
1.0000 6.0000 180.0000 12.0000
1.0000 5.9200 190.0000 11.0000
1.0000 5.5800 170.0000 12.0000
1.0000 5.9200 165.0000 10.0000
2.0000 5.0000 100.0000 6.0000
2.0000 5.5000 150.0000 8.0000
2.0000 5.4200 130.0000 7.0000
2.0000 5.7500 150.0000 9.0000
I wish to calculate the variance of each column, grouped by class (the first column).
I have this working with the following code, but it uses hard coded indices, requiring knowledge of the number of samples per class and they must be in specific order.
Is there a better way to do this?
variances = zeros(2,4);
variances = [1.0 var(A(1:4,2)), var(A(1:4,3)), var(A(1:4,4));
2.0 var(A(5:8,2)), var(A(5:8,3)), var(A(5:8,4))];
disp(variances);
1.0 3.5033e-02 1.2292e+02 9.1667e-01
2.0 9.7225e-02 5.5833e+02 1.6667e+00
Separate the class labels and the data into different variables.
cls = A(:, 1);
data = A(:, 2:end);
Get the list of class labels
labels = unique(cls);
Compute the variances
variances = zeros(length(labels), 3);
for i = 1:length(labels)
variances(i, :) = var(data(cls == labels(i), :)); % note the use of logical indexing
end
I've done a fair bit of this type of stuff over the years, but to be able to judge, better vs. best, it would help to know what you expect to change in the data set or structure.
Otherwise, if no change is anticipated and the hard code works, stick with it.
Easy, peasy. Use consolidator. It is on the file exchange.
A = [1.0000 6.0000 180.0000 12.0000
1.0000 5.9200 190.0000 11.0000
1.0000 5.5800 170.0000 12.0000
1.0000 5.9200 165.0000 10.0000
2.0000 5.0000 100.0000 6.0000
2.0000 5.5000 150.0000 8.0000
2.0000 5.4200 130.0000 7.0000
2.0000 5.7500 150.0000 9.0000];
[C1,var234] = consolidator(A(:,1),A(:,2:4),#var)
C1 =
1
2
var234 =
0.035033 122.92 0.91667
0.097225 558.33 1.6667
We can test the variances produced, since we know the grouping.
var(A(1:4,2:4))
ans =
0.035033 122.92 0.91667
var(A(5:8,2:4))
ans =
0.097225 558.33 1.6667
It is efficient too.

How do I append elements to a matrix using a for loop?

I have following data matrix, I want to iterate over this matrix and look at a value in the last column based on a given row and add that row - last element of that row to a new matrix.
5.1000 3.3000 1.7000 0.5000 1.0000
6.8000 3.2000 5.9000 2.3000 3.0000
5.0000 2.3000 3.3000 1.0000 2.0000
7.4000 2.8000 6.1000 1.9000 3.0000
6.5000 3.2000 5.1000 2.0000 3.0000
4.8000 3.4000 1.9000 0.2000 1.0000
4.9000 3.0000 1.4000 0.2000 1.0000
5.1000 3.8000 1.5000 0.3000 1.0000
5.1000 3.4000 1.5000 0.2000 1.0000
5.5000 2.6000 4.4000 1.2000 2.0000
This is the code that I have
M1 = [];
M2 = [];
M3 = [];
for i=1:length(currentCell)
if currentCell(1,5) == 1.00
m3Data = currentCell(1:1,1:4);
%how can I add m3Data to M1
end
end
Let your original matrix be M, then this
M1 = M(find(M(:,5)==1),1:4)
puts all the rows ending with a 1 into M1, excluding the final column. Is that what you want ?
You could do it with a for loop if you want, but I don't see any need.

extracting variable from multiple matlab files into one file

I have this project task, and I'm having problems solving it.
I took samples of the words from 1 to 10 spoken by 10 people.
From each sample I extracted each word e.g, I extracted the word 1 from all samples into different files. I now have 10 files each having the extracted first word. I want to combine these into one single array.
file = wavread( 'G:\Segmented Data\amir.wav');
t = linspace(0,8,length(file));
t2=linspace(0,.8,8820);
section1 = file(1:8820,:);
sound(section1, 11025);
figure(1),
plot(t2,section1);
I have 10 files having the above code. I want to extract the variable section from all these into a new file, and store them in an array.
Do you want to concatenate arrays?
>> a = 1.0:0.1:1.9 % your data, obtained from `wavread()`
a =
1.0000 1.1000 1.2000 1.3000 1.4000 1.5000 1.6000 1.7000 1.8000 1.9000
>> b = 2.0:0.1:2.9 % your data, obtained from `wavread()`
b =
2.0000 2.1000 2.2000 2.3000 2.4000 2.5000 2.6000 2.7000 2.8000 2.9000
>> c = 3.0:0.1:3.9 % your data, obtained from `wavread()`
c =
3.0000 3.1000 3.2000 3.3000 3.4000 3.5000 3.6000 3.7000 3.8000 3.9000
>> combined = [a; b; c] % a, b, and c in one array
combined =
1.0000 1.1000 1.2000 1.3000 1.4000 1.5000 1.6000 1.7000 1.8000 1.9000
2.0000 2.1000 2.2000 2.3000 2.4000 2.5000 2.6000 2.7000 2.8000 2.9000
3.0000 3.1000 3.2000 3.3000 3.4000 3.5000 3.6000 3.7000 3.8000 3.9000
This will, of course, only work if a, b and c are the same number of columns wide. If they are different sizes, you will have to pad them out with zeros so that they are the same size.

Is there a way to do partial average over matrix in matlab

I have a matrix (table actually) which I imported from a file:
1.0000 1.9736
4.0000 0.2016
9.0000 0.0584
10.0000 0.0495
5.0000 0.1845
2.0000 0.6873
1.0000 1.4177
2.0000 0.4699
5.0000 0.1555
10.0000 0.0435
13.0000 0.0326
8.0000 0.0860
5.0000 0.1685
4.0000 0.1956
5.0000 0.1433
8.0000 0.0675
13.0000 0.0335
13.0000 0.0327
10.0000 0.0431
9.0000 0.0582
10.0000 0.0551
13.0000 0.0308
I want to get the average of each of the occurance on left column. That is:
avg = [
1.0000 1.69565
2.0000 0.5786
4.0000 0.1978]
and so on. I could do this with a wile or for group but this is not the matlab way. So how can I do this?
a=[randi(5,10,1) rand(10,1)];
a =
4.0000 0.4387
1.0000 0.3816
2.0000 0.7655
1.0000 0.7952
1.0000 0.1869
5.0000 0.4898
4.0000 0.4456
2.0000 0.6463
5.0000 0.7094
1.0000 0.7547
[uniqueID,~,uniqueInd]=unique(a(:,1));
[uniqueID accumarray(uniqueInd,a(:,2))./accumarray(uniqueInd,1)]
ans =
1.0000 0.5296
2.0000 0.7059
4.0000 0.4422
5.0000 0.5996
If your matrix is called a, try
>> accumarray(grp2idx(a(:,1)),a(:,2),[],#mean)
ans =
1.6957
0.5786
0.1986
0.16295
0.07675
0.0583
0.0478
0.0324
Note that grp2idx is part of Statistics Toolbox. If you don't have that, you can use the unique command to get the same results.