001    /**
002     * StandardGlobalSimilarityFunction.java
003     * jCOLIBRI2 framework. 
004     * @author Juan A. Recio-García.
005     * GAIA - Group for Artificial Intelligence Applications
006     * http://gaia.fdi.ucm.es
007     * 26/06/2007
008     */
009    package jcolibri.method.retrieve.NNretrieval.similarity;
010    
011    import jcolibri.cbrcore.Attribute;
012    import jcolibri.cbrcore.CBRCase;
013    import jcolibri.cbrcore.CBRQuery;
014    import jcolibri.cbrcore.CaseComponent;
015    import jcolibri.method.retrieve.NNretrieval.NNConfig;
016    
017    /**
018     * Utility class to compute global similarities. 
019     * The implemented compute(...) method computes the similarity of the sub-attributes 
020     * of this compound attribute and then calls the computeSimilarity() abstract method to
021     * obtain the similarity value.<br>
022     * That way, the computeSimilarity() method is a hook to easly compute global similarities.
023     * @author Juan A. Recio-Garcia
024     * @version 1.0
025     *
026     */
027    public abstract class StandardGlobalSimilarityFunction implements GlobalSimilarityFunction
028    {
029    
030        /**
031         * Computes the similarities of the sub-attributes of this CaseComponent and calls the computeSimilarity() method with those values.
032         * @param componentOfCase compound attribute of the case
033         * @param componentOfQuery compound attribute of the query
034         * @param _case case being compared
035         * @param _query query being compared
036         * @param numSimConfig Similarity functions configuration
037         * @return a value between [0..1]
038         * @see jcolibri.method.retrieve.NNretrieval.similarity.GlobalSimilarityFunction#compute(jcolibri.cbrcore.CaseComponent, jcolibri.cbrcore.CaseComponent, jcolibri.cbrcore.CBRCase, jcolibri.cbrcore.CBRQuery, jcolibri.method.retrieve.NNretrieval.NNConfig)
039         */
040        public double compute(CaseComponent componentOfCase, CaseComponent componentOfQuery, CBRCase _case,
041                CBRQuery _query, NNConfig numSimConfig)
042        {
043            GlobalSimilarityFunction gsf = null;
044            LocalSimilarityFunction lsf = null;
045            
046            
047            Attribute[] attributes = jcolibri.util.AttributeUtils.getAttributes(componentOfCase.getClass());
048            
049            double[] values = new double[attributes.length];
050            double[] weights = new double[attributes.length];
051            
052            int ivalue = 0;
053    
054            for(int i=0; i<attributes.length; i++)
055            {
056                    Attribute at1 = attributes[i];
057                    Attribute at2 = new Attribute(at1.getName(), componentOfQuery.getClass());
058                    
059                    try{
060                    if((gsf = numSimConfig.getGlobalSimilFunction(at1)) != null)
061                    {
062                            values[ivalue] = gsf.compute((CaseComponent)at1.getValue(componentOfCase), (CaseComponent)at2.getValue(componentOfQuery), _case, _query, numSimConfig);
063                            weights[ivalue++] = numSimConfig.getWeight(at1); 
064                    }
065                    else if((lsf = numSimConfig.getLocalSimilFunction(at1))  != null)
066                    {
067                            if(lsf instanceof InContextLocalSimilarityFunction)
068                            {
069                                InContextLocalSimilarityFunction iclsf = (InContextLocalSimilarityFunction)lsf;
070                                iclsf.setContext(componentOfCase, componentOfQuery, _case, _query, at1.getName());
071                            }
072                            values[ivalue] = lsf.compute(at1.getValue(componentOfCase), at2.getValue(componentOfQuery));
073                            weights[ivalue++] = numSimConfig.getWeight(at1);
074                    }
075                    }catch(Exception e)
076                    {
077                            System.err.println(e.getMessage());
078                            e.printStackTrace();
079                    }
080            }
081            
082            return computeSimilarity(values, weights, ivalue);
083    
084        }
085        
086        /**
087         * Hook method that must be implemented by subclasses returned the global similarity value.
088         * @param values of the similarity of the sub-attributes
089         * @param weigths of the sub-attributes
090         * @param numberOfvalues (or sub-attributes) that were obtained (some subattributes may not compute for the similarity).
091         * @return a value between [0..1]
092         */
093        public abstract double computeSimilarity(double[] values, double[] weigths, int numberOfvalues);
094    }