Package no.uib.cipr.matrix

Source Code of no.uib.cipr.matrix.AbstractVector$RefVectorEntry

/*
* 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 <code>Vector</code>. The following methods throw
* <code>UnsupportedOperationException</code>, and should be overridden by a
* subclass:
* <ul>
* <li><code>get(int)</code></li>
* <li><code>set(int,double)</code></li>
* <li><code>copy</code></li>
* </ul>
* <p>
* 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:
* <ul>
* <li> <code>add(double,Vector)</code> and <code>set(double,Vector)</code>.
* </li>
* <li> <code>scale(double)</code>.</li>
* <li><code>dot(Vector)</code> and all the norms. </li>
* </ul>
* <p>
* Finally, a default iterator is provided by this class, which works by calling
* the <code>get</code> function. A tailored replacement should be used by
* subclasses.
* </ul>
*/
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<VectorEntry> 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));

        for (VectorEntry e : this)
            if (e.get() != 0)
                out.format("%10d % .12e\n", e.index() + 1, e.get());

        return out.toString();
    }

    /**
     * Iterator over a general vector
     */
    private class RefVectorIterator implements Iterator<VectorEntry> {

        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);
        }

    }

}
TOP

Related Classes of no.uib.cipr.matrix.AbstractVector$RefVectorEntry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.