it.uniroma2.sag.kelp.data.representation.vector.DenseVector.java Source code

Java tutorial

Introduction

Here is the source code for it.uniroma2.sag.kelp.data.representation.vector.DenseVector.java

Source

/*
 * Copyright 2014 Simone Filice and Giuseppe Castellucci and Danilo Croce and Roberto Basili
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package it.uniroma2.sag.kelp.data.representation.vector;

import java.util.HashMap;
import java.util.Map;

import it.uniroma2.sag.kelp.data.representation.Vector;

import org.ejml.alg.dense.mult.VectorVectorMult;
import org.ejml.data.DenseMatrix64F;
import org.ejml.ops.CommonOps;
import org.ejml.ops.NormOps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonTypeName;

/**
 * Dense Feature Vector. <br>
 * It uses <a href="https://code.google.com/p/efficient-java-matrix-library">
 * EJML </a> to guarantee a very fast computation
 * 
 * @author Simone Filice
 */

@JsonTypeName("DV")
public class DenseVector implements Vector {
    private Logger logger = LoggerFactory.getLogger(DenseVector.class);
    private static final long serialVersionUID = 1150851329091800382L;
    private static final String SEPARATOR = " |,";// a space or a comma can
    // separate feature values

    @JsonIgnore
    private DenseMatrix64F featuresValues;

    /**
     * Empty constructor necessary for making <code>RepresentationFactory</code>
     * support this implementation.
     * 
     * @param featureVector
     *            is an array of feature values
     */
    public DenseVector() {

    }

    @Override
    public void setDataFromText(String representationDescription) {
        // String [] stringFeatures =
        // representationDescription.split(SEPARATOR);
        // float [] features = new float [stringFeatures.length];
        //
        // for(int i=0; i<stringFeatures.length; i++){
        // features[i]= Float.parseFloat(stringFeatures[i]);
        // }
        // this.setFeatureValues(features);
        String[] stringFeatures = representationDescription.split(SEPARATOR);
        this.featuresValues = new DenseMatrix64F(1, stringFeatures.length);

        for (int i = 0; i < stringFeatures.length; i++) {
            Double val = Double.parseDouble(stringFeatures[i]);
            if (val.isNaN()) {
                logger.warn("NaN value in representation: " + representationDescription);
            }
            this.featuresValues.set(0, i, val);
        }
    }

    /**
     * Initializing constructor.
     * 
     * @param featureVector
     *            is an array of feature values
     */
    public DenseVector(double[] featureVector) {
        this.setFeatureValues(featureVector);
    }

    /**
     * Initializing constructor.
     * 
     * @param featureVector
     *            is an array of feature values in the EJML format
     */
    public DenseVector(DenseMatrix64F featureVector) {
        this.featuresValues = featureVector;
    }

    /**
     * Sets the feature values.
     * 
     * @param featureValues
     *            is an array of feature values
     */
    public void setFeatureValues(double[] featureValues) {
        this.featuresValues = new DenseMatrix64F(1, featureValues.length);
        for (int i = 0; i < featureValues.length; i++) {
            this.featuresValues.set(0, i, featureValues[i]);
        }

    }

    /**
     * Sets the feature values.
     * 
     * @param featureVector
     *            is an array of feature values in the EJML format
     */
    public void setFeatureValues(DenseMatrix64F featureVector) {
        this.featuresValues = featureVector;

    }

    /**
     * Returns the feature values in the EJML format
     * 
     * @return the feature values
     */
    @JsonIgnore
    public DenseMatrix64F getFeatureValues() {
        return featuresValues;
    }

    /**
     * Returns the feature value of the <code>featureIndex</code>-th element
     * 
     * @param featureIndex
     *            the index of the feature whose value must be returned
     * @return the value of the feature
     */
    public double getFeatureValue(int featureIndex) {
        return featuresValues.get(0, featureIndex);
    }

    /**
     * Returns the number of featuresValues
     * 
     * @return the number of featuresValues
     */
    @JsonIgnore
    public int getNumberOfFeatures() {
        return this.featuresValues.numCols;
    }

