<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.commons.geometry.euclidean.oned;

import org.apache.commons.geometry.core.Geometry;
import org.apache.commons.geometry.core.exception.IllegalNormException;
import org.apache.commons.geometry.core.internal.SimpleTupleFormat;
import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
import org.apache.commons.geometry.euclidean.EuclideanVector;
import org.apache.commons.geometry.euclidean.internal.Vectors;
import org.apache.commons.numbers.arrays.LinearCombination;

/** This class represents vectors and points in one-dimensional Euclidean space.
 * Instances of this class are guaranteed to be immutable.
 */
public class Vector1D extends EuclideanVector<Vector1D> {

    /** Zero vector (coordinates: 0). */
    public static final Vector1D ZERO = new Vector1D(0.0);

    /** Unit vector (coordinates: 1). */
    public static final Vector1D ONE  = Unit.ONE;

    /** Negation of unit vector (coordinates: -1). */
    public static final Vector1D MINUS_ONE = Unit.MINUS_ONE;

    // CHECKSTYLE: stop ConstantName
    /** A vector with all coordinates set to NaN. */
    public static final Vector1D NaN = new Vector1D(Double.NaN);
    // CHECKSTYLE: resume ConstantName

    /** A vector with all coordinates set to positive infinity. */
    public static final Vector1D POSITIVE_INFINITY =
        new Vector1D(Double.POSITIVE_INFINITY);

    /** A vector with all coordinates set to negative infinity. */
    public static final Vector1D NEGATIVE_INFINITY =
        new Vector1D(Double.NEGATIVE_INFINITY);

    /** Serializable UID. */
    private static final long serialVersionUID = 20180710L;

    /** Abscissa (coordinate value). */
    private final double x;

    /** Simple constructor.
     * @param x abscissa (coordinate value)
     */
    private Vector1D(double x) {
        this.x = x;
    }

    /**
     * Returns the abscissa (coordinate value) of the instance.
     * @return the abscissa value
     */
    public double getX() {
        return x;
    }

    /** {@inheritDoc} */
    @Override
    public int getDimension() {
        return 1;
    }

    /** {@inheritDoc} */
    @Override
    public boolean isNaN() {
        return Double.isNaN(x);
    }

    /** {@inheritDoc} */
    @Override
    public boolean isInfinite() {
        return !isNaN() && Double.isInfinite(x);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D vectorTo(Vector1D v) {
        return v.subtract(this);
    }

    /** {@inheritDoc} */
    @Override
    public Unit directionTo(Vector1D v) {
        return vectorTo(v).normalize();
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D lerp(Vector1D p, double t) {
        return linearCombination(1.0 - t, this, t, p);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D getZero() {
        return ZERO;
    }

    /** {@inheritDoc} */
    @Override
    public double norm() {
        return Vectors.norm(x);
    }

    /** {@inheritDoc} */
    @Override
    public double normSq() {
        return Vectors.normSq(x);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D withNorm(double magnitude) {
        getCheckedNorm(); // validate our norm value
        return (x > 0.0)? new Vector1D(magnitude) : new Vector1D(-magnitude);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D add(Vector1D v) {
        return new Vector1D(x + v.x);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D add(double factor, Vector1D v) {
        return new Vector1D(x + (factor * v.x));
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D subtract(Vector1D v) {
        return new Vector1D(x - v.x);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D subtract(double factor, Vector1D v) {
        return new Vector1D(x - (factor * v.x));
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D negate() {
        return new Vector1D(-x);
    }

    /** {@inheritDoc} */
    @Override
    public Unit normalize() {
        return Unit.from(x);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D multiply(double a) {
        return new Vector1D(a * x);
    }

    /** {@inheritDoc} */
    @Override
    public double distance(Vector1D v) {
        return Vectors.norm(x - v.x);
    }

    /** {@inheritDoc} */
    @Override
    public double distanceSq(Vector1D v) {
        return Vectors.normSq(x - v.x);
    }

    /** {@inheritDoc} */
    @Override
    public double dot(Vector1D v) {
        return x * v.x;
    }

    /** {@inheritDoc}
     * <p>For the one-dimensional case, this method returns 0 if the vector x values have
     * the same sign and {@code pi} if they are opposite.</p>
     */
    @Override
    public double angle(final Vector1D v) {
        // validate the norm values
        getCheckedNorm();
        v.getCheckedNorm();

        final double sig1 = Math.signum(x);
        final double sig2 = Math.signum(v.x);

        // the angle is 0 if the x value signs are the same and pi if not
        return (sig1 == sig2) ? 0.0 : Geometry.PI;
    }

    /** Apply the given transform to this vector, returning the result as a
     * new vector instance.
     * @param transform the transform to apply
     * @return a new, transformed vector
     * @see AffineTransformMatrix1D#apply(Vector1D)
     */
    public Vector1D transform(AffineTransformMatrix1D transform) {
        return transform.apply(this);
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(final Vector1D vec, final DoublePrecisionContext precision) {
        return precision.eq(x, vec.x);
    }

    /**
     * Get a hashCode for the vector.
     * <p>All NaN values have the same hash code.</p>
     *
     * @return a hash code value for this object
     */
    @Override
    public int hashCode() {
        if (isNaN()) {
            return 857;
        }
        return 403 * Double.hashCode(x);
    }

    /**
     * Test for the equality of two vectors.
     * <p>
     * If all coordinates of two vectors are exactly the same, and none are
     * <code>Double.NaN</code>, the two vectors are considered to be equal.
     * </p>
     * <p>
     * <code>NaN</code> coordinates are considered to globally affect the vector
     * and be equal to each other - i.e, if either (or all) coordinates of the
     * vector are equal to <code>Double.NaN</code>, the vector is equal to
     * {@link #NaN}.
     * </p>
     *
     * @param other Object to test for equality to this
     * @return true if two vector objects are equal, false if
     *         object is null, not an instance of Vector1D, or
     *         not equal to this Vector1D instance
     *
     */
    @Override
    public boolean equals(Object other) {

        if (this == other) {
            return true;
        }

        if (other instanceof Vector1D) {
            final Vector1D rhs = (Vector1D) other;
            if (rhs.isNaN()) {
                return this.isNaN();
            }

            return x == rhs.x;
        }
        return false;
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return SimpleTupleFormat.getDefault().format(x);
    }

    /** Returns a vector with the given coordinate value.
     * @param x vector coordinate
     * @return vector instance
     */
    public static Vector1D of(double x) {
        return new Vector1D(x);
    }

    /** Parses the given string and returns a new vector instance. The expected string
     * format is the same as that returned by {@link #toString()}.
     * @param str the string to parse
     * @return vector instance represented by the string
     * @throws IllegalArgumentException if the given string has an invalid format
     */
    public static Vector1D parse(String str) {
        return SimpleTupleFormat.getDefault().parse(str, Vector1D::new);
    }

    /** Returns a vector consisting of the linear combination of the inputs.
     * <p>
     * A linear combination is the sum of all of the inputs multiplied by their
     * corresponding scale factors.
     * </p>
     *
     * @param a scale factor for first coordinate
     * @param c first coordinate
     * @return vector with coordinates calculated by {@code a * c}
     */
    public static Vector1D linearCombination(double a, Vector1D c) {
        return new Vector1D(a * c.x);
    }

    /** Returns a vector consisting of the linear combination of the inputs.
     * <p>
     * A linear combination is the sum of all of the inputs multiplied by their
     * corresponding scale factors.
     * </p>
     *
     * @param a1 scale factor for first coordinate
     * @param v1 first coordinate
     * @param a2 scale factor for second coordinate
     * @param v2 second coordinate
     * @return vector with coordinates calculated by {@code (a1 * v1) + (a2 * v2)}
     */
    public static Vector1D linearCombination(double a1, Vector1D v1, double a2, Vector1D v2) {
        return new Vector1D(
                LinearCombination.value(a1, v1.x, a2, v2.x));
    }

    /** Returns a vector consisting of the linear combination of the inputs.
     * <p>
     * A linear combination is the sum of all of the inputs multiplied by their
     * corresponding scale factors.
     * </p>
     *
     * @param a1 scale factor for first coordinate
     * @param v1 first coordinate
     * @param a2 scale factor for second coordinate
     * @param v2 second coordinate
     * @param a3 scale factor for third coordinate
     * @param v3 third coordinate
     * @return vector with coordinates calculated by {@code (a1 * v1) + (a2 * v2) + (a3 * v3)}
     */
    public static Vector1D linearCombination(double a1, Vector1D v1, double a2, Vector1D v2,
            double a3, Vector1D v3) {
        return new Vector1D(
                LinearCombination.value(a1, v1.x, a2, v2.x, a3, v3.x));
    }

    /** Returns a vector consisting of the linear combination of the inputs.
     * <p>
     * A linear combination is the sum of all of the inputs multiplied by their
     * corresponding scale factors.
     * </p>
     *
     * @param a1 scale factor for first coordinate
     * @param v1 first coordinate
     * @param a2 scale factor for second coordinate
     * @param v2 second coordinate
     * @param a3 scale factor for third coordinate
     * @param v3 third coordinate
     * @param a4 scale factor for fourth coordinate
     * @param v4 fourth coordinate
     * @return point with coordinates calculated by {@code (a1 * v1) + (a2 * v2) + (a3 * v3) + (a4 * v4)}
     */
    public static Vector1D linearCombination(double a1, Vector1D v1, double a2, Vector1D v2,
            double a3, Vector1D v3, double a4, Vector1D v4) {
        return new Vector1D(
                LinearCombination.value(a1, v1.x, a2, v2.x, a3, v3.x, a4, v4.x));
    }

    /**
     * Represent unit vectors.
     * This allows optimizations to be performed for certain operations.
     */
    public static final class Unit extends Vector1D {
        /** Unit vector (coordinates: 1). */
        static final Unit ONE  = new Unit(1d);
        /** Negation of unit vector (coordinates: -1). */
        static final Unit MINUS_ONE = new Unit(-1d);

        /** Serializable version identifier */
        private static final long serialVersionUID = 20180903L;

        /** Simple constructor. Callers are responsible for ensuring that the given
         * values represent a normalized vector.
         * @param x abscissa (first coordinate value)
         */
        private Unit(final double x) {
            super(x);
        }

        /**
         * Creates a normalized vector.
         *
         * @param v Vector coordinate.
         * @return a vector whose norm is 1.
         * @throws IllegalNormException if the norm of the given value is zero, NaN, or infinite
         */
        public static Unit from(double x) {
            Vectors.checkedNorm(Vectors.norm(x));
            return x > 0 ? ONE : MINUS_ONE;
        }

        /**
         * Creates a normalized vector.
         *
         * @param v Vector.
         * @return a vector whose norm is 1.
         * @throws IllegalNormException if the norm of the given value is zero, NaN, or infinite
         */
        public static Unit from(Vector1D v) {
            return v instanceof Unit ?
                (Unit) v :
                from(v.getX());
        }

        /** {@inheritDoc} */
        @Override
        public double norm() {
            return 1;
        }

        /** {@inheritDoc} */
        @Override
        public double normSq() {
            return 1;
        }

        /** {@inheritDoc} */
        @Override
        public Unit normalize() {
            return this;
        }

        /** {@inheritDoc} */
        @Override
        public Vector1D withNorm(final double mag) {
            return multiply(mag);
        }

        /** {@inheritDoc} */
        @Override
        public Vector1D negate() {
            return this == ONE ? MINUS_ONE : ONE;
        }
    }
}
<commit_msg>Javadoc.<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.commons.geometry.euclidean.oned;

import org.apache.commons.geometry.core.Geometry;
import org.apache.commons.geometry.core.exception.IllegalNormException;
import org.apache.commons.geometry.core.internal.SimpleTupleFormat;
import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
import org.apache.commons.geometry.euclidean.EuclideanVector;
import org.apache.commons.geometry.euclidean.internal.Vectors;
import org.apache.commons.numbers.arrays.LinearCombination;

/** This class represents vectors and points in one-dimensional Euclidean space.
 * Instances of this class are guaranteed to be immutable.
 */
public class Vector1D extends EuclideanVector<Vector1D> {

    /** Zero vector (coordinates: 0). */
    public static final Vector1D ZERO = new Vector1D(0.0);

    /** Unit vector (coordinates: 1). */
    public static final Vector1D ONE  = Unit.ONE;

    /** Negation of unit vector (coordinates: -1). */
    public static final Vector1D MINUS_ONE = Unit.MINUS_ONE;

    // CHECKSTYLE: stop ConstantName
    /** A vector with all coordinates set to NaN. */
    public static final Vector1D NaN = new Vector1D(Double.NaN);
    // CHECKSTYLE: resume ConstantName

    /** A vector with all coordinates set to positive infinity. */
    public static final Vector1D POSITIVE_INFINITY =
        new Vector1D(Double.POSITIVE_INFINITY);

    /** A vector with all coordinates set to negative infinity. */
    public static final Vector1D NEGATIVE_INFINITY =
        new Vector1D(Double.NEGATIVE_INFINITY);

    /** Serializable UID. */
    private static final long serialVersionUID = 20180710L;

    /** Abscissa (coordinate value). */
    private final double x;

    /** Simple constructor.
     * @param x abscissa (coordinate value)
     */
    private Vector1D(double x) {
        this.x = x;
    }

    /**
     * Returns the abscissa (coordinate value) of the instance.
     * @return the abscissa value
     */
    public double getX() {
        return x;
    }

    /** {@inheritDoc} */
    @Override
    public int getDimension() {
        return 1;
    }

    /** {@inheritDoc} */
    @Override
    public boolean isNaN() {
        return Double.isNaN(x);
    }

    /** {@inheritDoc} */
    @Override
    public boolean isInfinite() {
        return !isNaN() && Double.isInfinite(x);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D vectorTo(Vector1D v) {
        return v.subtract(this);
    }

    /** {@inheritDoc} */
    @Override
    public Unit directionTo(Vector1D v) {
        return vectorTo(v).normalize();
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D lerp(Vector1D p, double t) {
        return linearCombination(1.0 - t, this, t, p);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D getZero() {
        return ZERO;
    }

    /** {@inheritDoc} */
    @Override
    public double norm() {
        return Vectors.norm(x);
    }

    /** {@inheritDoc} */
    @Override
    public double normSq() {
        return Vectors.normSq(x);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D withNorm(double magnitude) {
        getCheckedNorm(); // validate our norm value
        return (x > 0.0)? new Vector1D(magnitude) : new Vector1D(-magnitude);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D add(Vector1D v) {
        return new Vector1D(x + v.x);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D add(double factor, Vector1D v) {
        return new Vector1D(x + (factor * v.x));
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D subtract(Vector1D v) {
        return new Vector1D(x - v.x);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D subtract(double factor, Vector1D v) {
        return new Vector1D(x - (factor * v.x));
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D negate() {
        return new Vector1D(-x);
    }

    /** {@inheritDoc} */
    @Override
    public Unit normalize() {
        return Unit.from(x);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D multiply(double a) {
        return new Vector1D(a * x);
    }

    /** {@inheritDoc} */
    @Override
    public double distance(Vector1D v) {
        return Vectors.norm(x - v.x);
    }

    /** {@inheritDoc} */
    @Override
    public double distanceSq(Vector1D v) {
        return Vectors.normSq(x - v.x);
    }

    /** {@inheritDoc} */
    @Override
    public double dot(Vector1D v) {
        return x * v.x;
    }

    /** {@inheritDoc}
     * <p>For the one-dimensional case, this method returns 0 if the vector x values have
     * the same sign and {@code pi} if they are opposite.</p>
     */
    @Override
    public double angle(final Vector1D v) {
        // validate the norm values
        getCheckedNorm();
        v.getCheckedNorm();

        final double sig1 = Math.signum(x);
        final double sig2 = Math.signum(v.x);

        // the angle is 0 if the x value signs are the same and pi if not
        return (sig1 == sig2) ? 0.0 : Geometry.PI;
    }

    /** Apply the given transform to this vector, returning the result as a
     * new vector instance.
     * @param transform the transform to apply
     * @return a new, transformed vector
     * @see AffineTransformMatrix1D#apply(Vector1D)
     */
    public Vector1D transform(AffineTransformMatrix1D transform) {
        return transform.apply(this);
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(final Vector1D vec, final DoublePrecisionContext precision) {
        return precision.eq(x, vec.x);
    }

    /**
     * Get a hashCode for the vector.
     * <p>All NaN values have the same hash code.</p>
     *
     * @return a hash code value for this object
     */
    @Override
    public int hashCode() {
        if (isNaN()) {
            return 857;
        }
        return 403 * Double.hashCode(x);
    }

    /**
     * Test for the equality of two vectors.
     * <p>
     * If all coordinates of two vectors are exactly the same, and none are
     * <code>Double.NaN</code>, the two vectors are considered to be equal.
     * </p>
     * <p>
     * <code>NaN</code> coordinates are considered to globally affect the vector
     * and be equal to each other - i.e, if either (or all) coordinates of the
     * vector are equal to <code>Double.NaN</code>, the vector is equal to
     * {@link #NaN}.
     * </p>
     *
     * @param other Object to test for equality to this
     * @return true if two vector objects are equal, false if
     *         object is null, not an instance of Vector1D, or
     *         not equal to this Vector1D instance
     *
     */
    @Override
    public boolean equals(Object other) {

        if (this == other) {
            return true;
        }

        if (other instanceof Vector1D) {
            final Vector1D rhs = (Vector1D) other;
            if (rhs.isNaN()) {
                return this.isNaN();
            }

            return x == rhs.x;
        }
        return false;
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return SimpleTupleFormat.getDefault().format(x);
    }

    /** Returns a vector with the given coordinate value.
     * @param x vector coordinate
     * @return vector instance
     */
    public static Vector1D of(double x) {
        return new Vector1D(x);
    }

    /** Parses the given string and returns a new vector instance. The expected string
     * format is the same as that returned by {@link #toString()}.
     * @param str the string to parse
     * @return vector instance represented by the string
     * @throws IllegalArgumentException if the given string has an invalid format
     */
    public static Vector1D parse(String str) {
        return SimpleTupleFormat.getDefault().parse(str, Vector1D::new);
    }

    /** Returns a vector consisting of the linear combination of the inputs.
     * <p>
     * A linear combination is the sum of all of the inputs multiplied by their
     * corresponding scale factors.
     * </p>
     *
     * @param a scale factor for first coordinate
     * @param c first coordinate
     * @return vector with coordinates calculated by {@code a * c}
     */
    public static Vector1D linearCombination(double a, Vector1D c) {
        return new Vector1D(a * c.x);
    }

    /** Returns a vector consisting of the linear combination of the inputs.
     * <p>
     * A linear combination is the sum of all of the inputs multiplied by their
     * corresponding scale factors.
     * </p>
     *
     * @param a1 scale factor for first coordinate
     * @param v1 first coordinate
     * @param a2 scale factor for second coordinate
     * @param v2 second coordinate
     * @return vector with coordinates calculated by {@code (a1 * v1) + (a2 * v2)}
     */
    public static Vector1D linearCombination(double a1, Vector1D v1, double a2, Vector1D v2) {
        return new Vector1D(
                LinearCombination.value(a1, v1.x, a2, v2.x));
    }

    /** Returns a vector consisting of the linear combination of the inputs.
     * <p>
     * A linear combination is the sum of all of the inputs multiplied by their
     * corresponding scale factors.
     * </p>
     *
     * @param a1 scale factor for first coordinate
     * @param v1 first coordinate
     * @param a2 scale factor for second coordinate
     * @param v2 second coordinate
     * @param a3 scale factor for third coordinate
     * @param v3 third coordinate
     * @return vector with coordinates calculated by {@code (a1 * v1) + (a2 * v2) + (a3 * v3)}
     */
    public static Vector1D linearCombination(double a1, Vector1D v1, double a2, Vector1D v2,
            double a3, Vector1D v3) {
        return new Vector1D(
                LinearCombination.value(a1, v1.x, a2, v2.x, a3, v3.x));
    }

    /** Returns a vector consisting of the linear combination of the inputs.
     * <p>
     * A linear combination is the sum of all of the inputs multiplied by their
     * corresponding scale factors.
     * </p>
     *
     * @param a1 scale factor for first coordinate
     * @param v1 first coordinate
     * @param a2 scale factor for second coordinate
     * @param v2 second coordinate
     * @param a3 scale factor for third coordinate
     * @param v3 third coordinate
     * @param a4 scale factor for fourth coordinate
     * @param v4 fourth coordinate
     * @return point with coordinates calculated by {@code (a1 * v1) + (a2 * v2) + (a3 * v3) + (a4 * v4)}
     */
    public static Vector1D linearCombination(double a1, Vector1D v1, double a2, Vector1D v2,
            double a3, Vector1D v3, double a4, Vector1D v4) {
        return new Vector1D(
                LinearCombination.value(a1, v1.x, a2, v2.x, a3, v3.x, a4, v4.x));
    }

    /**
     * Represent unit vectors.
     * This allows optimizations to be performed for certain operations.
     */
    public static final class Unit extends Vector1D {
        /** Unit vector (coordinates: 1). */
        static final Unit ONE  = new Unit(1d);
        /** Negation of unit vector (coordinates: -1). */
        static final Unit MINUS_ONE = new Unit(-1d);

        /** Serializable version identifier */
        private static final long serialVersionUID = 20180903L;

        /** Simple constructor. Callers are responsible for ensuring that the given
         * values represent a normalized vector.
         * @param x abscissa (first coordinate value)
         */
        private Unit(final double x) {
            super(x);
        }

        /**
         * Creates a normalized vector.
         *
         * @param x Vector coordinate.
         * @return a vector whose norm is 1.
         * @throws IllegalNormException if the norm of the given value is zero, NaN, or infinite
         */
        public static Unit from(double x) {
            Vectors.checkedNorm(Vectors.norm(x));
            return x > 0 ? ONE : MINUS_ONE;
        }

        /**
         * Creates a normalized vector.
         *
         * @param v Vector.
         * @return a vector whose norm is 1.
         * @throws IllegalNormException if the norm of the given value is zero, NaN, or infinite
         */
        public static Unit from(Vector1D v) {
            return v instanceof Unit ?
                (Unit) v :
                from(v.getX());
        }

        /** {@inheritDoc} */
        @Override
        public double norm() {
            return 1;
        }

        /** {@inheritDoc} */
        @Override
        public double normSq() {
            return 1;
        }

        /** {@inheritDoc} */
        @Override
        public Unit normalize() {
            return this;
        }

        /** {@inheritDoc} */
        @Override
        public Vector1D withNorm(final double mag) {
            return multiply(mag);
        }

        /** {@inheritDoc} */
        @Override
        public Vector1D negate() {
            return this == ONE ? MINUS_ONE : ONE;
        }
    }
}

{'fraction_non_alphanumeric': 0.09936117226693615, 'fraction_numerical': 0.014653336701916483, 'mean_word_length': 2.18263266712612, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 53, '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': '2502962', 'n_tokens_mistral': 8026, 'n_tokens_neox': 7740, 'n_words': 2778}