net.librec.math.structure.DenseVector Maven / Gradle / Ivy
// Copyright (C) 2014 Guibing Guo
//
// This file is part of LibRec.
//
// LibRec is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// LibRec is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with LibRec. If not, see .
//
package net.librec.math.structure;
import net.librec.math.algorithm.Randoms;
import net.librec.math.algorithm.Stats;
import net.librec.util.StringUtil;
import java.io.Serializable;
/**
* Data Structure: dense vector
*
* @author guoguibing
*/
public class DenseVector implements Serializable {
private static final long serialVersionUID = -2930574547913792430L;
protected int size;
protected double[] data;
/**
* Construct a dense vector with a specific size
*
* @param size the size of vector
*/
public DenseVector(int size) {
this.size = size;
data = new double[size];
}
/**
* Construct a dense vector by deeply copying data from a given array
*
* @param array a given array
*/
public DenseVector(double[] array) {
this(array, true);
}
/**
* Construct a dense vector by copying data from a given array
*
* @param array a given data array
* @param deep whether to deep copy array data
*/
public DenseVector(double[] array, boolean deep) {
this.size = array.length;
if (deep) {
data = new double[array.length];
for (int i = 0; i < size; i++)
data[i] = array[i];
} else {
data = array;
}
}
/**
* Construct a dense vector by deeply copying data from a given vector
*
* @param vec a given vector
*/
public DenseVector(DenseVector vec) {
this(vec.data);
}
/**
* Make a deep copy of current vector
*/
public DenseVector clone() {
return new DenseVector(this);
}
/**
* Initialize a dense vector with Gaussian values
*
* @param mean mean of the gaussian
* @param sigma sigma of the gaussian
*/
public void init(double mean, double sigma) {
for (int i = 0; i < size; i++)
data[i] = Randoms.gaussian(mean, sigma);
}
/**
* Initialize a dense vector with uniform values in (0, 1)
*/
public void init() {
for (int i = 0; i < size; i++)
data[i] = Randoms.uniform();
}
/**
* Initialize a dense vector with uniform values in (0, range)
*
* @param range max of the range
*/
public void init(double range) {
for (int i = 0; i < size; i++)
data[i] = Randoms.uniform(0, range);
}
/**
* Get a value at entry [index]
*
* @param idx index of the data
* @return value at entry [index]
*/
public double get(int idx) {
return data[idx];
}
/**
* @return vector's data
*/
public double[] getData() {
return data;
}
/**
* @return mean of current vector
*/
public double mean() {
return Stats.mean(data);
}
/**
* @return summation of entries
*/
public double sum() {
return Stats.sum(data);
}
/**
* Set a value to entry [index]
*
* @param idx index to set
* @param val value to set
*/
public void set(int idx, double val) {
data[idx] = val;
}
/**
* Set a value to all entries
*
* @param val value to set
*/
public void setAll(double val) {
for (int i = 0; i < size; i++)
data[i] = val;
}
/**
* Add a value to entry [index]
*
* @param idx index to add
* @param val value to add
*/
public void add(int idx, double val) {
data[idx] += val;
}
/**
* Substract a value from entry [index]
*
* @param idx index to minus
* @param val value to minus
*/
public void minus(int idx, double val) {
data[idx] -= val;
}
/**
* Return a new dense vector by adding a value to all entries of current vector {@code a[i] = b[i] + c}
*
* @param val value to add
* @return a new dense vector by adding a value to all entries of current vector {@code a[i] = b[i] + c}
*/
public DenseVector add(double val) {
DenseVector result = new DenseVector(size);
for (int i = 0; i < size; i++)
result.data[i] = this.data[i] + val;
return result;
}
/**
* Return this dense vector by adding a value to all entries of current vector {@code b[i] = b[i] + c}
*
* @param val value to add
* @return this dense vector by adding a value to all entries of current vector {@code b[i] = b[i] + c}
*/
public DenseVector addEqual(double val) {
for (int i = 0; i < size; i++)
data[i] += val;
return this;
}
/**
* Do vector operation: {@code a + b}
*
* @param vec vector to add
* @return a new dense vector with results of {@code c = a + b}
*/
public DenseVector add(DenseVector vec) {
assert size == vec.size;
DenseVector result = new DenseVector(size);
for (int i = 0; i < result.size; i++)
result.data[i] = this.data[i] + vec.data[i];
return result;
}
/**
* Do vector operation: {@code a + b}
*
* @param vec vector to add
* @return this dense vector with results of {@code a = a + b}
*/
public DenseVector addEqual(DenseVector vec) {
assert size == vec.size;
for (int i = 0; i < size; i++)
data[i] += vec.data[i];
return this;
}
/**
* Return a new dense vector by substructing a value from all entries of current vector {@code a[i] = b[i] - c}
*
* @param val value to minus
* @return a new dense vector by substructing a value from all entries of current vector {@code a[i] = b[i] - c}
*/
public DenseVector minus(double val) {
DenseVector result = new DenseVector(size);
for (int i = 0; i < size; i++)
result.data[i] = this.data[i] - val;
return result;
}
/**
* Return this dense vector by substructing a value from all entries of current vector {@code b[i] = b[i] - c}
*
* @param val value to
* @return this dense vector by substructing a value from all entries of current vector {@code b[i] = b[i] - c}
*/
public DenseVector minusEqual(double val) {
for (int i = 0; i < size; i++)
data[i] -= val;
return this;
}
/**
* Do vector operation: {@code a - b}
*
* @param vec a given vector
* @return a new dense vector with results of {@code c = a - b}
*/
public DenseVector minus(DenseVector vec) {
assert size == vec.size;
DenseVector result = new DenseVector(size);
for (int i = 0; i < vec.size; i++)
result.data[i] = this.data[i] - vec.data[i];
return result;
}
/**
* Do vector operation: {@code a - b}
*
* @param vec a given vector
* @return this dense vector with results of {@code a = a - b}
*/
public DenseVector minusEqual(DenseVector vec) {
assert size == vec.size;
for (int i = 0; i < vec.size; i++)
data[i] -= vec.data[i];
return this;
}
/**
* Return a new dense vector by scaling a value to all entries of current vector {@code a = b.scale(c)}
*
* @param val a given value for scaling
* @return a new dense vector by scaling a value to all entries of current vector {@code a = b.scale(c)}
*/
public DenseVector scale(double val) {
DenseVector result = new DenseVector(size);
for (int i = 0; i < size; i++)
result.data[i] = this.data[i] * val;
return result;
}
/**
* Return this dense vector by scaling a value to all entries of current vector {@code b = b.scale(c)}.
*
* @param val a given value for scaling
* @return this dense vector by scaling a value to all entries of current vector {@code b = b.scale(c)}
*/
public DenseVector scaleEqual(double val) {
for (int i = 0; i < size; i++)
data[i] *= val;
return this;
}
/**
* Do vector operation: {@code a^t * b}
*
* @param vec a given vector
* @return the inner product of two vectors
*/
public double inner(DenseVector vec) {
assert size == vec.size;
double result = 0;
for (int i = 0; i < vec.size; i++)
result += get(i) * vec.get(i);
return result;
}
/**
* Do vector operation: {@code a^t * b}
*
* @param vec a given vector
* @return the inner product of two vectors
*/
public double inner(SparseVector vec) {
double result = 0;
for (int j : vec.getIndex())
result += vec.get(j) * get(j);
return result;
}
/**
* Do vector operation: {@code a * b^t}
*
* @param vec a given vector
* @return the outer product of two vectors
*/
public DenseMatrix outer(DenseVector vec) {
DenseMatrix mat = new DenseMatrix(this.size, vec.size);
for (int i = 0; i < mat.numRows; i++)
for (int j = 0; j < mat.numColumns; j++)
mat.set(i, j, get(i) * vec.get(j));
return mat;
}
/**
* Return the Kronecker product of two vectors
*
* @param M a dense matrix
* @param N another dense matrix
* @return the Kronecker product of two vectors
*/
public static DenseVector kroneckerProduct(DenseVector M, DenseVector N) {
DenseVector res = new DenseVector(M.size * N.size);
int i = 0;
for (int m = 0; m < M.size; m++) {
double mVal = M.get(m);
for (int n = 0; n < N.size; n++) {
res.set(i++, mVal * N.get(n));
}
}
return res;
}
@Override
public String toString() {
return StringUtil.toString(data);
}
/**
* @param data the data to set
*/
public void setData(double[] data) {
this.data = data;
}
}