/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.generators;

import java.util.Objects;
import com.io7m.jtensors.core.unparameterized.vectors.Vector2D;
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;

/**
 * A vector generator.
 */

public final class Vector2DGenerator implements Generator<Vector2D>
{
  private final Generator<Double> gen;

  /**
   * Construct a generator.
   *
   * @param in_gen A component generator
   */

  public Vector2DGenerator(
    final Generator<Double> in_gen)
  {
    this.gen = Objects.requireNonNull(in_gen, "Generator");
  }

  /**
   * Create a generator initialized with a default component generator.
   *
   * @return A generator
   */

  public static Generator<Vector2D> create()
  {
    return new Vector2DGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_LARGE_DOUBLE_LOWER,
      GeneratorConstants.BOUND_LARGE_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-65536.0, 65536.0]}.
   *
   * @return A generator
   */

  public static Generator<Vector2D> createSmall()
  {
    return new Vector2DGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_SMALL_DOUBLE_LOWER,
      GeneratorConstants.BOUND_SMALL_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-1.0, 1.0]}.
   *
   * @return A generator
   */

  public static Generator<Vector2D> createNormal()
  {
    return new Vector2DGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_NORMAL_DOUBLE_LOWER,
      GeneratorConstants.BOUND_NORMAL_DOUBLE_UPPER
    ));
  }

  @Override
  public Vector2D next()
  {
    return Vector2D.of(
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue());
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;
import com.io7m.jtensors.core.unparameterized.matrices.Matrix4x4D;
import com.io7m.jtensors.core.unparameterized.matrices.Matrix4x4F;

import java.nio.ByteBuffer;

/**
 *
A storage matrix.

 *
Storage component type: {@code binary16}

 *
Storage component count: {@code 4x4}

 */

public final class MatrixByteBuffered4x4s16
  extends TensorByteBufferedFloating16
  implements MatrixByteBuffered4x4Type
{
  private MatrixByteBuffered4x4s16(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static MatrixByteBuffered4x4s16 createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new MatrixByteBuffered4x4s16(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 4 * 4;
  }

  @Override
  public double r0c0()
  {
    return this.getValue(ColumnMajor.index4x4(0, 0));
  }

  @Override
  public double r0c1()
  {
    return this.getValue(ColumnMajor.index4x4(0, 1));
  }

  @Override
  public double r0c2()
  {
    return this.getValue(ColumnMajor.index4x4(0, 2));
  }

  @Override
  public double r0c3()
  {
    return this.getValue(ColumnMajor.index4x4(0, 3));
  }

  @Override
  public double r1c0()
  {
    return this.getValue(ColumnMajor.index4x4(1, 0));
  }

  @Override
  public double r1c1()
  {
    return this.getValue(ColumnMajor.index4x4(1, 1));
  }

  @Override
  public double r1c2()
  {
    return this.getValue(ColumnMajor.index4x4(1, 2));
  }

  @Override
  public double r1c3()
  {
    return this.getValue(ColumnMajor.index4x4(1, 3));
  }

  @Override
  public double r2c0()
  {
    return this.getValue(ColumnMajor.index4x4(2, 0));
  }

  @Override
  public double r2c1()
  {
    return this.getValue(ColumnMajor.index4x4(2, 1));
  }

  @Override
  public double r2c2()
  {
    return this.getValue(ColumnMajor.index4x4(2, 2));
  }

  @Override
  public double r2c3()
  {
    return this.getValue(ColumnMajor.index4x4(2, 3));
  }

  @Override
  public double r3c0()
  {
    return this.getValue(ColumnMajor.index4x4(3, 0));
  }

  @Override
  public double r3c1()
  {
    return this.getValue(ColumnMajor.index4x4(3, 1));
  }

  @Override
  public double r3c2()
  {
    return this.getValue(ColumnMajor.index4x4(3, 2));
  }

  @Override
  public double r3c3()
  {
    return this.getValue(ColumnMajor.index4x4(3, 3));
  }

  @Override
  public void setMatrix4x4D(final Matrix4x4D m)
  {
    this.putValue(ColumnMajor.index4x4(0, 0), m.r0c0());
    this.putValue(ColumnMajor.index4x4(0, 1), m.r0c1());
    this.putValue(ColumnMajor.index4x4(0, 2), m.r0c2());
    this.putValue(ColumnMajor.index4x4(0, 3), m.r0c3());

    this.putValue(ColumnMajor.index4x4(1, 0), m.r1c0());
    this.putValue(ColumnMajor.index4x4(1, 1), m.r1c1());
    this.putValue(ColumnMajor.index4x4(1, 2), m.r1c2());
    this.putValue(ColumnMajor.index4x4(1, 3), m.r1c3());

    this.putValue(ColumnMajor.index4x4(2, 0), m.r2c0());
    this.putValue(ColumnMajor.index4x4(2, 1), m.r2c1());
    this.putValue(ColumnMajor.index4x4(2, 2), m.r2c2());
    this.putValue(ColumnMajor.index4x4(2, 3), m.r2c3());

    this.putValue(ColumnMajor.index4x4(3, 0), m.r3c0());
    this.putValue(ColumnMajor.index4x4(3, 1), m.r3c1());
    this.putValue(ColumnMajor.index4x4(3, 2), m.r3c2());
    this.putValue(ColumnMajor.index4x4(3, 3), m.r3c3());
  }

  @Override
  public void setMatrix4x4F(final Matrix4x4F m)
  {
    this.putValue(ColumnMajor.index4x4(0, 0), (double) m.r0c0());
    this.putValue(ColumnMajor.index4x4(0, 1), (double) m.r0c1());
    this.putValue(ColumnMajor.index4x4(0, 2), (double) m.r0c2());
    this.putValue(ColumnMajor.index4x4(0, 3), (double) m.r0c3());

    this.putValue(ColumnMajor.index4x4(1, 0), (double) m.r1c0());
    this.putValue(ColumnMajor.index4x4(1, 1), (double) m.r1c1());
    this.putValue(ColumnMajor.index4x4(1, 2), (double) m.r1c2());
    this.putValue(ColumnMajor.index4x4(1, 3), (double) m.r1c3());

    this.putValue(ColumnMajor.index4x4(2, 0), (double) m.r2c0());
    this.putValue(ColumnMajor.index4x4(2, 1), (double) m.r2c1());
    this.putValue(ColumnMajor.index4x4(2, 2), (double) m.r2c2());
    this.putValue(ColumnMajor.index4x4(2, 3), (double) m.r2c3());

    this.putValue(ColumnMajor.index4x4(3, 0), (double) m.r3c0());
    this.putValue(ColumnMajor.index4x4(3, 1), (double) m.r3c1());
    this.putValue(ColumnMajor.index4x4(3, 2), (double) m.r3c2());
    this.putValue(ColumnMajor.index4x4(3, 3), (double) m.r3c3());
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.generators;

import java.util.Objects;
import com.io7m.jtensors.core.parameterized.matrices.PMatrix2x2F;
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;

/**
 * A matrix generator.
 *
 * @param <A> A phantom type parameter (possibly representing a source
 *            coordinate system)
 * @param <B> A phantom type parameter (possibly representing a target
 *            coordinate system)
 */

public final class PMatrix2x2FGenerator<A, B> implements Generator<PMatrix2x2F<A, B>>
{
  private final Generator<Double> gen;

  /**
   * Construct a generator.
   *
   * @param in_gen A component generator
   */

  public PMatrix2x2FGenerator(
    final Generator<Double> in_gen)
  {
    this.gen = Objects.requireNonNull(in_gen, "Generator");
  }

  /**
   * Create a generator initialized with a default component generator.
   *
   * @param <A> A phantom type parameter (possibly representing a source
   *            coordinate system)
   * @param <B> A phantom type parameter (possibly representing a target
   *            coordinate system)
   *
   * @return A generator
   */

  public static <A, B> Generator<PMatrix2x2F<A, B>> create()
  {
    return new PMatrix2x2FGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_LARGE_FLOAT_LOWER,
      GeneratorConstants.BOUND_LARGE_FLOAT_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that only
   * produces values in the range {@code [-1.0, 1.0]}.
   *
   * @param <A> A phantom type parameter (possibly representing a source
   *            coordinate system)
   * @param <B> A phantom type parameter (possibly representing a target
   *            coordinate system)
   *
   * @return A generator
   */

  public static <A, B> Generator<PMatrix2x2F<A, B>> createNormal()
  {
    return new PMatrix2x2FGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_NORMAL_FLOAT_LOWER,
      GeneratorConstants.BOUND_NORMAL_FLOAT_UPPER
    ));
  }

  @Override
  public PMatrix2x2F<A, B> next()
  {
    return PMatrix2x2F.of(
      this.gen.next().floatValue(),
      this.gen.next().floatValue(),
      this.gen.next().floatValue(),
      this.gen.next().floatValue());
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.generators;

import java.security.SecureRandom;
import java.util.Objects;
import com.io7m.jtensors.core.unparameterized.matrices.Matrix4x4D;
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;

/**
 * A matrix generator.
 */

public final class Matrix4x4DGenerator implements Generator<Matrix4x4D>
{
  private final Generator<Double> gen;

  /**
   * Construct a generator.
   *
   * @param in_gen A component generator
   */

  public Matrix4x4DGenerator(
    final Generator<Double> in_gen)
  {
    this.gen = Objects.requireNonNull(in_gen, "Generator");
  }

  /**
   * Create a generator initialized with a default component generator.
   *
   * @return A generator
   */

  public static Generator<Matrix4x4D> create()
  {
    return new Matrix4x4DGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_LARGE_DOUBLE_LOWER,
      GeneratorConstants.BOUND_LARGE_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that only
   * produces values in the range {@code [-1.0, 1.0]}.
   *
   * @return A generator
   */

  public static Generator<Matrix4x4D> createNormal()
  {
    return new Matrix4x4DGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_NORMAL_DOUBLE_LOWER,
      GeneratorConstants.BOUND_NORMAL_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that only
   * produces orthogonal matrices.
   *
   * @return A generator
   */

  public static Generator<Matrix4x4D> createOrthogonal()
  {
    return () -> {
      final SecureRandom rng = new SecureRandom();

      final double r0c0 = 1.0;
      final double r0c1 = 0.0;
      final double r0c2 = 0.0;
      final double r0c3 = rng.nextDouble();

      final double r1c0 = 0.0;
      final double r1c1 = 1.0;
      final double r1c2 = 0.0;
      final double r1c3 = rng.nextDouble();

      final double r2c0 = 0.0;
      final double r2c1 = 0.0;
      final double r2c2 = 1.0;
      final double r2c3 = rng.nextDouble();

      final double r3c0 = 0.0;
      final double r3c1 = 0.0;
      final double r3c2 = 0.0;
      final double r3c3 = 1.0;

      return Matrix4x4D.of(
        r0c0, r0c1, r0c2, r0c3,
        r1c0, r1c1, r1c2, r1c3,
        r2c0, r2c1, r2c2, r2c3,
        r3c0, r3c1, r3c2, r3c3);
    };
  }

  @Override
  public Matrix4x4D next()
  {
    return Matrix4x4D.of(
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue());
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.core.dotproducts;

import com.io7m.junreachable.UnreachableCodeException;

/**
 * Functions for calculating dot products.
 */

public final class DotProductsLong
{
  private DotProductsLong()
  {
    throw new UnreachableCodeException();
  }

  /**
   * Calculate the dot product of
   * {@code (x0, y0, z0, w0)} and {@code (x1, y1, z1, w1)}.
   *
   * @param x0 The X component of the first vector
   * @param y0 The Y component of the first vector
   * @param z0 The Z component of the first vector
   * @param w0 The W component of the first vector
   * @param x1 The X component of the second vector
   * @param y1 The Y component of the second vector
   * @param z1 The Z component of the second vector
   * @param w1 The W component of the second vector
   *
   * @return The dot product
   */

  public static long dotProduct4(
    final long x0,
    final long y0,
    final long z0,
    final long w0,
    final long x1,
    final long y1,
    final long z1,
    final long w1)
  {
    final long x = x0 * x1;
    final long y = y0 * y1;
    final long z = z0 * z1;
    final long w = w0 * w1;
    return x + y + z + w;
  }

  /**
   * Calculate the dot product of
   * {@code (x0, y0, z0)} and {@code (x1, y1, z1)}.
   *
   * @param x0 The X component of the first vector
   * @param y0 The Y component of the first vector
   * @param z0 The Z component of the first vector
   * @param x1 The X component of the second vector
   * @param y1 The Y component of the second vector
   * @param z1 The Z component of the second vector
   *
   * @return The dot product
   */

  public static long dotProduct3(
    final long x0,
    final long y0,
    final long z0,
    final long x1,
    final long y1,
    final long z1)
  {
    final long x = x0 * x1;
    final long y = y0 * y1;
    final long z = z0 * z1;
    return x + y + z;
  }

  /**
   * Calculate the dot product of {@code (x0, y0)} and {@code (x1, y1)}.
   *
   * @param x0 The X component of the first vector
   * @param y0 The Y component of the first vector
   * @param x1 The X component of the second vector
   * @param y1 The Y component of the second vector
   *
   * @return The dot product
   */

  public static long dotProduct2(
    final long x0,
    final long y0,
    final long x1,
    final long y1)
  {
    final long x = x0 * x1;
    final long y = y0 * y1;
    return x + y;
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.core.dotproducts;

import com.io7m.junreachable.UnreachableCodeException;

/**
 * Functions for calculating dot products.
 */

public final class DotProductsInt
{
  private DotProductsInt()
  {
    throw new UnreachableCodeException();
  }

  /**
   * Calculate the dot product of
   * {@code (x0, y0, z0, w0)} and {@code (x1, y1, z1, w1)}.
   *
   * @param x0 The X component of the first vector
   * @param y0 The Y component of the first vector
   * @param z0 The Z component of the first vector
   * @param w0 The W component of the first vector
   * @param x1 The X component of the second vector
   * @param y1 The Y component of the second vector
   * @param z1 The Z component of the second vector
   * @param w1 The W component of the second vector
   *
   * @return The dot product
   */

  public static int dotProduct4(
    final int x0,
    final int y0,
    final int z0,
    final int w0,
    final int x1,
    final int y1,
    final int z1,
    final int w1)
  {
    final int x = x0 * x1;
    final int y = y0 * y1;
    final int z = z0 * z1;
    final int w = w0 * w1;
    return x + y + z + w;
  }

  /**
   * Calculate the dot product of
   * {@code (x0, y0, z0)} and {@code (x1, y1, z1)}.
   *
   * @param x0 The X component of the first vector
   * @param y0 The Y component of the first vector
   * @param z0 The Z component of the first vector
   * @param x1 The X component of the second vector
   * @param y1 The Y component of the second vector
   * @param z1 The Z component of the second vector
   *
   * @return The dot product
   */

  public static int dotProduct3(
    final int x0,
    final int y0,
    final int z0,
    final int x1,
    final int y1,
    final int z1)
  {
    final int x = x0 * x1;
    final int y = y0 * y1;
    final int z = z0 * z1;
    return x + y + z;
  }

  /**
   * Calculate the dot product of {@code (x0, y0)} and {@code (x1, y1)}.
   *
   * @param x0 The X component of the first vector
   * @param y0 The Y component of the first vector
   * @param x1 The X component of the second vector
   * @param y1 The Y component of the second vector
   *
   * @return The dot product
   */

  public static int dotProduct2(
    final int x0,
    final int y0,
    final int x1,
    final int y1)
  {
    final int x = x0 * x1;
    final int y = y0 * y1;
    return x + y;
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;
import com.io7m.jtensors.core.unparameterized.matrices.Matrix4x4D;
import com.io7m.jtensors.core.unparameterized.matrices.Matrix4x4F;

import java.nio.ByteBuffer;

/**
 *
A storage matrix.

 *
Storage component type: {@code float}

 *
Storage component count: {@code 4x4}

 */

public final class MatrixByteBuffered4x4s32
  extends TensorByteBufferedFloating32
  implements MatrixByteBuffered4x4Type
{
  private MatrixByteBuffered4x4s32(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static MatrixByteBuffered4x4s32 createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new MatrixByteBuffered4x4s32(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 4 * 4;
  }

  @Override
  public double r0c0()
  {
    return this.getValue(ColumnMajor.index4x4(0, 0));
  }

  @Override
  public double r0c1()
  {
    return this.getValue(ColumnMajor.index4x4(0, 1));
  }

  @Override
  public double r0c2()
  {
    return this.getValue(ColumnMajor.index4x4(0, 2));
  }

  @Override
  public double r0c3()
  {
    return this.getValue(ColumnMajor.index4x4(0, 3));
  }

  @Override
  public double r1c0()
  {
    return this.getValue(ColumnMajor.index4x4(1, 0));
  }

  @Override
  public double r1c1()
  {
    return this.getValue(ColumnMajor.index4x4(1, 1));
  }

  @Override
  public double r1c2()
  {
    return this.getValue(ColumnMajor.index4x4(1, 2));
  }

  @Override
  public double r1c3()
  {
    return this.getValue(ColumnMajor.index4x4(1, 3));
  }

  @Override
  public double r2c0()
  {
    return this.getValue(ColumnMajor.index4x4(2, 0));
  }

  @Override
  public double r2c1()
  {
    return this.getValue(ColumnMajor.index4x4(2, 1));
  }

  @Override
  public double r2c2()
  {
    return this.getValue(ColumnMajor.index4x4(2, 2));
  }

  @Override
  public double r2c3()
  {
    return this.getValue(ColumnMajor.index4x4(2, 3));
  }

  @Override
  public double r3c0()
  {
    return this.getValue(ColumnMajor.index4x4(3, 0));
  }

  @Override
  public double r3c1()
  {
    return this.getValue(ColumnMajor.index4x4(3, 1));
  }

  @Override
  public double r3c2()
  {
    return this.getValue(ColumnMajor.index4x4(3, 2));
  }

  @Override
  public double r3c3()
  {
    return this.getValue(ColumnMajor.index4x4(3, 3));
  }

  @Override
  public void setMatrix4x4D(final Matrix4x4D m)
  {
    this.putValue(ColumnMajor.index4x4(0, 0), m.r0c0());
    this.putValue(ColumnMajor.index4x4(0, 1), m.r0c1());
    this.putValue(ColumnMajor.index4x4(0, 2), m.r0c2());
    this.putValue(ColumnMajor.index4x4(0, 3), m.r0c3());

    this.putValue(ColumnMajor.index4x4(1, 0), m.r1c0());
    this.putValue(ColumnMajor.index4x4(1, 1), m.r1c1());
    this.putValue(ColumnMajor.index4x4(1, 2), m.r1c2());
    this.putValue(ColumnMajor.index4x4(1, 3), m.r1c3());

    this.putValue(ColumnMajor.index4x4(2, 0), m.r2c0());
    this.putValue(ColumnMajor.index4x4(2, 1), m.r2c1());
    this.putValue(ColumnMajor.index4x4(2, 2), m.r2c2());
    this.putValue(ColumnMajor.index4x4(2, 3), m.r2c3());

    this.putValue(ColumnMajor.index4x4(3, 0), m.r3c0());
    this.putValue(ColumnMajor.index4x4(3, 1), m.r3c1());
    this.putValue(ColumnMajor.index4x4(3, 2), m.r3c2());
    this.putValue(ColumnMajor.index4x4(3, 3), m.r3c3());
  }

  @Override
  public void setMatrix4x4F(final Matrix4x4F m)
  {
    this.putValue(ColumnMajor.index4x4(0, 0), (double) m.r0c0());
    this.putValue(ColumnMajor.index4x4(0, 1), (double) m.r0c1());
    this.putValue(ColumnMajor.index4x4(0, 2), (double) m.r0c2());
    this.putValue(ColumnMajor.index4x4(0, 3), (double) m.r0c3());

    this.putValue(ColumnMajor.index4x4(1, 0), (double) m.r1c0());
    this.putValue(ColumnMajor.index4x4(1, 1), (double) m.r1c1());
    this.putValue(ColumnMajor.index4x4(1, 2), (double) m.r1c2());
    this.putValue(ColumnMajor.index4x4(1, 3), (double) m.r1c3());

    this.putValue(ColumnMajor.index4x4(2, 0), (double) m.r2c0());
    this.putValue(ColumnMajor.index4x4(2, 1), (double) m.r2c1());
    this.putValue(ColumnMajor.index4x4(2, 2), (double) m.r2c2());
    this.putValue(ColumnMajor.index4x4(2, 3), (double) m.r2c3());

    this.putValue(ColumnMajor.index4x4(3, 0), (double) m.r3c0());
    this.putValue(ColumnMajor.index4x4(3, 1), (double) m.r3c1());
    this.putValue(ColumnMajor.index4x4(3, 2), (double) m.r3c2());
    this.putValue(ColumnMajor.index4x4(3, 3), (double) m.r3c3());
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.core.dotproducts;

import com.io7m.junreachable.UnreachableCodeException;

/**
 * Functions for calculating dot products.
 */

public final class DotProductsDouble
{
  private DotProductsDouble()
  {
    throw new UnreachableCodeException();
  }

  /**
   * Calculate the dot product of
   * {@code (x0, y0, z0, w0)} and {@code (x1, y1, z1, w1)}.
   *
   * @param x0 The X component of the first vector
   * @param y0 The Y component of the first vector
   * @param z0 The Z component of the first vector
   * @param w0 The W component of the first vector
   * @param x1 The X component of the second vector
   * @param y1 The Y component of the second vector
   * @param z1 The Z component of the second vector
   * @param w1 The W component of the second vector
   *
   * @return The dot product
   */

  public static double dotProduct4(
    final double x0,
    final double y0,
    final double z0,
    final double w0,
    final double x1,
    final double y1,
    final double z1,
    final double w1)
  {
    final double x = x0 * x1;
    final double y = y0 * y1;
    final double z = z0 * z1;
    final double w = w0 * w1;
    return x + y + z + w;
  }

  /**
   * Calculate the dot product of
   * {@code (x0, y0, z0)} and {@code (x1, y1, z1)}.
   *
   * @param x0 The X component of the first vector
   * @param y0 The Y component of the first vector
   * @param z0 The Z component of the first vector
   * @param x1 The X component of the second vector
   * @param y1 The Y component of the second vector
   * @param z1 The Z component of the second vector
   *
   * @return The dot product
   */

  public static double dotProduct3(
    final double x0,
    final double y0,
    final double z0,
    final double x1,
    final double y1,
    final double z1)
  {
    final double x = x0 * x1;
    final double y = y0 * y1;
    final double z = z0 * z1;
    return x + y + z;
  }

  /**
   * Calculate the dot product of {@code (x0, y0)} and {@code (x1, y1)}.
   *
   * @param x0 The X component of the first vector
   * @param y0 The Y component of the first vector
   * @param x1 The X component of the second vector
   * @param y1 The Y component of the second vector
   *
   * @return The dot product
   */

  public static double dotProduct2(
    final double x0,
    final double y0,
    final double x1,
    final double y1)
  {
    final double x = x0 * x1;
    final double y = y0 * y1;
    return x + y;
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code long}

 *
Storage component count: {@code 4}

 */

public final class VectorByteBufferedIntegral4s64
  extends TensorByteBufferedIntegral64
  implements VectorByteBufferedIntegral4Type
{
  private VectorByteBufferedIntegral4s64(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static VectorByteBufferedIntegral4s64 createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new VectorByteBufferedIntegral4s64(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 4;
  }

  @Override
  public long x()
  {
    return this.getValue(0);
  }

  @Override
  public long y()
  {
    return this.getValue(1);
  }

  @Override
  public long z()
  {
    return this.getValue(2);
  }

  @Override
  public long w()
  {
    return this.getValue(3);
  }

  @Override
  public void setX(final long x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final long y)
  {
    this.putValue(1, y);
  }

  @Override
  public void setZ(final long z)
  {
    this.putValue(2, z);
  }

  @Override
  public void setW(final long w)
  {
    this.putValue(3, w);
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code double}

 *
Storage component count: {@code 3}

 */

public final class VectorByteBufferedFloating3s64
  extends TensorByteBufferedFloating64
  implements VectorByteBufferedFloating3Type
{
  private VectorByteBufferedFloating3s64(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static VectorByteBufferedFloating3s64 createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new VectorByteBufferedFloating3s64(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 3;
  }

  @Override
  public double x()
  {
    return this.getValue(0);
  }

  @Override
  public double y()
  {
    return this.getValue(1);
  }

  @Override
  public double z()
  {
    return this.getValue(2);
  }

  @Override
  public void setX(final double x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final double y)
  {
    this.putValue(1, y);
  }

  @Override
  public void setZ(final double z)
  {
    this.putValue(2, z);
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code byte}

 *
Storage component count: {@code 3}

 *
 * @param <T> A phantom type parameter
 */

public final class PVectorByteBufferedIntegral3s8<T>
  extends TensorByteBufferedIntegral8
  implements PVectorByteBufferedIntegral3Type<T>
{
  private PVectorByteBufferedIntegral3s8(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param <T>    A phantom type parameter
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static <T> PVectorByteBufferedIntegral3s8<T> createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new PVectorByteBufferedIntegral3s8<>(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 3;
  }

  @Override
  public long x()
  {
    return this.getValue(0);
  }

  @Override
  public long y()
  {
    return this.getValue(1);
  }

  @Override
  public long z()
  {
    return this.getValue(2);
  }

  @Override
  public void setX(final long x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final long y)
  {
    this.putValue(1, y);
  }

  @Override
  public void setZ(final long z)
  {
    this.putValue(2, z);
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code binary16}

 *
Storage component count: {@code 2}

 *
 * @param <T> A phantom type parameter
 */

public final class PVectorByteBufferedFloating2s16<T>
  extends TensorByteBufferedFloating16
  implements PVectorByteBufferedFloating2Type<T>
{
  private PVectorByteBufferedFloating2s16(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param <T>    A phantom type parameter
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static <T> PVectorByteBufferedFloating2s16<T> createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new PVectorByteBufferedFloating2s16<>(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 2;
  }

  @Override
  public double x()
  {
    return this.getValue(0);
  }

  @Override
  public double y()
  {
    return this.getValue(1);
  }

  @Override
  public void setX(final double x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final double y)
  {
    this.putValue(1, y);
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code double}

 *
Storage component count: {@code 4}

 *
 * @param <T> A phantom type parameter
 */

public final class PVectorByteBufferedFloating4s64<T>
  extends TensorByteBufferedFloating64
  implements PVectorByteBufferedFloating4Type<T>
{
  private PVectorByteBufferedFloating4s64(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param <T>    A phantom type parameter
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static <T> PVectorByteBufferedFloating4s64<T> createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new PVectorByteBufferedFloating4s64<>(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 4;
  }

  @Override
  public double x()
  {
    return this.getValue(0);
  }

  @Override
  public double y()
  {
    return this.getValue(1);
  }

  @Override
  public double z()
  {
    return this.getValue(2);
  }

  @Override
  public double w()
  {
    return this.getValue(3);
  }

  @Override
  public void setX(final double x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final double y)
  {
    this.putValue(1, y);
  }

  @Override
  public void setZ(final double z)
  {
    this.putValue(2, z);
  }

  @Override
  public void setW(final double w)
  {
    this.putValue(3, w);
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;
import com.io7m.jtensors.core.parameterized.matrices.PMatrix3x3D;
import com.io7m.jtensors.core.parameterized.matrices.PMatrix3x3F;
import com.io7m.jtensors.core.unparameterized.matrices.Matrix3x3D;
import com.io7m.jtensors.core.unparameterized.matrices.Matrix3x3F;

import java.nio.ByteBuffer;

/**
 *
A storage matrix.

 *
Storage component type: {@code double}

 *
Storage component count: {@code 3x3}

 *
 * @param  A phantom type parameter (possibly representing a source
 *            coordinate system)
 * @param  A phantom type parameter (possibly representing a target
 *            coordinate system)
 */

public final class PMatrixByteBuffered3x3s16
  extends TensorByteBufferedFloating16
  implements PMatrixByteBuffered3x3Type
{
  private PMatrixByteBuffered3x3s16(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param     A phantom type parameter (possibly representing a source
   *               coordinate system)
   * @param     A phantom type parameter (possibly representing a target
   *               coordinate system)
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static  PMatrixByteBuffered3x3s16 createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new PMatrixByteBuffered3x3s16<>(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 3 * 3;
  }

  @Override
  public double r0c0()
  {
    return this.getValue(ColumnMajor.index3x3(0, 0));
  }

  @Override
  public double r0c1()
  {
    return this.getValue(ColumnMajor.index3x3(0, 1));
  }

  @Override
  public double r0c2()
  {
    return this.getValue(ColumnMajor.index3x3(0, 2));
  }

  @Override
  public double r1c0()
  {
    return this.getValue(ColumnMajor.index3x3(1, 0));
  }

  @Override
  public double r1c1()
  {
    return this.getValue(ColumnMajor.index3x3(1, 1));
  }

  @Override
  public double r1c2()
  {
    return this.getValue(ColumnMajor.index3x3(1, 2));
  }

  @Override
  public double r2c0()
  {
    return this.getValue(ColumnMajor.index3x3(2, 0));
  }

  @Override
  public double r2c1()
  {
    return this.getValue(ColumnMajor.index3x3(2, 1));
  }

  @Override
  public double r2c2()
  {
    return this.getValue(ColumnMajor.index3x3(2, 2));
  }

  @Override
  public void setPMatrix3x3D(final PMatrix3x3D m)
  {
    this.putValue(ColumnMajor.index3x3(0, 0), m.r0c0());
    this.putValue(ColumnMajor.index3x3(0, 1), m.r0c1());
    this.putValue(ColumnMajor.index3x3(0, 2), m.r0c2());

    this.putValue(ColumnMajor.index3x3(1, 0), m.r1c0());
    this.putValue(ColumnMajor.index3x3(1, 1), m.r1c1());
    this.putValue(ColumnMajor.index3x3(1, 2), m.r1c2());

    this.putValue(ColumnMajor.index3x3(2, 0), m.r2c0());
    this.putValue(ColumnMajor.index3x3(2, 1), m.r2c1());
    this.putValue(ColumnMajor.index3x3(2, 2), m.r2c2());
  }

  @Override
  public void setPMatrix3x3F(final PMatrix3x3F m)
  {
    this.putValue(ColumnMajor.index3x3(0, 0), (double) m.r0c0());
    this.putValue(ColumnMajor.index3x3(0, 1), (double) m.r0c1());
    this.putValue(ColumnMajor.index3x3(0, 2), (double) m.r0c2());

    this.putValue(ColumnMajor.index3x3(1, 0), (double) m.r1c0());
    this.putValue(ColumnMajor.index3x3(1, 1), (double) m.r1c1());
    this.putValue(ColumnMajor.index3x3(1, 2), (double) m.r1c2());

    this.putValue(ColumnMajor.index3x3(2, 0), (double) m.r2c0());
    this.putValue(ColumnMajor.index3x3(2, 1), (double) m.r2c1());
    this.putValue(ColumnMajor.index3x3(2, 2), (double) m.r2c2());
  }

  @Override
  public void setMatrix3x3D(final Matrix3x3D m)
  {
    this.putValue(ColumnMajor.index3x3(0, 0), m.r0c0());
    this.putValue(ColumnMajor.index3x3(0, 1), m.r0c1());
    this.putValue(ColumnMajor.index3x3(0, 2), m.r0c2());

    this.putValue(ColumnMajor.index3x3(1, 0), m.r1c0());
    this.putValue(ColumnMajor.index3x3(1, 1), m.r1c1());
    this.putValue(ColumnMajor.index3x3(1, 2), m.r1c2());

    this.putValue(ColumnMajor.index3x3(2, 0), m.r2c0());
    this.putValue(ColumnMajor.index3x3(2, 1), m.r2c1());
    this.putValue(ColumnMajor.index3x3(2, 2), m.r2c2());
  }

  @Override
  public void setMatrix3x3F(final Matrix3x3F m)
  {
    this.putValue(ColumnMajor.index3x3(0, 0), (double) m.r0c0());
    this.putValue(ColumnMajor.index3x3(0, 1), (double) m.r0c1());
    this.putValue(ColumnMajor.index3x3(0, 2), (double) m.r0c2());

    this.putValue(ColumnMajor.index3x3(1, 0), (double) m.r1c0());
    this.putValue(ColumnMajor.index3x3(1, 1), (double) m.r1c1());
    this.putValue(ColumnMajor.index3x3(1, 2), (double) m.r1c2());

    this.putValue(ColumnMajor.index3x3(2, 0), (double) m.r2c0());
    this.putValue(ColumnMajor.index3x3(2, 1), (double) m.r2c1());
    this.putValue(ColumnMajor.index3x3(2, 2), (double) m.r2c2());
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code binary16}

 *
Storage component count: {@code 3}

 */

public final class VectorByteBufferedFloating3s16
  extends TensorByteBufferedFloating16
  implements VectorByteBufferedFloating3Type
{
  private VectorByteBufferedFloating3s16(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static VectorByteBufferedFloating3s16 createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new VectorByteBufferedFloating3s16(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 3;
  }

  @Override
  public double x()
  {
    return this.getValue(0);
  }

  @Override
  public double y()
  {
    return this.getValue(1);
  }

  @Override
  public double z()
  {
    return this.getValue(2);
  }

  @Override
  public void setX(final double x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final double y)
  {
    this.putValue(1, y);
  }

  @Override
  public void setZ(final double z)
  {
    this.putValue(2, z);
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code byte}

 *
Storage component count: {@code 4}

 */

public final class VectorByteBufferedIntegral4s8
  extends TensorByteBufferedIntegral8
  implements VectorByteBufferedIntegral4Type
{
  private VectorByteBufferedIntegral4s8(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static VectorByteBufferedIntegral4s8 createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new VectorByteBufferedIntegral4s8(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 4;
  }

  @Override
  public long x()
  {
    return this.getValue(0);
  }

  @Override
  public long y()
  {
    return this.getValue(1);
  }

  @Override
  public long z()
  {
    return this.getValue(2);
  }

  @Override
  public long w()
  {
    return this.getValue(3);
  }

  @Override
  public void setX(final long x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final long y)
  {
    this.putValue(1, y);
  }

  @Override
  public void setZ(final long z)
  {
    this.putValue(2, z);
  }

  @Override
  public void setW(final long w)
  {
    this.putValue(3, w);
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.generators;

import java.util.Objects;
import com.io7m.jtensors.core.unparameterized.vectors.Vector3F;
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;

/**
 * A vector generator.
 */

public final class Vector3FGenerator implements Generator<Vector3F>
{
  private final Generator<Double> gen;

  /**
   * Construct a generator.
   *
   * @param in_gen A component generator
   */

  public Vector3FGenerator(
    final Generator<Double> in_gen)
  {
    this.gen = Objects.requireNonNull(in_gen, "Generator");
  }

  /**
   * Create a generator initialized with a default component generator.
   *
   * @return A generator
   */

  public static Generator<Vector3F> create()
  {
    return new Vector3FGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_LARGE_FLOAT_LOWER,
      GeneratorConstants.BOUND_LARGE_FLOAT_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-65536.0, 65536.0]}.
   *
   * @return A generator
   */

  public static Generator<Vector3F> createSmall()
  {
    return new Vector3FGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_SMALL_FLOAT_LOWER,
      GeneratorConstants.BOUND_SMALL_FLOAT_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-1.0, 1.0]}.
   *
   * @return A generator
   */

  public static Generator<Vector3F> createNormal()
  {
    return new Vector3FGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_NORMAL_FLOAT_LOWER,
      GeneratorConstants.BOUND_NORMAL_FLOAT_UPPER
    ));
  }

  @Override
  public Vector3F next()
  {
    return Vector3F.of(
      this.gen.next().floatValue(),
      this.gen.next().floatValue(),
      this.gen.next().floatValue());
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code short}

 *
Storage component count: {@code 2}

 */

public final class VectorByteBufferedIntegral2s16
  extends TensorByteBufferedIntegral16
  implements VectorByteBufferedIntegral2Type
{
  private VectorByteBufferedIntegral2s16(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static VectorByteBufferedIntegral2s16 createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new VectorByteBufferedIntegral2s16(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 2;
  }

  @Override
  public long x()
  {
    return this.getValue(0);
  }

  @Override
  public long y()
  {
    return this.getValue(1);
  }

  @Override
  public void setX(final long x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final long y)
  {
    this.putValue(1, y);
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.generators;

import java.util.Objects;
import com.io7m.jtensors.core.parameterized.vectors.PVector3F;
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;

/**
 * A vector generator.
 *
 * @param <T>
 */

public final class PVector3FGenerator<T> implements Generator<PVector3F<T>>
{
  private final Generator<Double> gen;

  /**
   * Construct a generator.
   *
   * @param in_gen A component generator
   */

  public PVector3FGenerator(
    final Generator<Double> in_gen)
  {
    this.gen = Objects.requireNonNull(in_gen, "Generator");
  }

  /**
   * Create a generator initialized with a default component generator.
   *
   * @param <T> A phantom type parameter
   *
   * @return A generator
   */

  public static <T> Generator<PVector3F<T>> create()
  {
    return new PVector3FGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_LARGE_FLOAT_LOWER,
      GeneratorConstants.BOUND_LARGE_FLOAT_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-65536.0, 65536.0]}.
   *
   * @param <T> A phantom type parameter
   *
   * @return A generator
   */

  public static <T> Generator<PVector3F<T>> createSmall()
  {
    return new PVector3FGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_SMALL_FLOAT_LOWER,
      GeneratorConstants.BOUND_SMALL_FLOAT_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-1.0, 1.0]}.
   *
   * @param <T> A phantom type parameter
   *
   * @return A generator
   */

  public static <T> Generator<PVector3F<T>> createNormal()
  {
    return new PVector3FGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_NORMAL_FLOAT_LOWER,
      GeneratorConstants.BOUND_NORMAL_FLOAT_UPPER
    ));
  }

  @Override
  public PVector3F<T> next()
  {
    return PVector3F.of(
      this.gen.next().floatValue(),
      this.gen.next().floatValue(),
      this.gen.next().floatValue());
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;
import com.io7m.jtensors.core.unparameterized.matrices.Matrix3x3D;
import com.io7m.jtensors.core.unparameterized.matrices.Matrix3x3F;

import java.nio.ByteBuffer;

/**
 *
A storage matrix.

 *
Storage component type: {@code double}

 *
Storage component count: {@code 3x3}

 */

public final class MatrixByteBuffered3x3s64
  extends TensorByteBufferedFloating64
  implements MatrixByteBuffered3x3Type
{
  private MatrixByteBuffered3x3s64(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static MatrixByteBuffered3x3s64 createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new MatrixByteBuffered3x3s64(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 3 * 3;
  }

  @Override
  public double r0c0()
  {
    return this.getValue(ColumnMajor.index3x3(0, 0));
  }

  @Override
  public double r0c1()
  {
    return this.getValue(ColumnMajor.index3x3(0, 1));
  }

  @Override
  public double r0c2()
  {
    return this.getValue(ColumnMajor.index3x3(0, 2));
  }

  @Override
  public double r1c0()
  {
    return this.getValue(ColumnMajor.index3x3(1, 0));
  }

  @Override
  public double r1c1()
  {
    return this.getValue(ColumnMajor.index3x3(1, 1));
  }

  @Override
  public double r1c2()
  {
    return this.getValue(ColumnMajor.index3x3(1, 2));
  }

  @Override
  public double r2c0()
  {
    return this.getValue(ColumnMajor.index3x3(2, 0));
  }

  @Override
  public double r2c1()
  {
    return this.getValue(ColumnMajor.index3x3(2, 1));
  }

  @Override
  public double r2c2()
  {
    return this.getValue(ColumnMajor.index3x3(2, 2));
  }

  @Override
  public void setMatrix3x3D(final Matrix3x3D m)
  {
    this.putValue(ColumnMajor.index3x3(0, 0), m.r0c0());
    this.putValue(ColumnMajor.index3x3(0, 1), m.r0c1());
    this.putValue(ColumnMajor.index3x3(0, 2), m.r0c2());

    this.putValue(ColumnMajor.index3x3(1, 0), m.r1c0());
    this.putValue(ColumnMajor.index3x3(1, 1), m.r1c1());
    this.putValue(ColumnMajor.index3x3(1, 2), m.r1c2());

    this.putValue(ColumnMajor.index3x3(2, 0), m.r2c0());
    this.putValue(ColumnMajor.index3x3(2, 1), m.r2c1());
    this.putValue(ColumnMajor.index3x3(2, 2), m.r2c2());
  }

  @Override
  public void setMatrix3x3F(final Matrix3x3F m)
  {
    this.putValue(ColumnMajor.index3x3(0, 0), (double) m.r0c0());
    this.putValue(ColumnMajor.index3x3(0, 1), (double) m.r0c1());
    this.putValue(ColumnMajor.index3x3(0, 2), (double) m.r0c2());

    this.putValue(ColumnMajor.index3x3(1, 0), (double) m.r1c0());
    this.putValue(ColumnMajor.index3x3(1, 1), (double) m.r1c1());
    this.putValue(ColumnMajor.index3x3(1, 2), (double) m.r1c2());

    this.putValue(ColumnMajor.index3x3(2, 0), (double) m.r2c0());
    this.putValue(ColumnMajor.index3x3(2, 1), (double) m.r2c1());
    this.putValue(ColumnMajor.index3x3(2, 2), (double) m.r2c2());
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code long}

 *
Storage component count: {@code 3}

 *
 * @param <T> A phantom type parameter
 */

public final class PVectorByteBufferedIntegral3s64<T>
  extends TensorByteBufferedIntegral64
  implements PVectorByteBufferedIntegral3Type<T>
{
  private PVectorByteBufferedIntegral3s64(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param <T>    A phantom type parameter
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static <T> PVectorByteBufferedIntegral3s64<T> createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new PVectorByteBufferedIntegral3s64<>(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 3;
  }

  @Override
  public long x()
  {
    return this.getValue(0);
  }

  @Override
  public long y()
  {
    return this.getValue(1);
  }

  @Override
  public long z()
  {
    return this.getValue(2);
  }

  @Override
  public void setX(final long x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final long y)
  {
    this.putValue(1, y);
  }

  @Override
  public void setZ(final long z)
  {
    this.putValue(2, z);
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code float}

 *
Storage component count: {@code 4}

 *
 * @param <T> A phantom type parameter
 */

public final class PVectorByteBufferedFloating4s32<T>
  extends TensorByteBufferedFloating32
  implements PVectorByteBufferedFloating4Type<T>
{
  private PVectorByteBufferedFloating4s32(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param <T>    A phantom type parameter
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static <T> PVectorByteBufferedFloating4s32<T> createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new PVectorByteBufferedFloating4s32<>(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 4;
  }

  @Override
  public double x()
  {
    return this.getValue(0);
  }

  @Override
  public double y()
  {
    return this.getValue(1);
  }

  @Override
  public double z()
  {
    return this.getValue(2);
  }

  @Override
  public double w()
  {
    return this.getValue(3);
  }

  @Override
  public void setX(final double x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final double y)
  {
    this.putValue(1, y);
  }

  @Override
  public void setZ(final double z)
  {
    this.putValue(2, z);
  }

  @Override
  public void setW(final double w)
  {
    this.putValue(3, w);
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.generators;

import java.util.Objects;
import com.io7m.jtensors.core.unparameterized.vectors.Vector4D;
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;

/**
 * A vector generator.
 */

public final class Vector4DGenerator implements Generator<Vector4D>
{
  private final Generator<Double> gen;

  /**
   * Construct a generator.
   *
   * @param in_gen A component generator
   */

  public Vector4DGenerator(
    final Generator<Double> in_gen)
  {
    this.gen = Objects.requireNonNull(in_gen, "Generator");
  }

  /**
   * Create a generator initialized with a default component generator.
   *
   * @return A generator
   */

  public static Generator<Vector4D> create()
  {
    return new Vector4DGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_LARGE_DOUBLE_LOWER,
      GeneratorConstants.BOUND_LARGE_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-65536.0, 65536.0]}.
   *
   * @return A generator
   */

  public static Generator<Vector4D> createSmall()
  {
    return new Vector4DGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_SMALL_DOUBLE_LOWER,
      GeneratorConstants.BOUND_SMALL_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-1.0, 1.0]}.
   *
   * @return A generator
   */

  public static Generator<Vector4D> createNormal()
  {
    return new Vector4DGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_NORMAL_DOUBLE_LOWER,
      GeneratorConstants.BOUND_NORMAL_DOUBLE_UPPER
    ));
  }

  @Override
  public Vector4D next()
  {
    return Vector4D.of(
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue());
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code binary16}

 *
Storage component count: {@code 3}

 *
 * @param <T> A phantom type parameter
 */

public final class PVectorByteBufferedFloating3s16<T>
  extends TensorByteBufferedFloating16
  implements PVectorByteBufferedFloating3Type<T>
{
  private PVectorByteBufferedFloating3s16(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param <T>    A phantom type parameter
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static <T> PVectorByteBufferedFloating3s16<T> createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new PVectorByteBufferedFloating3s16<>(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 3;
  }

  @Override
  public double x()
  {
    return this.getValue(0);
  }

  @Override
  public double y()
  {
    return this.getValue(1);
  }

  @Override
  public double z()
  {
    return this.getValue(2);
  }

  @Override
  public void setX(final double x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final double y)
  {
    this.putValue(1, y);
  }

  @Override
  public void setZ(final double z)
  {
    this.putValue(2, z);
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.generators;

import java.util.Objects;
import com.io7m.jtensors.core.parameterized.matrices.PMatrix3x3D;
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;

/**
 * A matrix generator.
 *
 * @param <A> A phantom type parameter (possibly representing a source
 *            coordinate system)
 * @param <B> A phantom type parameter (possibly representing a target
 *            coordinate system)
 */

public final class PMatrix3x3DGenerator<A, B> implements Generator<PMatrix3x3D<A, B>>
{
  private final Generator<Double> gen;

  /**
   * Construct a generator.
   *
   * @param in_gen A component generator
   */

  public PMatrix3x3DGenerator(
    final Generator<Double> in_gen)
  {
    this.gen = Objects.requireNonNull(in_gen, "Generator");
  }

  /**
   * Create a generator initialized with a default component generator.
   *
   * @param <A> A phantom type parameter (possibly representing a source
   *            coordinate system)
   * @param <B> A phantom type parameter (possibly representing a target
   *            coordinate system)
   *
   * @return A generator
   */

  public static <A, B> Generator<PMatrix3x3D<A, B>> create()
  {
    return new PMatrix3x3DGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_LARGE_DOUBLE_LOWER,
      GeneratorConstants.BOUND_LARGE_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that only
   * produces values in the range {@code [-1.0, 1.0]}.
   *
   * @param <A> A phantom type parameter (possibly representing a source
   *            coordinate system)
   * @param <B> A phantom type parameter (possibly representing a target
   *            coordinate system)
   *
   * @return A generator
   */

  public static <A, B> Generator<PMatrix3x3D<A, B>> createNormal()
  {
    return new PMatrix3x3DGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_NORMAL_DOUBLE_LOWER,
      GeneratorConstants.BOUND_NORMAL_DOUBLE_UPPER
    ));
  }

  @Override
  public PMatrix3x3D<A, B> next()
  {
    return PMatrix3x3D.of(
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue());
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.generators;

import java.util.Objects;
import com.io7m.jtensors.core.parameterized.vectors.PVector2F;
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;

/**
 * A vector generator.
 *
 * @param <T>
 */

public final class PVector2FGenerator<T> implements Generator<PVector2F<T>>
{
  private final Generator<Double> gen;

  /**
   * Construct a generator.
   *
   * @param in_gen A component generator
   */

  public PVector2FGenerator(
    final Generator<Double> in_gen)
  {
    this.gen = Objects.requireNonNull(in_gen, "Generator");
  }

  /**
   * Create a generator initialized with a default component generator.
   *
   * @param <T> A phantom type parameter
   *
   * @return A generator
   */

  public static <T> Generator<PVector2F<T>> create()
  {
    return new PVector2FGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_LARGE_FLOAT_LOWER,
      GeneratorConstants.BOUND_LARGE_FLOAT_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-65536.0, 65536.0]}.
   *
   * @param <T> A phantom type parameter
   *
   * @return A generator
   */

  public static <T> Generator<PVector2F<T>> createSmall()
  {
    return new PVector2FGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_SMALL_FLOAT_LOWER,
      GeneratorConstants.BOUND_SMALL_FLOAT_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-1.0, 1.0]}.
   *
   * @param <T> A phantom type parameter
   *
   * @return A generator
   */

  public static <T> Generator<PVector2F<T>> createNormal()
  {
    return new PVector2FGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_NORMAL_FLOAT_LOWER,
      GeneratorConstants.BOUND_NORMAL_FLOAT_UPPER
    ));
  }

  @Override
  public PVector2F<T> next()
  {
    return PVector2F.of(
      this.gen.next().floatValue(),
      this.gen.next().floatValue());
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.generators;

import java.util.Objects;
import com.io7m.jtensors.core.parameterized.matrices.PMatrix2x2D;
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;

/**
 * A matrix generator.
 *
 * @param <A> A phantom type parameter (possibly representing a source
 *            coordinate system)
 * @param <B> A phantom type parameter (possibly representing a target
 *            coordinate system)
 */

public final class PMatrix2x2DGenerator<A, B> implements Generator<PMatrix2x2D<A, B>>
{
  private final Generator<Double> gen;

  /**
   * Construct a generator.
   *
   * @param in_gen A component generator
   */

  public PMatrix2x2DGenerator(
    final Generator<Double> in_gen)
  {
    this.gen = Objects.requireNonNull(in_gen, "Generator");
  }

  /**
   * Create a generator initialized with a default component generator.
   *
   * @param <A> A phantom type parameter (possibly representing a source
   *            coordinate system)
   * @param <B> A phantom type parameter (possibly representing a target
   *            coordinate system)
   *
   * @return A generator
   */

  public static <A, B> Generator<PMatrix2x2D<A, B>> create()
  {
    return new PMatrix2x2DGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_LARGE_DOUBLE_LOWER,
      GeneratorConstants.BOUND_LARGE_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that only
   * produces values in the range {@code [-1.0, 1.0]}.
   *
   * @param <A> A phantom type parameter (possibly representing a source
   *            coordinate system)
   * @param <B> A phantom type parameter (possibly representing a target
   *            coordinate system)
   *
   * @return A generator
   */

  public static <A, B> Generator<PMatrix2x2D<A, B>> createNormal()
  {
    return new PMatrix2x2DGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_NORMAL_DOUBLE_LOWER,
      GeneratorConstants.BOUND_NORMAL_DOUBLE_UPPER
    ));
  }

  @Override
  public PMatrix2x2D<A, B> next()
  {
    return PMatrix2x2D.of(
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue());
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.generators;

import java.util.Objects;
import com.io7m.jtensors.core.unparameterized.vectors.Vector3D;
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;

/**
 * A vector generator.
 */

public final class Vector3DGenerator implements Generator<Vector3D>
{
  private final Generator<Double> gen;

  /**
   * Construct a generator.
   *
   * @param in_gen A component generator
   */

  public Vector3DGenerator(
    final Generator<Double> in_gen)
  {
    this.gen = Objects.requireNonNull(in_gen, "Generator");
  }

  /**
   * Create a generator initialized with a default component generator.
   *
   * @return A generator
   */

  public static Generator<Vector3D> create()
  {
    return new Vector3DGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_LARGE_DOUBLE_LOWER,
      GeneratorConstants.BOUND_LARGE_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-65536.0, 65536.0]}.
   *
   * @return A generator
   */

  public static Generator<Vector3D> createSmall()
  {
    return new Vector3DGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_SMALL_DOUBLE_LOWER,
      GeneratorConstants.BOUND_SMALL_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-1.0, 1.0]}.
   *
   * @return A generator
   */

  public static Generator<Vector3D> createNormal()
  {
    return new Vector3DGenerator(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_NORMAL_DOUBLE_LOWER,
      GeneratorConstants.BOUND_NORMAL_DOUBLE_UPPER
    ));
  }

  @Override
  public Vector3D next()
  {
    return Vector3D.of(
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue());
  }
}


/*
 * Copyright © 2017 <code@io7m.com> http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.generators;

import java.util.Objects;
import com.io7m.jtensors.core.parameterized.vectors.PVector4D;
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;

/**
 * A vector generator.
 *
 * @param <T>
 */

public final class PVector4DGenerator<T> implements Generator<PVector4D<T>>
{
  private final Generator<Double> gen;

  /**
   * Construct a generator.
   *
   * @param in_gen A component generator
   */

  public PVector4DGenerator(
    final Generator<Double> in_gen)
  {
    this.gen = Objects.requireNonNull(in_gen, "Generator");
  }

  /**
   * Create a generator initialized with a default component generator.
   *
   * @param <T> A phantom type parameter
   *
   * @return A generator
   */

  public static <T> Generator<PVector4D<T>> create()
  {
    return new PVector4DGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_LARGE_DOUBLE_LOWER,
      GeneratorConstants.BOUND_LARGE_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-(2 ^ 16), 2 ^ 16]}.
   *
   * @param <T> A phantom type parameter
   *
   * @return A generator
   */

  public static <T> Generator<PVector4D<T>> createSmall()
  {
    return new PVector4DGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_SMALL_DOUBLE_LOWER,
      GeneratorConstants.BOUND_SMALL_DOUBLE_UPPER
    ));
  }

  /**
   * Create a generator initialized with a default component generator that
   * produces values in the range {@code [-1.0, 1.0]}.
   *
   * @param <T> A phantom type parameter
   *
   * @return A generator
   */

  public static <T> Generator<PVector4D<T>> createNormal()
  {
    return new PVector4DGenerator<>(PrimitiveGenerators.doubles(
      GeneratorConstants.BOUND_NORMAL_DOUBLE_LOWER,
      GeneratorConstants.BOUND_NORMAL_DOUBLE_UPPER
    ));
  }

  @Override
  public PVector4D<T> next()
  {
    return PVector4D.of(
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue(),
      this.gen.next().doubleValue());
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code long}

 *
Storage component count: {@code 4}

 *
 * @param <T> A phantom type parameter
 */

public final class PVectorByteBufferedIntegral4s64<T>
  extends TensorByteBufferedIntegral64
  implements PVectorByteBufferedIntegral4Type<T>
{
  private PVectorByteBufferedIntegral4s64(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param <T>    A phantom type parameter
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static <T> PVectorByteBufferedIntegral4s64<T> createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new PVectorByteBufferedIntegral4s64<>(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 4;
  }

  @Override
  public long x()
  {
    return this.getValue(0);
  }

  @Override
  public long y()
  {
    return this.getValue(1);
  }

  @Override
  public long z()
  {
    return this.getValue(2);
  }

  @Override
  public long w()
  {
    return this.getValue(3);
  }

  @Override
  public void setX(final long x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final long y)
  {
    this.putValue(1, y);
  }

  @Override
  public void setZ(final long z)
  {
    this.putValue(2, z);
  }

  @Override
  public void setW(final long w)
  {
    this.putValue(3, w);
  }
}


/*
 * Copyright © 2017  http://io7m.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors.storage.bytebuffered;

import com.io7m.mutable.numbers.core.MutableLongType;

import java.nio.ByteBuffer;

/**
 *
A storage vector.

 *
Storage component type: {@code int}

 *
Storage component count: {@code 2}

 *
 * @param <T> A phantom type parameter
 */

public final class PVectorByteBufferedIntegral2s32<T>
  extends TensorByteBufferedIntegral32
  implements PVectorByteBufferedIntegral2Type<T>
{
  private PVectorByteBufferedIntegral2s32(
    final ByteBuffer in_buffer,
    final MutableLongType in_base,
    final int in_offset)
  {
    super(in_buffer, in_base, in_offset);
  }

  /**
   *
Return a new vector that is backed by the given byte buffer {@code
   * b}

   *
   *
The data for the instance will be taken from the data at the current
   * value of {@code base.get() + offset}, each time a field is requested or
   * set.

   *
   *
No initialization of the data is performed.

   *
   * @param <T>    A phantom type parameter
   * @param b      The byte buffer
   * @param base   The base address
   * @param offset A constant offset
   *
   * @return A new buffered vector
   */

  public static <T> PVectorByteBufferedIntegral2s32<T> createWithBase(
    final ByteBuffer b,
    final MutableLongType base,
    final int offset)
  {
    return new PVectorByteBufferedIntegral2s32<>(b, base, offset);
  }

  @Override
  protected int componentCount()
  {
    return 2;
  }

  @Override
  public long x()
  {
    return this.getValue(0);
  }

  @Override
  public long y()
  {
    return this.getValue(1);
  }

  @Override
  public void setX(final long x)
  {
    this.putValue(0, x);
  }

  @Override
  public void setY(final long y)
  {
    this.putValue(1, y);
  }
}