source: src/main/java/weka/clusterers/forOPTICSAndDBScan/DataObjects/EuclidianDataObject.java @ 19

Last change on this file since 19 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 9.3 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 *    Copyright (C) 2004
19 *    & Matthias Schubert (schubert@dbs.ifi.lmu.de)
20 *    & Zhanna Melnikova-Albrecht (melnikov@cip.ifi.lmu.de)
21 *    & Rainer Holzmann (holzmann@cip.ifi.lmu.de)
22 */
23
24package weka.clusterers.forOPTICSAndDBScan.DataObjects;
25
26import weka.clusterers.forOPTICSAndDBScan.Databases.Database;
27import weka.core.Attribute;
28import weka.core.Instance;
29import weka.core.RevisionHandler;
30import weka.core.RevisionUtils;
31import weka.core.Utils;
32
33import java.io.Serializable;
34
35/**
36 * <p>
37 * EuclidianDataObject.java <br/>
38 * Authors: Rainer Holzmann, Zhanna Melnikova-Albrecht, Matthias Schubert <br/>
39 * Date: Aug 19, 2004 <br/>
40 * Time: 5:50:22 PM <br/>
41 * $ Revision 1.4 $ <br/>
42 * </p>
43 *
44 * @author Matthias Schubert (schubert@dbs.ifi.lmu.de)
45 * @author Zhanna Melnikova-Albrecht (melnikov@cip.ifi.lmu.de)
46 * @author Rainer Holzmann (holzmann@cip.ifi.lmu.de)
47 * @version $Revision: 5987 $
48 */
49public class EuclidianDataObject
50    implements DataObject, Serializable, RevisionHandler {
51
52    /** for serialization */
53    private static final long serialVersionUID = -4408119914898291075L;
54
55    /**
56     * Holds the original instance
57     */
58    private Instance instance;
59
60    /**
61     * Holds the (unique) key that is associated with this DataObject
62     */
63    private String key;
64
65    /**
66     * Holds the ID of the cluster, to which this DataObject is assigned
67     */
68    private int clusterID;
69
70    /**
71     * Holds the status for this DataObject (true, if it has been processed, else false)
72     */
73    private boolean processed;
74
75    /**
76     * Holds the coreDistance for this DataObject
77     */
78    private double c_dist;
79
80    /**
81     * Holds the reachabilityDistance for this DataObject
82     */
83    private double r_dist;
84
85    /**
86     * Holds the database, that is the keeper of this DataObject
87     */
88    private Database database;
89
90    // *****************************************************************************************************************
91    // constructors
92    // *****************************************************************************************************************
93
94    /**
95     * Constructs a new DataObject. The original instance is kept as instance-variable
96     * @param originalInstance the original instance
97     */
98    public EuclidianDataObject(Instance originalInstance, String key, Database database) {
99        this.database = database;
100        this.key = key;
101        instance = originalInstance;
102        clusterID = DataObject.UNCLASSIFIED;
103        processed = false;
104        c_dist = DataObject.UNDEFINED;
105        r_dist = DataObject.UNDEFINED;
106    }
107
108    // *****************************************************************************************************************
109    // methods
110    // *****************************************************************************************************************
111
112    /**
113     * Compares two DataObjects in respect to their attribute-values
114     * @param dataObject The DataObject, that is compared with this.dataObject
115     * @return Returns true, if the DataObjects correspond in each value, else returns false
116     */
117    public boolean equals(DataObject dataObject) {
118        if (this == dataObject) return true;
119        if (!(dataObject instanceof EuclidianDataObject)) return false;
120
121        final EuclidianDataObject euclidianDataObject = (EuclidianDataObject) dataObject;
122
123        if (getInstance().equalHeaders(euclidianDataObject.getInstance())) {
124            for (int i = 0; i < getInstance().numValues(); i++) {
125                double i_value_Instance_1 = getInstance().valueSparse(i);
126                double i_value_Instance_2 = euclidianDataObject.getInstance().valueSparse(i);
127
128                if (i_value_Instance_1 != i_value_Instance_2) return false;
129            }
130            return true;
131        }
132        return false;
133    }
134
135    /**
136     * Calculates the euclidian-distance between dataObject and this.dataObject
137     * @param dataObject The DataObject, that is used for distance-calculation with this.dataObject
138     * @return double-value The euclidian-distance between dataObject and this.dataObject
139     *                      NaN, if the computation could not be performed
140     */
141    public double distance(DataObject dataObject) {
142        double dist = 0.0;
143
144        if (!(dataObject instanceof EuclidianDataObject)) return Double.NaN;
145
146        if (getInstance().equalHeaders(dataObject.getInstance())) {
147            for (int i = 0; i < getInstance().numValues(); i++) {
148                double cDistance = computeDistance(getInstance().index(i),
149                        getInstance().valueSparse(i),
150                        dataObject.getInstance().valueSparse(i));
151                dist += Math.pow(cDistance, 2.0);
152            }
153            return Math.sqrt(dist);
154        }
155        return Double.NaN;
156    }
157
158    /**
159     * Performs euclidian-distance-calculation between two given values
160     * @param index of the attribute within the DataObject's instance
161     * @param v value_1
162     * @param v1 value_2
163     * @return double norm-distance between value_1 and value_2
164     */
165    private double computeDistance(int index, double v, double v1) {
166        switch (getInstance().attribute(index).type()) {
167            case Attribute.NOMINAL:
168                return (Utils.isMissingValue(v) || Utils.isMissingValue(v1)
169                        || ((int) v != (int) v1)) ? 1 : 0;
170
171            case Attribute.NUMERIC:
172                if (Utils.isMissingValue(v) || Utils.isMissingValue(v1)) {
173                    if (Utils.isMissingValue(v) && Utils.isMissingValue(v1))
174                        return 1;
175                    else {
176                        return (Utils.isMissingValue(v)) ? norm(v1, index)
177                                : norm(v, index);
178                    }
179                } else
180                    return norm(v, index) - norm(v1, index);
181
182            default:
183                return 0;
184        }
185    }
186
187    /**
188     * Normalizes a given value of a numeric attribute.
189     *
190     * @param x the value to be normalized
191     * @param i the attribute's index
192     */
193    private double norm(double x, int i) {
194        if (Double.isNaN(database.getAttributeMinValues()[i])
195                || Utils.eq(database.getAttributeMaxValues()[i], database.getAttributeMinValues()[i])) {
196            return 0;
197        } else {
198            return (x - database.getAttributeMinValues()[i]) /
199                    (database.getAttributeMaxValues()[i] - database.getAttributeMinValues()[i]);
200        }
201    }
202
203    /**
204     * Returns the original instance
205     * @return originalInstance
206     */
207    public Instance getInstance() {
208        return instance;
209    }
210
211    /**
212     * Returns the key for this DataObject
213     * @return key
214     */
215    public String getKey() {
216        return key;
217    }
218
219    /**
220     * Sets the key for this DataObject
221     * @param key The key is represented as string
222     */
223    public void setKey(String key) {
224        this.key = key;
225    }
226
227    /**
228     * Sets the clusterID (cluster), to which this DataObject belongs to
229     * @param clusterID Number of the Cluster
230     */
231    public void setClusterLabel(int clusterID) {
232        this.clusterID = clusterID;
233    }
234
235    /**
236     * Returns the clusterID, to which this DataObject belongs to
237     * @return clusterID
238     */
239    public int getClusterLabel() {
240        return clusterID;
241    }
242
243    /**
244     * Marks this dataObject as processed
245     * @param processed True, if the DataObject has been already processed, false else
246     */
247    public void setProcessed(boolean processed) {
248        this.processed = processed;
249    }
250
251    /**
252     * Gives information about the status of a dataObject
253     * @return True, if this dataObject has been processed, else false
254     */
255    public boolean isProcessed() {
256        return processed;
257    }
258
259    /**
260     * Sets a new coreDistance for this dataObject
261     * @param c_dist coreDistance
262     */
263    public void setCoreDistance(double c_dist) {
264        this.c_dist = c_dist;
265    }
266
267    /**
268     * Returns the coreDistance for this dataObject
269     * @return coreDistance
270     */
271    public double getCoreDistance() {
272        return c_dist;
273    }
274
275    /**
276     * Sets a new reachability-distance for this dataObject
277     */
278    public void setReachabilityDistance(double r_dist) {
279        this.r_dist = r_dist;
280    }
281
282    /**
283     * Returns the reachabilityDistance for this dataObject
284     */
285    public double getReachabilityDistance() {
286        return r_dist;
287    }
288
289    public String toString() {
290        return instance.toString();
291    }
292   
293    /**
294     * Returns the revision string.
295     *
296     * @return          the revision
297     */
298    public String getRevision() {
299      return RevisionUtils.extract("$Revision: 5987 $");
300    }
301}
Note: See TracBrowser for help on using the repository browser.