########################################
# The contents of this file are subject to the MLX PUBLIC LICENSE version
# 1.0 (the "License"); you may not use this file except in
# compliance with the License.
# 
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
# the License for the specific language governing rights and limitations
# under the License.
# 
# The Original Source Code is "compClust", released 2003 September 03.
# 
# The Original Source Code was developed by the California Institute of
# Technology (Caltech).  Portions created by Caltech are Copyright (C)
# 2002-2003 California Institute of Technology. All Rights Reserved.
########################################
#
#       Authors: Lucas Scharenbroich
#                Christopher Hart
# Last Modified: Dec 13 23:41:29 PST 2001
#

import Numeric
import MLab

from compClust.mlx.views import TransformView

##############################################################################
#
# MinLDView
#
# Transforms the dataset such that the variance is equally distributed
# across all dimensions
#
# This class does not need to override _mapKeysToParent
#
#############################################################################

class MinLDView(TransformView):

  """
  Provides a transformed view of your data such that the variance
  is evenly distributed across all dimensions (columns) of the dataset
  """

  def __init__(self, dataset, name=None):

    TransformView.__init__(self, dataset, None, name=name)
    self._refresh()
    
  def _refresh(self):

    if self.dataset.isDirty():
      self.dataset._refresh()
      
    #
    # Compute the SVD of the parent's data
    #
    
    u, s, v = MLab.svd(MLab.cov(self.dataset.getData()))
    sigmas  = s / MLab.sum(s)

    #
    # Precompute the matrix multiplications

    matrix = Numeric.dot( Numeric.dot( Numeric.transpose( v ), \
                                       MLab.diag( 1 / sigmas)), v)
    
    self.setMatrix(matrix)

    self.dirty = 0
