Iterate though a matrix with repeated values and preform operations on corresponding columns.

Hello,
I have a matrix of three columns and many rows, the third column has several (ordered) repeated values for example A=[0.5 0.2 1; 0.6 1.2 1; 0.3 0.23 1; 0.52 0.64 2; 0.56 0.7 2] etc. I would like to iterate through the matrix, and for each repeated 3rd column preform a operation on the associated first and second column values. My current code is as follows:
IDs=A(:,3);
[rows, columns] = size(IDs);
Count=0;
for i=1:rows
for j=1:columns
if IDs==IDs(i,j)
P(i,j) = polyfit(A(i,1),A(j,2),1);
Count=Count+1;
end
end
T=unique(IDs);
D=[P T];
end
This doesn't return any value of P, although it runs without errors. Any help would be much appreciated. Thanks..

 Risposta accettata

There are multiple issues with your code, but they all boil down to the superfluous looping over rows and columns. Doing so means polyfit is applied to scalar values, which is totally useless.
Try this instead:
A = [0.5 0.2 1; 0.6 1.2 1; 0.3 0.23 1; 0.52 0.64 2; 0.56 0.7 2]
X = accumarray(A(:,3),A(:,1),[],@(v){v})
Y = accumarray(A(:,3),A(:,2),[],@(v){v})
C = cellfun(@(x,y)polyfit(x,y,1),X,Y,'UniformOutput',false);
this gives the points fitted in cell arrays X and Y, and the fitted polyfit output (coefficients) in the cell array C. For the example data, it gives these coefficients:
>> C{:}
ans =
2.75000 -0.74000
ans =
1.50000 -0.14000
Plot in a Loop
I also plotted these coefficients and the original data, to check them:
F = 'rg';
V = 0:0.01:1;
for k = 1:numel(C)
plot(X{k},Y{k},['o',F(k)])
hold on
plot(V,polyval(C{k},V),F(k))
end
Plot at Once
You could also plot it without any (explicit) loop:
V = 0:0.01:1;
Z = [X,Y]';
Z(3,:) = {'o'};
plot(Z{:})
hold on
W(2,:) = cellfun(@(c)polyval(c,V),C,'UniformOutput',false);
W(1,:) = {V};
plot(W{:})
This has the advantage that it uses the axes/figure ColorOrder property, so you do not need to specify the colors yourself:

9 Commenti

Hi, please may i ask what does the 'cellfun(@(c)' part of the code do? as the c is used again in the polyval part, thankyou.
The code
@(c)polyval(c,V)
defines an anonymous function, and it returns its function handle. This anonymous function uses the value of V from the main workspace, and whatever values of c that it gets passed as a function input.
The function cellfun requires a function handle for its first input, and applies this function to every cell of the input cell array/s.
Thankyou!! If I want to increase my matrix size, I do get an error here, that:
Subscripted assignment dimension mismatch.
W(2,:) = cellfun(@(c)polyval(c,V),C,'UniformOutput',false);
is there a way to overcome this please?
You need to delete W from your workspace before running that code. The code assumes that W does not exist, and if W already exists and has a different size, then it will cause an error.
This is one of the reasons why writing functions is so much better than writing scripts: you don't get random old variables hanging around. You should consider writing functions, which would avoid this problem and many others:
Is there a way to calculate the R^2 value for these fits using the output values? I used [P,S]=cellfun(@(x,y)polyfit(x,y,1),X,Y,'UniformOutput',false) which gives a structure array for each with fields R (triangular factor), df (degrees of freedom) and normr(norm of residuals)?
p = polyfit(x,y,degree);
polydata = polyval(p,x);
sstot = sum((y - mean(y)).^2);
ssres = sum((y - polydata).^2);
rsquared = 1 - (ssres / sstot);
Or:
I have tried this, but since all of my data is in cells, for each given ID (ordered repeats), and my polyval values are in the W cell array it does not work .
@Matlab User: so you tried "this", but you are not going to tell us what "this" is. Sorry but my mind-reading ability is a bit rusty. Perhaps you tried something, but how am I supposed to know what you tried if you don't actually show it to us? Perhaps it caused an error? Or the output just seemed wrong? You see, without you showing us we have no way of knowing what you did, or what happened when you did "this".
In any case: you have data in cells. So loop over the cell arrays.

Accedi per commentare.

Più risposte (0)

Categorie

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by