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

linear.FieldVector Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2016 Jacob Rachiele
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software without restriction
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to
 * do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Contributors:
 *
 * Jacob Rachiele
 */
package linear;

import com.google.common.collect.ImmutableList;
import math.FieldElement;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * An immutable and thread-safe implementation of a vector backed by a list of {@link FieldElement}s.
 *
 * @author Jacob Rachiele
 */
final class FieldVector> {

    private final List elements;

    /**
     * Create a new vector using the provided list of elements.
     *
     * @param elements a list of elements constituting the elements of the new vector.
     */
    FieldVector(List elements) {
        this.elements = ImmutableList.copyOf(elements);
    }

    /**
     * Create a new vector using the provided elements.
     *
     * @param elements the elements of the new vector.
     */
    @SafeVarargs
    FieldVector(T... elements) {
        this.elements = ImmutableList.copyOf(Arrays.asList(elements.clone()));
    }

    /**
     * The elements of the vector as a list of field elements.
     *
     * @return the elements of the vector as a list of field element.
     */
    List elements() {
        return this.elements;
    }

    /**
     * Return the element at index i, where indexing begins at 0.
     *
     * @param i the index of the element.
     * @return the element at index i, where indexing begins at 0.
     */
    T at(final int i) {
        return this.elements.get(i);
    }

    /**
     * The number of elements in this vector.
     *
     * @return the number of elements in this vector.
     */
    int size() {
        return this.elements.size();
    }

    /**
     * Add this vector to the given vector and return the result in a new vector.
     *
     * @param other the vector to add to this vector.
     * @return this vector added to the given vector.
     */
    FieldVector plus(final FieldVector other) {
        final List summed = new ArrayList<>(this.size());
        for (int i = 0; i < this.size(); i++) {
            summed.add(this.elements.get(i).plus(other.elements.get(i)));
        }
        return new FieldVector<>(summed);
    }

    /**
     * Subtract the given vector from this vector and return the result in a new vector.
     *
     * @param other the vector to subtract from this vector.
     * @return this vector subtracted by the given vector.
     */
    FieldVector minus(final FieldVector other) {
        final List differenced = new ArrayList<>(this.size());
        for (int i = 0; i < this.size(); i++) {
            differenced.add(this.elements.get(i).minus(other.elements.get(i)));
        }
        return new FieldVector<>(differenced);
    }

    /**
     * Scale this vector by the given scalar and return the result in a new vector.
     *
     * @param alpha the scalar to scale this vector by.
     * @return this vector scaled by the given scalar.
     */
    FieldVector scaledBy(final T alpha) {
        final List scaled = new ArrayList<>(this.size());
        for (int i = 0; i < this.size(); i++) {
            scaled.add(this.elements.get(i).times(alpha));
        }
        return new FieldVector<>(scaled);
    }

    FieldVector axpy(final FieldVector other, final T alpha) {
        final List result = new ArrayList<>(this.size());
        for (int i = 0; i < this.size(); i++) {
            result.add(this.elements.get(i).times(alpha).plus(other.elements.get(i)));
        }
        return new FieldVector<>(result);
    }

    /**
     * Compute the dot product of this vector with the given vector.
     *
     * @param other the vector to take the dot product with.
     * @return the dot product of this vector with the given vector.
     */
    T dotProduct(final FieldVector other) {
        if (this.size() > 0) {
            T product = this.elements.get(0).times(other.elements.get(0).conjugate());
            for (int t = 1; t < this.elements.size(); t++) {
                product = product.plus(this.elements.get(t).times(other.elements.get(t).conjugate()));
            }
            return product;
        }
        throw new IllegalStateException("The dot product is undefined for zero length vectors.");
    }

    /**
     * Compute the L2 length of this vector.
     *
     * @return the L2 length of this vector.
     */
    double norm() {
        return Math.sqrt(sumOfSquares());
    }

    private double sumOfSquares() {
        double sum = 0.0;
        if (this.size() > 0) {
            sum = Math.pow(this.elements.get(0).abs(), 2);
            for (int i = 1; i < this.elements.size(); i++) {
                sum += Math.pow(this.elements.get(i).abs(), 2);
            }
        }
        return sum;
    }


    @Override
    public String toString() {
        return "elements: " + elements;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((elements == null) ? 0 : elements.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        FieldVector other = (FieldVector) obj;
        if (elements == null) {
            if (other.elements != null) return false;
        } else if (!elements.equals(other.elements)) return false;
        return true;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy