1/*2 * Licensed to the Apache Software Foundation (ASF) under one3 * or more contributor license agreements. See the NOTICE file4 * distributed with this work for additional information5 * regarding copyright ownership. The ASF licenses this file6 * to you under the Apache License, Version 2.0 (the7 * "License"); you may not use this file except in compliance8 * with the License. You may obtain a copy of the License at9 *10 * http://www.apache.org/licenses/LICENSE-2.011 *12 * Unless required by applicable law or agreed to in writing, software13 * 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 and16 * limitations under the License.17 */1819package org.apache.giraph.aggregators.matrix.dense;
2021import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
2223import java.io.DataInput;
24import java.io.DataOutput;
25import java.io.IOException;
2627import org.apache.hadoop.io.Writable;
2829/**30 * The double dense vector holds the values of a particular row. The singleton31 * is used to avoid creating too many objects by compactly represent vectors32 * with a single nonzero coordinate. This way we perform aggregations33 * efficiently.34 */35publicclassDoubleDenseVectorimplements Writable {
36/** The entries of the vector. */37privatefinal DoubleArrayList entries = new DoubleArrayList();
38/** If true, this vector is singleton */39privateboolean isSingleton = false;
40/** The index of the singleton */41privateint singletonIndex;
42/** The value of the singleton */43privatedouble singletonValue;
4445/** Create a new vector with default size. */46publicDoubleDenseVector() { }
4748/**49 * Create a new vector with given size.50 *51 * @param size the size of the vector52 */53publicDoubleDenseVector(int size) {
54 ensureCapacity(size);
55 }
5657/**58 * Set the singleton index and value.59 *60 * @param index the index61 * @param value the value62 */63publicvoid setSingleton(int index, double value) {
64 isSingleton = true;
65this.singletonIndex = index;
66this.singletonValue = value;
67 }
6869/**70 * Get the singleton index.71 *72 * @return the singleton index73 */74publicint getSingletonIndex() {
75return singletonIndex;
76 }
7778/**79 * Get the singleton value.80 *81 * @return the singleton value82 */83publicdouble getSingletonValue() {
84return singletonValue;
85 }
8687/**88 * Get a particular entry of the vector.89 *90 * @param i the entry91 * @return the value of the entry.92 */93publicdouble get(int i) {
94// The default value is 0.095if (i >= entries.size()) {
96return 0.0;
97 }
98return entries.getDouble(i);
99 }
100101/**102 * Set the given value to the entry with the index specified.103 *104 * @param i the entry105 * @param value the value to set to the entry106 */107publicvoid set(int i, double value) {
108 entries.set(i, value);
109 }
110111/**112 * Add the vector specified. This is a vector addition that does an113 * element-by-element addition.114 *115 * @param other the vector to add.116 */117publicvoid add(DoubleDenseVector other) {
118if (isSingleton) {
119thrownew RuntimeException("Cannot add to singleton vector");
120 }
121if (other.isSingleton) {
122 ensureCapacity(other.singletonIndex + 1);
123 entries.set(other.singletonIndex,
124 entries.getDouble(other.singletonIndex) + other.singletonValue);
125 } else {
126 ensureCapacity(other.entries.size());
127for (int i = 0; i < other.entries.size(); ++i) {
128 entries.set(i, entries.getDouble(i) + other.entries.getDouble(i));
129 }
130 }
131 }
132133/**134 * Resize the array to be at least the size specified.135 *136 * @param size the size of the array137 */138privatevoid ensureCapacity(int size) {
139if (entries.size() < size) {
140 entries.size(size);
141 }
142 }
143144 @Override
145publicvoid write(DataOutput out) throws IOException {
146 out.writeBoolean(isSingleton);
147if (isSingleton) {
148 out.writeInt(singletonIndex);
149 out.writeDouble(singletonValue);
150 } else {
151 out.writeInt(entries.size());
152for (int i = 0; i < entries.size(); ++i) {
153 out.writeDouble(entries.getDouble(i));
154 }
155 }
156 }
157158 @Override
159publicvoid readFields(DataInput in) throws IOException {
160 isSingleton = in.readBoolean();
161if (isSingleton) {
162 singletonIndex = in.readInt();
163 singletonValue = in.readDouble();
164 } else {
165int size = in.readInt();
166for (int i = 0; i < size; ++i) {
167 entries.add(in.readDouble());
168 }
169 }
170 }
171 }