2013-08-24 155 views
2

在Matlab中,我想一個數據結構,看起來像這樣:子結構與相關領域

DataStruct 
    .model 
    .Q 
    .Qchol 
     . 
     . 
    .system 
     . 
     . 

結構很可能是一類,雖然我並不真的需要所有的其他功能伴隨着oop。

但我需要

  • 如果Q自動Qchol = cholcov(Q)分配的東西,那麼。
  • 如果Qchol被分配了一些東西,然後自動Q = Qchol' * Qchol
  • 同時,既QQchol存儲快速讀取訪問
  • QQchol是可寫的,通過簡單的任務,如:DS1.mod.Q = value

我知道我可以做model一類,並且已經設置了/獲取Q和Qchol的方法。然而,對於兩個矩陣來說,這看起來似乎是一個矯枉過正的問題(加上可能還有一些字段)。此外,Matlab 警告我不應該在設置方法期間訪問其他屬性。

所以:有這樣的數據結構,最好沒有警告的最佳方式是什麼?

回答

3

你基本上希望賦值(DS1.mod.Q = value)有副作用,這不可避免地暗示了一個setter,因此也就是一個類。你應該放棄這個要求,或者寫一個班級。

如果您希望避免在類聲明中定義屬性,您可以使用Dynamic Properties,它允許您在運行時添加屬性(儘管有一些指示語法addprop())。

編輯

帕特里克的問題更大然後就M-皮棉。考慮下面的類:

classdef cantInstantiateMe < handle 
    properties 
     x 
     minus_x 
    end 
    methods 
     function obj = cantInstantiateMe(x) 
      obj.x = x; % <-- this calls set.x(), which calls set.minus_x(), which calls set.x(), ... 
      obj.minus_x = -x; 
     end 

     function set.x(obj, value) 
      obj.x = value; 
      obj.minus_x = -value; % <-- this gives an M-Lint warning 
     end 

     function set.minus_x(obj, value) 
      obj.minus_x = value; 
      obj.x = -value;     
     end 

    end 
end 

這個類不能被實例化,因爲每個setter會調用其他二傳(這不是MATLAB專用)。試圖在我的機器上實例化:

???達到500的最大遞歸限制。使用set(0,'RecursionLimit',N) 來更改限制。請注意,超出您的可用堆棧空間可能會使MATLAB和/或您的計算機崩潰 。

在這一點上,我認爲你有兩個選擇:

  • 讓無論是QQchol一個dependent property。這將以每次讀取訪問時重新計算依賴屬性爲代價。
  • 使用一些私人陰影屬性,例如shadow_Qshadow_Qchol當公共屬性的setter被調用時將被設置,並且當它們的getter被調用時被返回。類似於:

    function set.x(obj, value) 
         obj.shadow_x = value; 
         obj.shadow_minus_x = -value; 
    end 
    
    function value = get.x(obj) 
         value = obj.shadow_x; 
    end 
    

    請注意,我沒有正確測試,所以我不知道Matlab中的所有含義。在我熟悉的其他語言中,這應該可以正常工作。

  • 關於警告 - 我的方法是禁用警告是安全的,只要你真的知道你在做什麼。
+0

是的,謝謝你在我的問題上有用的觀點,這使得你的結論更加明顯。你對Matlab給我的警告有什麼看法?這樣的副作用(影響另一個財產)肯定是一個共同的願望?當然有一個很好的方法來做到這一點? – Patrick

+0

感謝您的全面編輯。實際上我已經試過了你上面的不可實例化的例子。我的方法是添加一個內部開關,告訴setter不要設置另一個(因爲它已經被設置)。但是使用你的方法不會帶來任何警告,所以它可能更乾淨。 – Patrick

+0

@Patrick - 歡迎您:) – bavaza

1

@bavaza所示,實現此目的的一種方式是使用具有相應陰影私有屬性的依賴屬性。

下面是實現內部數據結構的代碼(靈感來自this post)。你需要用的組合物,使這個類的一個實例外部對象的屬性:

classdef Model < handle 
    properties (Dependent) 
     Q 
     Qchol 
    end 
    properties (Access = private) 
     Q_ 
     Qchol_ 
    end 

    methods 
     function obj = Model() 
     end 

     function val = get.Q(obj) 
      val = obj.Q_; 
     end 
     function val = get.Qchol(obj) 
      val = obj.Qchol_; 
     end 

     function set.Q(obj, val) 
      obj.Q_ = val; 
      obj.Qchol_ = cholcov(val); 
     end 
     function set.Qchol(obj, val) 
      obj.Qchol_ = val; 
      obj.Q_ = val'*val; 
     end 
    end 
end 

用暴露的相關屬性,都會同時影響基礎變量設定一個值:

>> m = Model 
m = 
    Model with properties: 

     Q: [] 
    Qchol: [] 

>> m.Qchol = rand(3) 
m = 
    Model with properties: 

     Q: [3x3 double] 
    Qchol: [3x3 double] 
+0

我很高興看到這在Matlab中沒有奇怪的副作用。添加到我的食譜:) – bavaza

+0

謝謝,這確實是我所採用的解決方案。我還沒有嘗試過構圖,但我認爲它會正常工作。 – Patrick