commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Phil Steitz <phil.ste...@gmail.com>
Subject Re: [math] Matrix decomposition API
Date Wed, 03 Dec 2008 01:43:09 GMT
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.

Phil

>   
>> Thanks for the advice.
>> Luc
>>
>>     
>>> Phil
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>
>>>
>>>       
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>
>>     
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>   


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message