2014-04-23 9 views
5

powiedzmy, że mam dwie tablice strukturę z pasującymi dziedzinach, a także zawartości obu tablicach w danej dziedzinie są tego samego rozmiaru:Jak skutecznie zastosować liniową kombinację dwóch różnych tablic struktury?

A.field1 = [1,2,3] 
A.field2 = 5 

B.field1 = [4,5,6] 
B.field2 = 9 

Chciałbym wziąć liniowej kombinacji wszystkich danych w każdym polu. W naszym przykładzie będzie to oznaczać, że jeśli x i y są stałymi, chciałbym, aby uzyskać strukturę tablicy C takie, że

C.field1 = x*(A.field1) + y*(B.field1) 
C.field2 = x*(A.field2) + y*(B.field2) 

Moje pierwsze przypuszczenie było używać command structfun ale to tylko wydaje się pojedynczą strukturę array jako wejście, gdzie potrzebowałbym wejść A i B.

Tępym sposobem jest wyodrębnianie wszystkich danych i przechowywanie ich w oddzielnych zmiennych, weź liniową kombinację i umieść je z powrotem w tablicy struktur. Ale wydaje się, że musi być prostszy sposób (lub przynajmniej taki, który jest szybszy do wpisania, moje tablice nie są tak małe).

+2

Jeśli szukasz rozwiązania, które pozwala na bardzo czyste i łatwe do wykonania kodu, chciałbym używać obiektów zamiast elemencie. Tutaj możesz nadpisać operacje 'plus' lub' times' własnymi metodami (kod oparty na jednej z odpowiedzi). Jeśli to zrobisz, możesz użyć składni takiej jak 'x * A + y * B'. To rozwiązanie będzie wolniejsze w czasie wykonywania. – Daniel

Odpowiedz

1

Po zakłada, masz dwie tablice strukturę z dowolnej liczby dopasowanych polach (n - ta sama dla obu strukturach), które nie są zagnieżdżone (nie A.field1.field2)

Pętla waniliowa:

x = 2; 
y = 3; 
names = fieldnames(A); % returns n x 1 cell array 

for n = 1:length(names) 
    C.(names{n}) = x*A.(names{n}) + y*B.(names{n}); 
end 

Wyjście:

C = 

    field1: [14 19 24] 
    field2: 37 

alternatywna użyciu cellfun:

x = 2; 
y = 3; 
names = fieldnames(A); 
A2 = struct2cell(A); 
B2 = struct2cell(B); 

C2 = cellfun(@(A,B) x*A+3*B, A2,B2,'UniformOutput',0); 
C2 = cell2struct(C2,names) 

wyjściowa:

C2 = 

    field1: [14 19 24] 
    field2: 37 
+0

Dzięki! Który z nich byłby obliczeniowo szybszy? Ten, który ma chyba celę komórkową? – Joachim

+0

Zgaduję, że "cela", ale nie sprawdziłem. – nkjt

1

Kod

%%// Input structs 
A.field1 = [1,2,3] 
A.field2 = 5 
A.field3 = [8 9]; 

B.field1 = [4,5,6] 
B.field2 = 9 
B.field3 = [11 12]; 

%%// Scaling factors 
scaling_factors = [2; 3]; %%// This is your [x y] 
cellA = cellfun(@(x) x*scaling_factors(1),struct2cell(A),'un',0) 
cellB = cellfun(@(x) x*scaling_factors(2),struct2cell(B),'un',0) 
cellC = cellfun(@plus, cellA, cellB,'uni',0) 

C = cell2struct(cellC, fieldnames(A)) 
1

Można konwertować je do komórki tablic, które obsługują wiele argumentów:

result = cell2struct(cellfun(@(x,y){1/4*x+3/4*y}, struct2cell(A),struct2cell(B)), fieldnames(A)); 

samego kodu, ale z lepszym stylu (jedna wkładki nienawidzę):

cellA = struct2cell(A); 
cellB = struct2cell(B); 
cellResult = cellfun(@(x,y){1/4*x+3/4*y},cellA,cellB); 
result = cell2struct(cellResult , fieldnames(A)); 
Powiązane problemy