All Downloads are FREE. Search and download functionalities are using the official Maven repository.

no.uib.cipr.matrix.AbstractVector Maven / Gradle / Ivy

/*
 * Copyright (C) 2003-2006 Bjørn-Ove Heimsund
 * 
 * This file is part of MTJ.
 * 
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This library 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 Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

package no.uib.cipr.matrix;

import java.io.Serializable;
import java.util.Formatter;
import java.util.Iterator;

/**
 * Partial implementation of Vector. The following methods throw
 * UnsupportedOperationException, and should be overridden by a
 * subclass:
 * 
    *
  • get(int)
  • *
  • set(int,double)
  • *
  • copy
  • *
*

* For the rest of the methods, simple default implementations using a vector * iterator has been provided. There are some kernel operations which the * simpler operations forward to, and they are: *

    *
  • add(double,Vector) and set(double,Vector).
  • *
  • scale(double).
  • *
  • dot(Vector) and all the norms.
  • *
*

* Finally, a default iterator is provided by this class, which works by calling * the get function. A tailored replacement should be used by * subclasses. */ public abstract class AbstractVector implements Vector, Serializable { /** * Size of the vector */ protected int size; /** * Constructor for AbstractVector. * * @param size * Size of the vector */ protected AbstractVector(int size) { if (size < 0) throw new IllegalArgumentException("Vector size cannot be negative"); this.size = size; } /** * Constructor for AbstractVector, same size as x * * @param x * Vector to get the size from */ protected AbstractVector(Vector x) { this.size = x.size(); } public int size() { return size; } public void set(int index, double value) { throw new UnsupportedOperationException(); } public void add(int index, double value) { set(index, value + get(index)); } public double get(int index) { throw new UnsupportedOperationException(); } public Vector copy() { throw new UnsupportedOperationException(); } /** * Checks the index */ protected void check(int index) { if (index < 0) throw new IndexOutOfBoundsException("index is negative (" + index + ")"); if (index >= size) throw new IndexOutOfBoundsException("index >= size (" + index + " >= " + size + ")"); } public Vector zero() { for (VectorEntry e : this) e.set(0); return this; } public Vector scale(double alpha) { if (alpha == 0) return zero(); else if (alpha == 1) return this; for (VectorEntry e : this) e.set(alpha * e.get()); return this; } public Vector set(Vector y) { return set(1, y); } public Vector set(double alpha, Vector y) { checkSize(y); if (alpha == 0) return zero(); zero(); for (VectorEntry e : y) set(e.index(), alpha * e.get()); return this; } public Vector add(Vector y) { return add(1, y); } public Vector add(double alpha, Vector y) { checkSize(y); if (alpha == 0) return this; for (VectorEntry e : y) add(e.index(), alpha * e.get()); return this; } public double dot(Vector y) { checkSize(y); double ret = 0; for (VectorEntry e : this) ret += e.get() * y.get(e.index()); return ret; } /** * Checks for conformant sizes */ protected void checkSize(Vector y) { if (size != y.size()) throw new IndexOutOfBoundsException("x.size != y.size (" + size + " != " + y.size() + ")"); } public double norm(Norm type) { if (type == Norm.One) return norm1(); else if (type == Norm.Two) return norm2(); else if (type == Norm.TwoRobust) return norm2_robust(); else // Infinity return normInf(); } protected double norm1() { double sum = 0; for (VectorEntry e : this) sum += Math.abs(e.get()); return sum; } protected double norm2() { double norm = 0; for (VectorEntry e : this) norm += e.get() * e.get(); return Math.sqrt(norm); } protected double norm2_robust() { double scale = 0, ssq = 1; for (VectorEntry e : this) { double xval = e.get(); if (xval != 0) { double absxi = Math.abs(xval); if (scale < absxi) { ssq = 1 + ssq * Math.pow(scale / absxi, 2); scale = absxi; } else ssq = ssq + Math.pow(absxi / scale, 2); } } return scale * Math.sqrt(ssq); } protected double normInf() { double max = 0; for (VectorEntry e : this) max = Math.max(Math.abs(e.get()), max); return max; } public Iterator iterator() { return new RefVectorIterator(); } @Override public String toString() { // Output into coordinate format. Indices start from 1 instead of 0 Formatter out = new Formatter(); out.format("%10d %19d\n", size, Matrices.cardinality(this)); int i = 0; for (VectorEntry e : this) { if (e.get() != 0) out.format("%10d % .12e\n", e.index() + 1, e.get()); if (++i == 100) { out.format("...\n"); break; } } return out.toString(); } /** * Iterator over a general vector */ private class RefVectorIterator implements Iterator { private int index; private final RefVectorEntry entry = new RefVectorEntry(); public boolean hasNext() { return index < size; } public VectorEntry next() { entry.update(index); index++; return entry; } public void remove() { entry.set(0); } } /** * Vector entry backed by the vector. May be reused for higher performance */ private class RefVectorEntry implements VectorEntry { private int index; /** * Updates the entry */ public void update(int index) { this.index = index; } public int index() { return index; } public double get() { return AbstractVector.this.get(index); } public void set(double value) { AbstractVector.this.set(index, value); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy