Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
DoubleDenseVector |
|
| 2.0;2 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, software | |
13 | * distributed under the License is distributed on an "AS IS" BASIS, | |
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
15 | * See the License for the specific language governing permissions and | |
16 | * limitations under the License. | |
17 | */ | |
18 | ||
19 | package org.apache.giraph.aggregators.matrix.dense; | |
20 | ||
21 | import it.unimi.dsi.fastutil.doubles.DoubleArrayList; | |
22 | ||
23 | import java.io.DataInput; | |
24 | import java.io.DataOutput; | |
25 | import java.io.IOException; | |
26 | ||
27 | import org.apache.hadoop.io.Writable; | |
28 | ||
29 | /** | |
30 | * The double dense vector holds the values of a particular row. The singleton | |
31 | * is used to avoid creating too many objects by compactly represent vectors | |
32 | * with a single nonzero coordinate. This way we perform aggregations | |
33 | * efficiently. | |
34 | */ | |
35 | public class DoubleDenseVector implements Writable { | |
36 | /** The entries of the vector. */ | |
37 | 0 | private final DoubleArrayList entries = new DoubleArrayList(); |
38 | /** If true, this vector is singleton */ | |
39 | 0 | private boolean isSingleton = false; |
40 | /** The index of the singleton */ | |
41 | private int singletonIndex; | |
42 | /** The value of the singleton */ | |
43 | private double singletonValue; | |
44 | ||
45 | /** Create a new vector with default size. */ | |
46 | 0 | public DoubleDenseVector() { } |
47 | ||
48 | /** | |
49 | * Create a new vector with given size. | |
50 | * | |
51 | * @param size the size of the vector | |
52 | */ | |
53 | 0 | public DoubleDenseVector(int size) { |
54 | 0 | ensureCapacity(size); |
55 | 0 | } |
56 | ||
57 | /** | |
58 | * Set the singleton index and value. | |
59 | * | |
60 | * @param index the index | |
61 | * @param value the value | |
62 | */ | |
63 | public void setSingleton(int index, double value) { | |
64 | 0 | isSingleton = true; |
65 | 0 | this.singletonIndex = index; |
66 | 0 | this.singletonValue = value; |
67 | 0 | } |
68 | ||
69 | /** | |
70 | * Get the singleton index. | |
71 | * | |
72 | * @return the singleton index | |
73 | */ | |
74 | public int getSingletonIndex() { | |
75 | 0 | return singletonIndex; |
76 | } | |
77 | ||
78 | /** | |
79 | * Get the singleton value. | |
80 | * | |
81 | * @return the singleton value | |
82 | */ | |
83 | public double getSingletonValue() { | |
84 | 0 | return singletonValue; |
85 | } | |
86 | ||
87 | /** | |
88 | * Get a particular entry of the vector. | |
89 | * | |
90 | * @param i the entry | |
91 | * @return the value of the entry. | |
92 | */ | |
93 | public double get(int i) { | |
94 | // The default value is 0.0 | |
95 | 0 | if (i >= entries.size()) { |
96 | 0 | return 0.0; |
97 | } | |
98 | 0 | return entries.getDouble(i); |
99 | } | |
100 | ||
101 | /** | |
102 | * Set the given value to the entry with the index specified. | |
103 | * | |
104 | * @param i the entry | |
105 | * @param value the value to set to the entry | |
106 | */ | |
107 | public void set(int i, double value) { | |
108 | 0 | entries.set(i, value); |
109 | 0 | } |
110 | ||
111 | /** | |
112 | * Add the vector specified. This is a vector addition that does an | |
113 | * element-by-element addition. | |
114 | * | |
115 | * @param other the vector to add. | |
116 | */ | |
117 | public void add(DoubleDenseVector other) { | |
118 | 0 | if (isSingleton) { |
119 | 0 | throw new RuntimeException("Cannot add to singleton vector"); |
120 | } | |
121 | 0 | if (other.isSingleton) { |
122 | 0 | ensureCapacity(other.singletonIndex + 1); |
123 | 0 | entries.set(other.singletonIndex, |
124 | 0 | entries.getDouble(other.singletonIndex) + other.singletonValue); |
125 | } else { | |
126 | 0 | ensureCapacity(other.entries.size()); |
127 | 0 | for (int i = 0; i < other.entries.size(); ++i) { |
128 | 0 | entries.set(i, entries.getDouble(i) + other.entries.getDouble(i)); |
129 | } | |
130 | } | |
131 | 0 | } |
132 | ||
133 | /** | |
134 | * Resize the array to be at least the size specified. | |
135 | * | |
136 | * @param size the size of the array | |
137 | */ | |
138 | private void ensureCapacity(int size) { | |
139 | 0 | if (entries.size() < size) { |
140 | 0 | entries.size(size); |
141 | } | |
142 | 0 | } |
143 | ||
144 | @Override | |
145 | public void write(DataOutput out) throws IOException { | |
146 | 0 | out.writeBoolean(isSingleton); |
147 | 0 | if (isSingleton) { |
148 | 0 | out.writeInt(singletonIndex); |
149 | 0 | out.writeDouble(singletonValue); |
150 | } else { | |
151 | 0 | out.writeInt(entries.size()); |
152 | 0 | for (int i = 0; i < entries.size(); ++i) { |
153 | 0 | out.writeDouble(entries.getDouble(i)); |
154 | } | |
155 | } | |
156 | 0 | } |
157 | ||
158 | @Override | |
159 | public void readFields(DataInput in) throws IOException { | |
160 | 0 | isSingleton = in.readBoolean(); |
161 | 0 | if (isSingleton) { |
162 | 0 | singletonIndex = in.readInt(); |
163 | 0 | singletonValue = in.readDouble(); |
164 | } else { | |
165 | 0 | int size = in.readInt(); |
166 | 0 | for (int i = 0; i < size; ++i) { |
167 | 0 | entries.add(in.readDouble()); |
168 | } | |
169 | } | |
170 | 0 | } |
171 | } |