~ubuntu-branches/ubuntu/precise/weka/precise

« back to all changes in this revision

Viewing changes to weka/clusterers/forOPTICSAndDBScan/DataObjects/ManhattanDataObject.java

  • Committer: Bazaar Package Importer
  • Author(s): Soeren Sonnenburg
  • Date: 2008-02-24 09:18:45 UTC
  • Revision ID: james.westby@ubuntu.com-20080224091845-1l8zy6fm6xipbzsr
Tags: upstream-3.5.7+tut1
ImportĀ upstreamĀ versionĀ 3.5.7+tut1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
24
package weka.clusterers.forOPTICSAndDBScan.DataObjects;
 
25
 
 
26
import weka.clusterers.forOPTICSAndDBScan.Databases.Database;
 
27
import weka.core.Attribute;
 
28
import weka.core.Instance;
 
29
import weka.core.Utils;
 
30
 
 
31
import java.io.Serializable;
 
32
 
 
33
/**
 
34
 * <p>
 
35
 * ManhattanDataObject.java <br/>
 
36
 * Authors: Rainer Holzmann, Zhanna Melnikova-Albrecht, Matthias Schubert <br/>
 
37
 * Date: Aug 19, 2004 <br/>
 
38
 * Time: 5:50:22 PM <br/>
 
39
 * $ Revision 1.4 $ <br/>
 
40
 * </p>
 
41
 *
 
42
 * @author Matthias Schubert (schubert@dbs.ifi.lmu.de)
 
43
 * @author Zhanna Melnikova-Albrecht (melnikov@cip.ifi.lmu.de)
 
44
 * @author Rainer Holzmann (holzmann@cip.ifi.lmu.de)
 
45
 * @version $Revision: 1.3 $
 
46
 */
 
47
public class ManhattanDataObject
 
48
    implements DataObject, Serializable {
 
49
 
 
50
    /** for serialization */
 
51
    private static final long serialVersionUID = -3417720553766544582L;
 
52
 
 
53
    /**
 
54
     * Holds the original instance
 
55
     */
 
56
    private Instance instance;
 
57
 
 
58
    /**
 
59
     * Holds the (unique) key that is associated with this DataObject
 
60
     */
 
61
    private String key;
 
62
 
 
63
    /**
 
64
     * Holds the ID of the cluster, to which this DataObject is assigned
 
65
     */
 
66
    private int clusterID;
 
67
 
 
68
    /**
 
69
     * Holds the status for this DataObject (true, if it has been processed, else false)
 
70
     */
 
71
    private boolean processed;
 
72
 
 
73
    /**
 
74
     * Holds the coreDistance for this DataObject
 
75
     */
 
76
    private double c_dist;
 
77
 
 
78
    /**
 
79
     * Holds the reachabilityDistance for this DataObject
 
80
     */
 
81
    private double r_dist;
 
82
 
 
83
    /**
 
84
     * Holds the database, that is the keeper of this DataObject
 
85
     */
 
86
    private Database database;
 
87
 
 
88
    // *****************************************************************************************************************
 
89
    // constructors
 
90
    // *****************************************************************************************************************
 
91
 
 
92
    /**
 
93
     * Constructs a new DataObject. The original instance is kept as instance-variable
 
94
     * @param originalInstance the original instance
 
95
     */
 
96
    public ManhattanDataObject(Instance originalInstance, String key, Database database) {
 
97
        this.database = database;
 
98
        this.key = key;
 
99
        instance = originalInstance;
 
100
        clusterID = DataObject.UNCLASSIFIED;
 
101
        processed = false;
 
102
        c_dist = DataObject.UNDEFINED;
 
103
        r_dist = DataObject.UNDEFINED;
 
104
    }
 
105
 
 
106
    // *****************************************************************************************************************
 
107
    // methods
 
108
    // *****************************************************************************************************************
 
109
 
 
110
    /**
 
111
     * Compares two DataObjects in respect to their attribute-values
 
112
     * @param dataObject The DataObject, that is compared with this.dataObject
 
113
     * @return Returns true, if the DataObjects correspond in each value, else returns false
 
114
     */
 
115
    public boolean equals(DataObject dataObject) {
 
116
        if (this == dataObject) return true;
 
117
        if (!(dataObject instanceof ManhattanDataObject)) return false;
 
118
 
 
119
        final ManhattanDataObject manhattanDataObject = (ManhattanDataObject) dataObject;
 
120
 
 
121
        if (getInstance().equalHeaders(manhattanDataObject.getInstance())) {
 
122
            for (int i = 0; i < getInstance().numAttributes(); i++) {
 
123
                double i_value_Instance_1 = getInstance().valueSparse(i);
 
124
                double i_value_Instance_2 = manhattanDataObject.getInstance().valueSparse(i);
 
125
 
 
126
                if (i_value_Instance_1 != i_value_Instance_2) return false;
 
127
            }
 
128
            return true;
 
129
        }
 
130
        return false;
 
131
    }
 
132
 
 
133
    /**
 
134
     * Calculates the manhattan-distance between dataObject and this.dataObject
 
135
     * @param dataObject The DataObject, that is used for distance-calculation with this.dataObject
 
136
     * @return double-value The manhattan-distance between dataObject and this.dataObject
 
137
     *                      NaN, if the computation could not be performed
 
138
     */
 
139
    public double distance(DataObject dataObject) {
 
140
        double dist = 0.0;
 
141
 
 
142
        if (!(dataObject instanceof ManhattanDataObject)) return Double.NaN;
 
143
 
 
144
        if (getInstance().equalHeaders(dataObject.getInstance())) {
 
145
            for (int i = 0; i < getInstance().numAttributes(); i++) {
 
146
                double cDistance = computeDistance(getInstance().index(i),
 
147
                        getInstance().valueSparse(i),
 
148
                        dataObject.getInstance().valueSparse(i));
 
149
                dist += Math.abs(cDistance);
 
150
            }
 
151
            return dist;
 
152
        }
 
153
        return Double.NaN;
 
154
    }
 
155
 
 
156
    /**
 
157
     * Performs manhattan-distance-calculation between two given values
 
158
     * @param index of the attribute within the DataObject's instance
 
159
     * @param v value_1
 
160
     * @param v1 value_2
 
161
     * @return double norm-distance between value_1 and value_2
 
162
     */
 
163
    private double computeDistance(int index, double v, double v1) {
 
164
        switch (getInstance().attribute(index).type()) {
 
165
            case Attribute.NOMINAL:
 
166
                return (Instance.isMissingValue(v) || Instance.isMissingValue(v1)
 
167
                        || ((int) v != (int) v1)) ? 1 : 0;
 
168
 
 
169
            case Attribute.NUMERIC:
 
170
                if (Instance.isMissingValue(v) || Instance.isMissingValue(v1)) {
 
171
                    if (Instance.isMissingValue(v) && Instance.isMissingValue(v1))
 
172
                        return 1;
 
173
                    else {
 
174
                        return (Instance.isMissingValue(v)) ? norm(v1, index)
 
175
                                : norm(v, index);
 
176
                    }
 
177
                } else
 
178
                    return norm(v, index) - norm(v1, index);
 
179
 
 
180
            default:
 
181
                return 0;
 
182
        }
 
183
    }
 
184
 
 
185
    /**
 
186
     * Normalizes a given value of a numeric attribute.
 
187
     *
 
188
     * @param x the value to be normalized
 
189
     * @param i the attribute's index
 
190
     */
 
191
    private double norm(double x, int i) {
 
192
        if (Double.isNaN(database.getAttributeMinValues()[i])
 
193
                || Utils.eq(database.getAttributeMaxValues()[i], database.getAttributeMinValues()[i])) {
 
194
            return 0;
 
195
        } else {
 
196
            return (x - database.getAttributeMinValues()[i]) /
 
197
                    (database.getAttributeMaxValues()[i] - database.getAttributeMinValues()[i]);
 
198
        }
 
199
    }
 
200
 
 
201
    /**
 
202
     * Returns the original instance
 
203
     * @return originalInstance
 
204
     */
 
205
    public Instance getInstance() {
 
206
        return instance;
 
207
    }
 
208
 
 
209
    /**
 
210
     * Returns the key for this DataObject
 
211
     * @return key
 
212
     */
 
213
    public String getKey() {
 
214
        return key;
 
215
    }
 
216
 
 
217
    /**
 
218
     * Sets the key for this DataObject
 
219
     * @param key The key is represented as string
 
220
     */
 
221
    public void setKey(String key) {
 
222
        this.key = key;
 
223
    }
 
224
 
 
225
    /**
 
226
     * Sets the clusterID (cluster), to which this DataObject belongs to
 
227
     * @param clusterID Number of the Cluster
 
228
     */
 
229
    public void setClusterLabel(int clusterID) {
 
230
        this.clusterID = clusterID;
 
231
    }
 
232
 
 
233
    /**
 
234
     * Returns the clusterID, to which this DataObject belongs to
 
235
     * @return clusterID
 
236
     */
 
237
    public int getClusterLabel() {
 
238
        return clusterID;
 
239
    }
 
240
 
 
241
    /**
 
242
     * Marks this dataObject as processed
 
243
     * @param processed True, if the DataObject has been already processed, false else
 
244
     */
 
245
    public void setProcessed(boolean processed) {
 
246
        this.processed = processed;
 
247
    }
 
248
 
 
249
    /**
 
250
     * Gives information about the status of a dataObject
 
251
     * @return True, if this dataObject has been processed, else false
 
252
     */
 
253
    public boolean isProcessed() {
 
254
        return processed;
 
255
    }
 
256
 
 
257
    /**
 
258
     * Sets a new coreDistance for this dataObject
 
259
     * @param c_dist coreDistance
 
260
     */
 
261
    public void setCoreDistance(double c_dist) {
 
262
        this.c_dist = c_dist;
 
263
    }
 
264
 
 
265
    /**
 
266
     * Returns the coreDistance for this dataObject
 
267
     * @return coreDistance
 
268
     */
 
269
    public double getCoreDistance() {
 
270
        return c_dist;
 
271
    }
 
272
 
 
273
    /**
 
274
     * Sets a new reachability-distance for this dataObject
 
275
     */
 
276
    public void setReachabilityDistance(double r_dist) {
 
277
        this.r_dist = r_dist;
 
278
    }
 
279
 
 
280
    /**
 
281
     * Returns the reachabilityDistance for this dataObject
 
282
     */
 
283
    public double getReachabilityDistance() {
 
284
        return r_dist;
 
285
    }
 
286
 
 
287
    public String toString() {
 
288
        return instance.toString();
 
289
    }
 
290
 
 
291
    // *****************************************************************************************************************
 
292
    // inner classes
 
293
    // *****************************************************************************************************************
 
294
 
 
295
}