<commit_before>/*
Copyright 2005 <NAME>

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 org.gavrog.joss.geometry;

import java.util.List;

import org.gavrog.jane.compounds.Matrix;
import org.gavrog.jane.numbers.ArithmeticBase;
import org.gavrog.jane.numbers.Complex;
import org.gavrog.jane.numbers.IArithmetic;
import org.gavrog.jane.numbers.Rational;
import org.gavrog.jane.numbers.Real;
import org.gavrog.jane.numbers.Whole;

/**
 * A d-dimensional vector represented by a row vector. To make interaction with
 * other geometry types easier, a zero coordinate is added internally.
 * 
 * @author <NAME>
 * @version $Id: Vector.java,v 1.29 2006/09/12 23:00:44 odf Exp $
 */
public class Vector extends ArithmeticBase implements IArithmetic {
    final Matrix coords;
    final int dimension;

    /**
     * Creates a new vector from a row matrix containing its cartesian
     * coordinates. The dimension d of the vector created will correspond to the
     * number of columns in the given matrix. An extra coordinate of value 0
     * will be added internally.
     * 
     * @param M contains the coordinates for the vector.
     */
    public Vector(final Matrix M) {
        if (M.numberOfRows() != 1) {
            throw new IllegalArgumentException("matrix must have exactly 1 row");
        }
        final int d = M.numberOfColumns();
        this.dimension = d;
        this.coords = new Matrix(1, d + 1);
        this.coords.setSubMatrix(0, 0, M);
        this.coords.set(0, d, Whole.ZERO);
    }

    /**
     * Creates a new vector from its cartesian coordinates represented as an
     * array. The dimension d of the vector created will correspond to the
     * number of an entries in the array. An extra coordinate of value 0 will be
     * added internally.
     * 
     * @param coordinates the coordinates for the vector.
     */
    public Vector(final IArithmetic[] coordinates) {
        this(new Matrix(new IArithmetic[][] {coordinates}));
    }
    
    /**
     * Creates a new vector from its cartesian coordinates represented as an
     * array. The dimension d of the vector created will correspond to the
     * number of an entries in the array. An extra coordinate of value 0 will be
     * added internally.
     * 
     * @param coordinates the coordinates for the vector.
     */
    public Vector(final int[] coordinates) {
        this(new Matrix(new int[][] {coordinates}));
    }
    
    /**
     * Creates a new vector from its cartesian coordinates represented as an
     * array. The dimension d of the vector created will correspond to the
     * number of an entries in the array. An extra coordinate of value 0 will be
     * added internally.
     * 
     * @param coordinates the coordinates for the vector.
     */
    public Vector(final double[] coordinates) {
        this(new Matrix(new double[][] {coordinates}));
    }
    
    /**
     * Creates a new 2-dimensional vector.
     * 
     * @param a the first coordinate.
     * @param b the second coordinate.
     */
    public Vector(final int a, final int b) {
        this(new int[] { a, b });
    }
    
    /**
     * Creates a new 3-dimensional vector.
     * 
     * @param a the first coordinate.
     * @param b the second coordinate.
     * @param c the third coordinate.
     */
    public Vector(final int a, final int b, final int c) {
        this(new int[] { a, b, c });
    }
    
    /**
     * Creates a new 2-dimensional vector.
     * 
     * @param a the first coordinate.
     * @param b the second coordinate.
     */
    public Vector(final IArithmetic a, final IArithmetic b) {
        this(new IArithmetic[] { a, b });
    }
    
    /**
     * Creates a new 3-dimensional vector.
     * 
     * @param a the first coordinate.
     * @param b the second coordinate.
     * @param c the third coordinate.
     */
    public Vector(final IArithmetic a, final IArithmetic b, final IArithmetic c) {
        this(new IArithmetic[] { a, b, c });
    }
    
    /**
     * Creates a new vector as a copy of a given one.
     * @param v the model vector.
     */
    public Vector(final Vector v) {
        this.dimension = v.dimension;
        this.coords = v.coords;
    }
    
    /**
     * This constructor applies a matrix to a vector. It is used to apply a
     * general projective operator to a vector.
     * 
     * @param v the original vector.
     * @param M the operator to apply as a (d+1)x(d+1) matrix.
     */
    Vector(final Vector v, final Matrix M) {
        this(image(v, M));
    }

