
org.ojalgo.array.operation.DOT Maven / Gradle / Ivy
/*
* Copyright 1997-2024 Optimatika
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.ojalgo.array.operation;
import java.math.BigDecimal;
import org.ojalgo.function.constant.BigMath;
import org.ojalgo.function.constant.PrimitiveMath;
import org.ojalgo.scalar.ComplexNumber;
import org.ojalgo.scalar.Scalar;
import org.ojalgo.structure.Access1D;
/**
* The ?dot routines perform a vector-vector reduction operation defined as Equation where xi and yi are
* elements of vectors x and y.
*
* @author apete
*/
public abstract class DOT implements ArrayOperation {
public static int THRESHOLD = 128;
public static double invoke(final Access1D> array1, final int offset1, final double[] array2, final int offset2, final int first, final int limit) {
double retVal = PrimitiveMath.ZERO;
for (int i = first; i < limit; i++) {
retVal += array1.doubleValue(offset1 + i) * array2[offset2 + i];
}
return retVal;
}
public static float invoke(final Access1D> array1, final int offset1, final float[] array2, final int offset2, final int first, final int limit) {
float retVal = 0F;
for (int i = first; i < limit; i++) {
retVal += array1.floatValue(offset1 + i) * array2[offset2 + i];
}
return retVal;
}
public static > N invoke(final Access1D array2, final int offset2, final N[] array1, final int offset1, final int first,
final int limit, final Scalar.Factory factory) {
return DOT.invoke(array1, offset1, array2, offset2, first, limit, factory);
}
public static BigDecimal invoke(final BigDecimal[] array1, final int offset1, final BigDecimal[] array2, final int offset2, final int first,
final int limit) {
BigDecimal retVal = BigMath.ZERO;
for (int i = first; i < limit; i++) {
retVal = retVal.add(array1[offset1 + i].multiply(array2[offset2 + i]));
}
return retVal;
}
public static ComplexNumber invoke(final ComplexNumber[] array1, final int offset1, final ComplexNumber[] array2, final int offset2, final int first,
final int limit) {
ComplexNumber retVal = ComplexNumber.ZERO;
for (int i = first; i < limit; i++) {
retVal = retVal.add(array1[offset1 + i].multiply(array2[offset2 + i]));
}
return retVal;
}
public static double invoke(final double[] array1, final int offset1, final Access1D> array2, final int offset2, final int first, final int limit) {
double retVal = PrimitiveMath.ZERO;
for (int i = first; i < limit; i++) {
retVal += array1[offset1 + i] * array2.doubleValue(offset2 + i);
}
return retVal;
}
public static double invoke(final double[] array1, final int offset1, final double[] array2, final int offset2, final int first, final int limit) {
return DOT.unrolled04(array1, offset1, array2, offset2, first, limit);
}
public static float invoke(final float[] array1, final int offset1, final Access1D> array2, final int offset2, final int first, final int limit) {
float retVal = 0F;
for (int i = first; i < limit; i++) {
retVal += array1[offset1 + i] * array2.floatValue(offset2 + i);
}
return retVal;
}
public static float invoke(final float[] array1, final int offset1, final float[] array2, final int offset2, final int first, final int limit) {
return DOT.unrolled04(array1, offset1, array2, offset2, first, limit);
}
public static > N invoke(final N[] array1, final int offset1, final Access1D array2, final int offset2, final int first,
final int limit, final Scalar.Factory factory) {
Scalar retVal = factory.zero();
for (int i = first; i < limit; i++) {
retVal = retVal.add(array1[offset1 + i].multiply(array2.get(offset2 + i)));
}
return retVal.get();
}
public static > N invoke(final N[] array1, final int offset1, final N[] array2, final int offset2, final int first, final int limit,
final Scalar.Factory factory) {
Scalar retVal = factory.zero();
for (int i = first; i < limit; i++) {
retVal = retVal.add(array1[offset1 + i].multiply(array2[offset2 + i]));
}
return retVal.get();
}
public static > N invokeG(final Access1D array1, final int offset1, final Access1D array2, final int offset2, final int first,
final int limit, final Scalar.Factory scalar) {
Scalar retVal = scalar.zero();
for (int i = first; i < limit; i++) {
retVal = retVal.add(array1.get(offset1 + i).multiply(array2.get(offset2 + i)));
}
return retVal.get();
}
public static double invokeP64(final Access1D> array1, final int offset1, final Access1D> array2, final int offset2, final int first, final int limit) {
double retVal = PrimitiveMath.ZERO;
for (int i = first; i < limit; i++) {
retVal += array1.doubleValue(offset1 + i) * array2.doubleValue(offset2 + i);
}
return retVal;
}
static double plain(final double[] array1, final int offset1, final double[] array2, final int offset2, final int first, final int limit) {
double retVal = 0F;
for (int i = first; i < limit; i++) {
retVal += array1[offset1 + i] * array2[offset2 + i];
}
return retVal;
}
static float plain(final float[] array1, final int offset1, final float[] array2, final int offset2, final int first, final int limit) {
float retVal = 0F;
for (int i = first; i < limit; i++) {
retVal += array1[offset1 + i] * array2[offset2 + i];
}
return retVal;
}
static float unrolled02(final float[] array1, final int offset1, final float[] array2, final int offset2, final int first, final int limit) {
int remainder = (limit - first) % 2;
float sum0 = 0F;
float sum1 = 0F;
int shift10 = offset1 + 0;
int shift11 = offset1 + 1;
int shift20 = offset2 + 0;
int shift21 = offset2 + 1;
int i = first;
for (int lim = limit - remainder; i < lim; i += 2) {
sum0 += array1[shift10 + i] * array2[shift20 + i];
sum1 += array1[shift11 + i] * array2[shift21 + i];
}
for (; i < limit; i++) {
sum0 += array1[shift10 + i] * array2[shift20 + i];
}
return sum0 + sum1;
}
static double unrolled04(final double[] array1, final int offset1, final double[] array2, final int offset2, final int first, final int limit) {
int remainder = (limit - first) % 4;
double sum0 = 0F;
double sum1 = 0F;
double sum2 = 0F;
double sum3 = 0F;
int shift10 = offset1 + 0;
int shift11 = offset1 + 1;
int shift12 = offset1 + 2;
int shift13 = offset1 + 3;
int shift20 = offset2 + 0;
int shift21 = offset2 + 1;
int shift22 = offset2 + 2;
int shift23 = offset2 + 3;
int i = first;
for (int lim = limit - remainder; i < lim; i += 4) {
sum0 += array1[shift10 + i] * array2[shift20 + i];
sum1 += array1[shift11 + i] * array2[shift21 + i];
sum2 += array1[shift12 + i] * array2[shift22 + i];
sum3 += array1[shift13 + i] * array2[shift23 + i];
}
for (; i < limit; i++) {
sum0 += array1[shift10 + i] * array2[shift20 + i];
}
return sum0 + sum1 + sum2 + sum3;
}
static float unrolled04(final float[] array1, final int offset1, final float[] array2, final int offset2, final int first, final int limit) {
int remainder = (limit - first) % 4;
float sum0 = 0F;
float sum1 = 0F;
float sum2 = 0F;
float sum3 = 0F;
int shift10 = offset1 + 0;
int shift11 = offset1 + 1;
int shift12 = offset1 + 2;
int shift13 = offset1 + 3;
int shift20 = offset2 + 0;
int shift21 = offset2 + 1;
int shift22 = offset2 + 2;
int shift23 = offset2 + 3;
int i = first;
for (int lim = limit - remainder; i < lim; i += 4) {
sum0 += array1[shift10 + i] * array2[shift20 + i];
sum1 += array1[shift11 + i] * array2[shift21 + i];
sum2 += array1[shift12 + i] * array2[shift22 + i];
sum3 += array1[shift13 + i] * array2[shift23 + i];
}
for (; i < limit; i++) {
sum0 += array1[shift10 + i] * array2[shift20 + i];
}
return sum0 + sum1 + sum2 + sum3;
}
static float unrolled08(final float[] array1, final int offset1, final float[] array2, final int offset2, final int first, final int limit) {
int remainder = (limit - first) % 8;
float sum0 = 0F;
float sum1 = 0F;
float sum2 = 0F;
float sum3 = 0F;
float sum4 = 0F;
float sum5 = 0F;
float sum6 = 0F;
float sum7 = 0F;
int shift10 = offset1 + 0;
int shift11 = offset1 + 1;
int shift12 = offset1 + 2;
int shift13 = offset1 + 3;
int shift14 = offset1 + 4;
int shift15 = offset1 + 5;
int shift16 = offset1 + 6;
int shift17 = offset1 + 7;
int shift20 = offset2 + 0;
int shift21 = offset2 + 1;
int shift22 = offset2 + 2;
int shift23 = offset2 + 3;
int shift24 = offset2 + 4;
int shift25 = offset2 + 5;
int shift26 = offset2 + 6;
int shift27 = offset2 + 7;
int i = first;
for (int lim = limit - remainder; i < lim; i += 8) {
sum0 += array1[shift10 + i] * array2[shift20 + i];
sum1 += array1[shift11 + i] * array2[shift21 + i];
sum2 += array1[shift12 + i] * array2[shift22 + i];
sum3 += array1[shift13 + i] * array2[shift23 + i];
sum4 += array1[shift14 + i] * array2[shift24 + i];
sum5 += array1[shift15 + i] * array2[shift25 + i];
sum6 += array1[shift16 + i] * array2[shift26 + i];
sum7 += array1[shift17 + i] * array2[shift27 + i];
}
for (; i < limit; i++) {
sum0 += array1[shift10 + i] * array2[shift20 + i];
}
return sum0 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7;
}
static float unrolled16(final float[] array1, final int offset1, final float[] array2, final int offset2, final int first, final int limit) {
int remainder = (limit - first) % 16;
float sum00 = 0F;
float sum01 = 0F;
float sum02 = 0F;
float sum03 = 0F;
float sum04 = 0F;
float sum05 = 0F;
float sum06 = 0F;
float sum07 = 0F;
float sum08 = 0F;
float sum09 = 0F;
float sum10 = 0F;
float sum11 = 0F;
float sum12 = 0F;
float sum13 = 0F;
float sum14 = 0F;
float sum15 = 0F;
int shift100 = offset1 + 0;
int shift101 = offset1 + 1;
int shift102 = offset1 + 2;
int shift103 = offset1 + 3;
int shift104 = offset1 + 4;
int shift105 = offset1 + 5;
int shift106 = offset1 + 6;
int shift107 = offset1 + 7;
int shift108 = offset1 + 8;
int shift109 = offset1 + 9;
int shift110 = offset1 + 10;
int shift111 = offset1 + 11;
int shift112 = offset1 + 12;
int shift113 = offset1 + 13;
int shift114 = offset1 + 14;
int shift115 = offset1 + 15;
int shift200 = offset2 + 0;
int shift201 = offset2 + 1;
int shift202 = offset2 + 2;
int shift203 = offset2 + 3;
int shift204 = offset2 + 4;
int shift205 = offset2 + 5;
int shift206 = offset2 + 6;
int shift207 = offset2 + 7;
int shift208 = offset2 + 8;
int shift209 = offset2 + 9;
int shift210 = offset2 + 10;
int shift211 = offset2 + 11;
int shift212 = offset2 + 12;
int shift213 = offset2 + 13;
int shift214 = offset2 + 14;
int shift215 = offset2 + 15;
int i = first;
for (int lim = limit - remainder; i < lim; i += 16) {
sum00 += array1[shift100 + i] * array2[shift200 + i];
sum01 += array1[shift101 + i] * array2[shift201 + i];
sum02 += array1[shift102 + i] * array2[shift202 + i];
sum03 += array1[shift103 + i] * array2[shift203 + i];
sum04 += array1[shift104 + i] * array2[shift204 + i];
sum05 += array1[shift105 + i] * array2[shift205 + i];
sum06 += array1[shift106 + i] * array2[shift206 + i];
sum07 += array1[shift107 + i] * array2[shift207 + i];
sum08 += array1[shift108 + i] * array2[shift208 + i];
sum09 += array1[shift109 + i] * array2[shift209 + i];
sum10 += array1[shift110 + i] * array2[shift210 + i];
sum11 += array1[shift111 + i] * array2[shift211 + i];
sum12 += array1[shift112 + i] * array2[shift212 + i];
sum13 += array1[shift113 + i] * array2[shift213 + i];
sum14 += array1[shift114 + i] * array2[shift214 + i];
sum15 += array1[shift115 + i] * array2[shift215 + i];
}
for (; i < limit; i++) {
sum00 += array1[shift100 + i] * array2[shift200 + i];
}
return sum00 + sum01 + sum02 + sum03 + sum04 + sum05 + sum06 + sum07 + sum08 + sum09 + sum10 + sum11 + sum12 + sum13 + sum14 + sum15;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy