MatLab function for each two values in struct inside loop
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
Mohammed Hammad
el 29 de Mzo. de 2019
Hello,
I have a struct with some fileds, (attached)
something like exp = {'Names', 'Date', 'X' , 'Y'}
Names = ['John', 'Adam', 'Markus',.....]
X = [ X1, X2, X3, X4,.....]
Y = [ Y1, Y2, Y3, Y4,.....]
I want to run an equation to calculate the sqrt for each two values depending on the same field (Date)
For Date (Date 1)
s12 = sqrt((X2-X1)^2+(Y2-Y1)^2);
then
s13= sqrt((X3-X1)^2+(Y3-Y1)^2);
and
s14= sqrt((X4-X1)^2+(Y4-Y1)^2);
and
s23 = sqrt((X3-X2)^2+(Y3-Y2)^2);
and
s24 = sqrt((X4-X2)^2+(Y4-Y2)^2);
and
s34 = sqrt((X4-X3)^2+(Y4-Y3)^2);
And the same for (Date2)
So I wrote a loop as follows:
for i= 1:length(example)
for j = i+1;
for u = 1:length(unique(example.dates,'rows'));
s(i) = sqrt((example(j).x-example(i).x)^2+(example(j).y-example(i).y)^2);
abr{i} = sprintf('%s-%s',strtrim(example(j).name),strtrim(example(i).name));
end
end
end
%%%%% Export results to an array (Date, Name i_Name j, S)
result = [];
for n = 1:length(unique(example.dates,'rows'));
result = [result; dates(n) abr(n) d(n)];
end
But I am sure there is something wrong because I should get s for all the pairs of the values and just for the same date each time.
The results should be something like that:
Please help me to figure out how to do that.
4 comentarios
Luna
el 29 de Mzo. de 2019
You have the same names and also same dates, are you sure that your name list will be unique for each date? Otherwise you will get a row like Ronny vs Ronny for example.
Respuesta aceptada
Stephen23
el 29 de Mzo. de 2019
Editada: Stephen23
el 29 de Mzo. de 2019
load example.mat
C = {example.Name};
D = {example.dates};
M = [example.x;example.y];
[U,~,idu] = unique(D);
N = max(idu);
fprintf('%-12s %-10s %-10s %s\n','Date','Name1','Name2','Result')
for k = 1:N
idf = find(idu==k);
P = nchoosek(1:numel(idf),2);
V = sqrt(sum((M(:,idf(P(:,1)))-M(:,idf(P(:,2)))).^2,1));
T = [repmat(U(k),size(V));C(idf(P(:,1)));C(idf(P(:,2)));num2cell(V)];
fprintf('%-12s %-10s %-10s %#.5g\n',T{:});
end
Which prints this in the command window:
Date Name1 Name2 Result
02-Apr-2002 John Adam 4.8237e+06
02-Apr-2002 John Markus 6.7899e+06
02-Apr-2002 John Ronny 7.4859e+06
02-Apr-2002 John Michael 3.8794e+06
02-Apr-2002 Adam Markus 5.9770e+06
02-Apr-2002 Adam Ronny 6.6450e+06
02-Apr-2002 Adam Michael 4.7198e+06
02-Apr-2002 Markus Ronny 7.3046e+05
02-Apr-2002 Markus Michael 2.9522e+06
02-Apr-2002 Ronny Michael 3.6236e+06
03-Apr-2002 Ronny Markus 5.9770e+06
03-Apr-2002 Ronny Michael 6.6450e+06
03-Apr-2002 Ronny John 4.8237e+06
03-Apr-2002 Ronny Adam 4.7198e+06
03-Apr-2002 Ronny Romio 5.8499e+05
03-Apr-2002 Ronny Sebastian 7.4353e+06
03-Apr-2002 Markus Michael 7.3046e+05
03-Apr-2002 Markus John 6.7899e+06
03-Apr-2002 Markus Adam 2.9522e+06
03-Apr-2002 Markus Romio 6.1503e+06
03-Apr-2002 Markus Sebastian 1.0072e+07
03-Apr-2002 Michael John 7.4859e+06
03-Apr-2002 Michael Adam 3.6236e+06
03-Apr-2002 Michael Romio 6.8414e+06
03-Apr-2002 Michael Sebastian 1.0753e+07
03-Apr-2002 John Adam 3.8794e+06
03-Apr-2002 John Romio 4.3132e+06
03-Apr-2002 John Sebastian 3.3172e+06
03-Apr-2002 Adam Romio 4.6077e+06
03-Apr-2002 Adam Sebastian 7.1300e+06
03-Apr-2002 Romio Sebastian 6.8562e+06
>>
And checking the last one:
>> sqrt((example(11).x-example(12).x).^2 + (example(11).y-example(12).y).^2)
ans =
6.8562e+06
>> example(11:12).Name
ans =
Romio
ans =
Sebastian
>> example(11:12).dates
ans =
03-Apr-2002
ans =
03-Apr-2002
7 comentarios
Mohammed Hammad
el 30 de Mzo. de 2019
Editada: Mohammed Hammad
el 30 de Mzo. de 2019
Stephen23
el 31 de Mzo. de 2019
Editada: Stephen23
el 31 de Mzo. de 2019
1. This loop:
for i=1:length(theFiles)
eval(['load ' theFiles(i).name]);
array = cell2struct(data, Headings, 2);
end
serves absolutely no purpose whatsoever, because you do not use any indexing (or concatenation) to store the output array, and so you simply overwrite array except for the one defined on the last iteration. So every previous iteration is just a waste of time. Also that eval usage should be avoided, which you can do very simply:
load(theFiles(i).name)
or even better:
S = load(theFiles(i).name);
array = cell2struct(S.data, Headings, 2);
2. You never use the variable array for anything anyway: once you have imported that data and created array you just ignore it. Seems like a waste of time to me!
3. For some reason you are still accessing a variable named example, although this is not defined anywhere in your code.
In any case that error message is very easy to understand: you will get that error whenever numel(idf)<2, i.e. there is only one name in the entire date group. If there is only one name (for a particular date) then clearly it is not possible to generate all combinations of two names from it! You will need to decide what to do in those cases (I cannot decide how your algorithm should work), but most likely you will need to add an IF condition, something like this:
Z = cell(1,N); % preallocate. Why did you remove this??? Very bad idea!
for k = 1:N
idf = find(idu==N);
if numel(idf)>1
... your code
Z{k} = T; % add data
else
... decide what you want to do with zero/one names.
end
end
Z = [Z{:}] % concatenate
Depending on how you decide to handle the one-name groups, you might need to use indexing for the concatenation as well.
Más respuestas (0)
Ver también
Categorías
Más información sobre Loops and Conditional Statements en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!