    /**
     * Applies an operator to a vector.
     * 
     * @param v the original vector.
     * @param M the operator to apply as a (d+1)x(d+1) matrix.
     * @return the resulting vector coordinates.
     */
    private static Matrix image(final Vector v, final Matrix M) {
        final int d = v.getDimension();
        if (d != M.numberOfRows() - 1 || d != M.numberOfColumns() - 1) {
            throw new IllegalArgumentException("dimensions don't match");
        }
        final Matrix img = (Matrix) v.coords.times(M);
        if (!img.get(0, d).isZero()) {
            throw new UnsupportedOperationException(
                    "the operation did not produce a vector");
        }
        return img.getSubMatrix(0, 0, 1, d);
    }
    
    /**
     * Returns a zero vector of a certain dimension.
     * 
     * @param dimension the requested dimension of the vector.
     * @return a zero vector of the requested dimension.
     */
    public static Vector zero(final int dimension) {
        return new Vector(Matrix.zero(1, dimension));
    }
    
    /**
     * Returns a unit vector, that is, a vector with a 1 at exactly one position and 0
     * everywhere else.
     * 
     * @param dimension the dimension of the vector.
     * @param axis the index of the non-zero entry.
     * @return the new vector.
     */
    public static Vector unit(final int dimension, final int axis) {
        final int a[] = new int[dimension];
        a[axis] = 1;
        return new Vector(a);
    }
    
