Phil Steitz a écrit :
> Luc Maisonobe wrote:
>> Luc Maisonobe a écrit :
>>  
>>> Phil Steitz a écrit :
>>>    
>>>> There are a couple of things about the decomposition API that are
>>>> starting to bug me.  Apologies for not having raised them until now,
>>>> since they apply to LU as well as the new Eigen decomp.
>>>>
>>>> 1) I don't like the state dependencies bleeding into the decomposition
>>>> interfaces - i.e., having the interface contract include the
>>>> requirement
>>>> that decompose() be called before the getters.  Logically, the
>>>> decomposition interfaces should just *be* the getters, which is now the
>>>> case for EigenDecomposition, but not LU (where the interface includes
>>>> the decompose method).   The state dependency is an implementation
>>>> artifact that should not be included in the decomposition interface.
>>>>
>>>> 2) It would seem natural for decompose return a decomposition, rather
>>>> than void.
>>>> I am not sure if there is an efficient way to address both of these,
>>>> since the caching and incremental computation in the current impls is
>>>> sort of essential.  At a minimum, we should probably remove the
>>>> advertised exceptions and decompose methods from the interfaces.
>>>>
>>>> Here is one idea that may or may not work.  It would make the API a
>>>> little more complicated, but if we split the implementation classes
>>>> into
>>>> decomposers and decompositions, with decompose producing a
>>>> decomposition, the decompositions would be able to handle state
>>>> transparently to users.
>>>>       
>>> I will try to introduce this.
>>>     
>>
>> A few more thoughts. If I understand correctly, you propose is to
>> separate the decomposition part in an interface with a decompose method
>> and the solver part as the interface returned by this decompose method.
>> We would have two parallel hierarchies of interfaces/classes:
>>
>> interface DecompositionEngine {
>>   public DecompositionSolver decompose(RealMatrix);
>> }
>>
>> interface XYZEngine extends DecompositionEngine {
>>
>>   public void setThreshold(final double threshold) {
>>      this.threshold = threshold;
>>   }
>>
>>   public XYZDecomposition xyzDecompose(RealMatrix matrix) {
>>     XYZDecomposition decomposition = new XYZDecompositionImpl();
>>     decomposition.setThreshold(threshold);
>>     decomposition.doWhatYouWantWithMatrix(matrix);
>>     return decomposition;
>>   }
>>
>>   public DecompositionSolver decompose(RealMatrix matrix) {
>>     return xyzDecompose(matrix);
>>   }
>>
>> }
>>
>> interface DecompositionSolver {
>>   public RealVector solve(RealVector);
>> }
>>
>> interface XYZDecomposition extends DecompositionSolver {
>>   public void setThreshold(double threshold);
>>   public RealMatrix getX();
>>   public RealMatrix getY();
>>   public RealMatrix getZ();
>> }
>>
>> class XYZDecompositionImpl() implements XYZDecomposition {
>> }
>>
>> This allows both dedicated use of a specific algorithm (XYZ) and the
>> extra methods it provides (setThrehold, getX ...) and use of generic
>> interfaces (DecompositionEngine, DecompositionSolver) and the generic
>> methods (solve, getInverse ...). It is however quite complex.
>>
>> A simpler approach is to remove the umbrella interface
>> DecompositionEngine and the generic decompose method and retain
>> everything else (perhaps reusing the single name "decompose" for the now
>> independent methods with different return types). The
>> DecompositionSolver interface would be kept. This prevents use of a
>> generic engine.
>>
>> An even simpler approach would be to completely remove the state
>> dependencies part by removing the decompose method and forcing
>> everything to be set up right at construction. I'm not sure you would
>> consider it addresses your second point.
>>
>> Luc
>>   
> 
> Sorry I was not clear.  What I meant was to split things more along the
> following lines (assuming this can be made to work), for e.g.
> EigenDecompostion.
> 
> 1. Keep EigenDecomposition as is, but make it standalone - i.e., drop
> the "Extends DecompositionSolver".  So this now just represents a
> decomposition.
> 
> 2. Leave the decompose method in a DecompositionEngine or somesuch with
> signature
> EigenDecomposition decompose(RealMatrix).  Leave solve there or put in a
> separate solver class with signature
> double[] solve(double[] b, EigenDecomposition ed)
> 
> So you use decompose(RealMatrix) do create a decomposition that can be
> used directly or passed to a solver.    This gets around the state
> dependencies and the need to have constructors do the decompositions. 
> The DecompositionEngine's decompose method could return a
> DecompositionImpl that handles state / incremental computation
> transparently to users.

I have implemented this. I agree the separation between decomposition
and solve was worth the change. Could you have a look to the new API ?

Luc

> 
> Phil
> 
>>  
>>> Thanks for the advice.
>>> Luc
>>>
>>>    
>>>> Phil
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>>>> For additional commands, e-mail: [EMAIL PROTECTED]
>>>>
>>>>
>>>>       
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>>> For additional commands, e-mail: [EMAIL PROTECTED]
>>>
>>>
>>>     
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>> For additional commands, e-mail: [EMAIL PROTECTED]
>>
>>   
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to