    @Override
    public boolean equals(Object featureVector) {
        if (featureVector == null) {
            return false;
        }
        if (this == featureVector) {
            return true;
        }
        if (featureVector instanceof DenseVector) {
            DenseVector that = (DenseVector) featureVector;
            if (this.getNumberOfFeatures() == that.getNumberOfFeatures()) {
                for (int i = 0; i < this.getNumberOfFeatures(); i++) {
                    if (this.getFeatureValue(i) != that.getFeatureValue(i)) {
                        return false;
                    }
                }
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    @Override
    public String toString() {
        if (this.featuresValues.numCols == 0) {
            return "";
        }
        StringBuilder ret = new StringBuilder();
        ret.append(Double.toString(this.getFeatureValue(0)));
        for (int i = 1; i < this.featuresValues.numCols; i++) {
            ret = ret.append(" " + Double.toString(this.getFeatureValue(i)));
        }

        return ret.toString().trim();
    }

    @Override
    public void normalize() {
        double norm = NormOps.fastNormP2(this.featuresValues);
        if (norm != 0)
            CommonOps.divide(norm, this.featuresValues);
    }

    @Override
    public float innerProduct(Vector vector) {
        if (vector instanceof DenseVector) {
            DenseVector dense = (DenseVector) vector;
            if (featuresValues == null)
                logger.debug("Features Values are null");
            return (float) VectorVectorMult.innerProd(featuresValues, dense.getFeatureValues());
        }

        throw new IllegalArgumentException("Expected a DenseVector to performe the innerProduct");
    }

    @Override
    public void pointWiseProduct(Vector vector) {
        CommonOps.elementMult(this.featuresValues, ((DenseVector) vector).featuresValues);
    }

    @Override
    public void scale(float coeff) {
        CommonOps.scale(coeff, this.featuresValues);

    }

    @Override
    public void add(Vector vector) {
        CommonOps.addEquals(this.featuresValues, ((DenseVector) vector).featuresValues);

    }

    public void diff(DenseVector vector) {
        CommonOps.subEquals(this.featuresValues, ((DenseVector) vector).featuresValues);
    }

    @Override
    public void add(float coeff, Vector vector) {

        CommonOps.addEquals(this.featuresValues, coeff, ((DenseVector) vector).featuresValues);

    }

    @Override
    public void add(float coeff, float vectorCoeff, Vector vector) {
        this.scale(coeff);
        this.add(vectorCoeff, vector);

    }

    @JsonIgnore
    @Override
    public DenseVector getZeroVector() {
        DenseMatrix64F dense = new DenseMatrix64F(this.featuresValues.numRows, this.featuresValues.numCols);
        DenseVector vector = new DenseVector(dense);
        return vector;
    }

    @Override
    public String getTextFromData() {
        return this.toString();
    }

    @Override
    @JsonIgnore
    public float getSquaredNorm() {
        double norm = NormOps.fastNormP2(this.featuresValues);
        return (float) (norm * norm);
    }

    @Override
    public Map<Object, Number> getActiveFeatures() {
        Map<Object, Number> activeFeats = new HashMap<Object, Number>();
        for (int i = 0; i < this.getNumberOfFeatures(); i++) {
            if (featuresValues.get(0, i) != 0) {
                activeFeats.put(i, featuresValues.get(0, i));
            }
        }
        return activeFeats;
    }

    @Override
    public DenseVector copyVector() {
        DenseMatrix64F featureValues = this.getFeatureValues().copy();
        DenseVector copy = new DenseVector(featureValues);
        return copy;
    }

    @Override
    public void setFeatureValue(Object featureIdentifier, float value) {
        if (!(featureIdentifier instanceof Integer)) {
            throw new IllegalArgumentException("The argument featureIdentifier must be an Integer");
        }
        this.featuresValues.set((Integer) featureIdentifier, value);

    }

    @Override
    public float getFeatureValue(Object featureIdentifier) {
        if (!(featureIdentifier instanceof Integer)) {
            throw new IllegalArgumentException("The argument featureIdentifier must be an Integer");
        }
        return (float) this.getFeatureValue(((Integer) featureIdentifier).intValue());
    }
}