    /**
     * Computes the product of two vectors with respect to a given quadratic form.
     * 
     * @param v the first vector.
     * @param w the second vector.
     * @param form a matrix representing the quadratic form.
     * @return the value of the product.
     */
    public static IArithmetic dot(final Vector v, final Vector w, final Matrix form) {
        final int d = v.getDimension();
        if (w.getDimension() != d || form.numberOfRows() != d
                || form.numberOfColumns() != d) {
            throw new IllegalArgumentException("dimensions do not match");
        }
        if (!form.equals(form.transposed())) {<commit_msg>Added new method unit() with vector argument.<commit_after>/*
Copyright 2005 <NAME>

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 org.gavrog.joss.geometry;

import java.util.List;

import org.gavrog.jane.compounds.Matrix;
import org.gavrog.jane.numbers.ArithmeticBase;
import org.gavrog.jane.numbers.Complex;
import org.gavrog.jane.numbers.IArithmetic;
import org.gavrog.jane.numbers.Rational;
import org.gavrog.jane.numbers.Real;
import org.gavrog.jane.numbers.Whole;

/**
 * A d-dimensional vector represented by a row vector. To make interaction with
 * other geometry types easier, a zero coordinate is added internally.
 * 
 * @author <NAME>
 * @version $Id: Vector.java,v 1.30 2007/05/30 00:36:14 odf Exp $
 */
public class Vector extends ArithmeticBase implements IArithmetic {
    final Matrix coords;
    final int dimension;

    /**
     * Creates a new vector from a row matrix containing its cartesian
     * coordinates. The dimension d of the vector created will correspond to the
     * number of columns in the given matrix. An extra coordinate of value 0
     * will be added internally.
     * 
     * @param M contains the coordinates for the vector.
     */
    public Vector(final Matrix M) {
        if (M.numberOfRows() != 1) {
            throw new IllegalArgumentException("matrix must have exactly 1 row");
        }
        final int d = M.numberOfColumns();
        this.dimension = d;
        this.coords = new Matrix(1, d + 1);
        this.coords.setSubMatrix(0, 0, M);
        this.coords.set(0, d, Whole.ZERO);
    }

    /**
     * Creates a new vector from its cartesian coordinates represented as an
     * array. The dimension d of the vector created will correspond to the
     * number of an entries in the array. An extra coordinate of value 0 will be
     * added internally.
     * 
     * @param coordinates the coordinates for the vector.
     */
    public Vector(final IArithmetic[] coordinates) {
        this(new Matrix(new IArithmetic[][] {coordinates}));
    }
    
    /**
     * Creates a new vector from its cartesian coordinates represented as an
     * array. The dimension d of the vector created will correspond to the
     * number of an entries in the array. An extra coordinate of value 0 will be
     * added internally.
     * 
     * @param coordinates the coordinates for the vector.
     */
    public Vector(final int[] coordinates) {
        this(new Matrix(new int[][] {coordinates}));
    }
    
    /**
     * Creates a new vector from its cartesian coordinates represented as an
     * array. The dimension d of the vector created will correspond to the
     * number of an entries in the array. An extra coordinate of value 0 will be
     * added internally.
     * 
     * @param coordinates the coordinates for the vector.
     */
    public Vector(final double[] coordinates) {
        this(new Matrix(new double[][] {coordinates}));
    }
    
    /**
     * Creates a new 2-dimensional vector.
     * 
     * @param a the first coordinate.
     * @param b the second coordinate.
     */
    public Vector(final int a, final int b) {
        this(new int[] { a, b });
    }
    
    /**
     * Creates a new 3-dimensional vector.
     * 
     * @param a the first coordinate.
     * @param b the second coordinate.
     * @param c the third coordinate.
     */
    public Vector(final int a, final int b, final int c) {
        this(new int[] { a, b, c });
    }
    
    /**
     * Creates a new 2-dimensional vector.
     * 
     * @param a the first coordinate.
     * @param b the second coordinate.
     */
    public Vector(final IArithmetic a, final IArithmetic b) {
        this(new IArithmetic[] { a, b });
    }
    
    /**
     * Creates a new 3-dimensional vector.
     * 
     * @param a the first coordinate.
     * @param b the second coordinate.
     * @param c the third coordinate.
     */
    public Vector(final IArithmetic a, final IArithmetic b, final IArithmetic c) {
        this(new IArithmetic[] { a, b, c });
    }
    
    /**
     * Creates a new vector as a copy of a given one.
     * @param v the model vector.
     */
    public Vector(final Vector v) {
        this.dimension = v.dimension;
        this.coords = v.coords;
    }
    
    /**
     * This constructor applies a matrix to a vector. It is used to apply a
     * general projective operator to a vector.
     * 
     * @param v the original vector.
     * @param M the operator to apply as a (d+1)x(d+1) matrix.
     */
    Vector(final Vector v, final Matrix M) {
        this(image(v, M));
    }

    /**
     * Applies an operator to a vector.
     * 
     * @param v the original vector.
     * @param M the operator to apply as a (d+1)x(d+1) matrix.
     * @return the resulting vector coordinates.
     */
    private static Matrix image(final Vector v, final Matrix M) {
        final int d = v.getDimension();
        if (d != M.numberOfRows() - 1 || d != M.numberOfColumns() - 1) {
            throw new IllegalArgumentException("dimensions don't match");
        }
        final Matrix img = (Matrix) v.coords.times(M);
        if (!img.get(0, d).isZero()) {
            throw new UnsupportedOperationException(
                    "the operation did not produce a vector");
        }
        return img.getSubMatrix(0, 0, 1, d);
    }
    
    /**
     * Returns a zero vector of a certain dimension.
     * 
     * @param dimension the requested dimension of the vector.
     * @return a zero vector of the requested dimension.
     */
    public static Vector zero(final int dimension) {
        return new Vector(Matrix.zero(1, dimension));
    }
    
    /**
     * Returns a unit vector, that is, a vector with a 1 at exactly one position and 0
     * everywhere else.
     * 
     * @param dimension the dimension of the vector.
     * @param axis the index of the non-zero entry.
     * @return the new vector.
     */
    public static Vector unit(final int dimension, final int axis) {
        final int a[] = new int[dimension];
        a[axis] = 1;
        return new Vector(a);
    }
    
    /**
     * Returns a unit vector in the same direction as the given one.
     * 
     * @param source the input vector.
     * @return a vector of unit length in the same direction.
     */
    public static Vector unit(final Vector source) {
        final IArithmetic x = dot(source, source);
        if (x instanceof Real) {
            return (Vector) x.dividedBy(((Real) x).sqrt());
        } else {
            throw new IllegalArgumentException("cannot take square root");
        }
    }
    
    /**
     * Computes the product of two vectors with respect to a given quadratic form.
     * 
     * @param v the first vector.
     * @param w the second vector.
     * @param form a matrix representing the quadratic form.
     * @return the value of the product.
     */
    public static IArithmetic dot(final Vector v, final Vector w, final Matrix form) {
        final int d = v.getDimension();
        if (w.getDimension() != d || form.numberOfRows() != d
                || form.numberOfColumns() != d) {
            throw new IllegalArgumentException("dimensions do not match");
        }
        if (!form.equals(form.transposed())) {
{'fraction_non_alphanumeric': 0.09274896126524594, 'fraction_numerical': 0.007237635705669481, 'mean_word_length': 2.2913542126157918, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5204169', 'n_tokens_mistral': 4277, 'n_tokens_neox': 4091, 'n_words': 1683}