blob: 29594452a7c3d217c4bb70781a47eaf9e3349cd2 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2020 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.rj.data.impl;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.eclipse.statet.rj.data.impl.AbstractRStore.DEFAULT_LONG_DATA_SEGMENT_LENGTH;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.rj.data.RComplexStore;
import org.eclipse.statet.rj.data.RComplexStore.Complex;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RStore;
@NonNullByDefault
public abstract class RComplexStoreTest extends AbstractRStoreTest {
static class CplxCaseData extends CaseData {
final double[] realValues;
final double[] imaginaryValues;
public CplxCaseData(final String label, final double[] realValues, final double[] imaginaryValues,
final boolean[] nas) {
super(label, nas);
assert (realValues.length == this.length);
assert (imaginaryValues.length == this.length);
this.realValues= realValues;
this.imaginaryValues= imaginaryValues;
}
public CplxCaseData(final String label, final double[] realValues, final double[] imaginaryValues) {
super(label, realValues.length);
assert (realValues.length == this.length);
assert (imaginaryValues.length == this.length);
this.realValues= realValues;
this.imaginaryValues= imaginaryValues;
}
}
protected static final List<CplxCaseData> DEFAULT_DATA_SOURCES;
static {
final var datas= new ArrayList<CplxCaseData>();
datas.add(new CplxCaseData("empty", new double[0], new double[0]));
datas.add(new CplxCaseData("single-0", new double[] { 0 }, new double[] { 0 }));
datas.add(new CplxCaseData("single-1", new double[] { 1 }, new double[] { 0 }));
datas.add(new CplxCaseData("single-i1", new double[] { 0 }, new double[] { 1 }));
datas.add(new CplxCaseData("single-NA", new double[] { 0 }, new double[] { 0 }, new boolean[] { true }));
{ final double[] realValues= new double[0xFF];
final double[] imaginaryValues= new double[realValues.length];
final boolean[] nas= new boolean[realValues.length];
int i= 0;
realValues[i++]= 0;
realValues[i++]= -0;
realValues[i++]= +1;
realValues[i++]= -1;
realValues[i++]= Double.MIN_NORMAL;
realValues[i++]= Double.MIN_VALUE;
realValues[i++]= Double.MAX_VALUE;
realValues[i++]= Double.POSITIVE_INFINITY;
realValues[i++]= -Double.NEGATIVE_INFINITY;
realValues[i++]= Double.NaN;
imaginaryValues[i++]= -0;
imaginaryValues[i++]= -1;
imaginaryValues[i++]= +1;
imaginaryValues[i++]= Double.MIN_NORMAL;
imaginaryValues[i++]= Double.MIN_VALUE;
imaginaryValues[i++]= -Double.MAX_VALUE;
imaginaryValues[i++]= Double.POSITIVE_INFINITY;
imaginaryValues[i++]= -Double.NEGATIVE_INFINITY;
nas[i++]= true;
datas.add(new CplxCaseData("special", realValues, imaginaryValues, nas));
}
{ final Random rand= new Random(16857);
final double[] realValues= new double[100000];
final double[] imaginaryValues= new double[realValues.length];
for (int i= 0; i < realValues.length; i++) {
realValues[i]= rand.nextDouble();
imaginaryValues[i]= rand.nextDouble();
}
datas.add(new CplxCaseData("rand100000", realValues, imaginaryValues));
}
if (isBigDataEnabled(24)) {
final Random rand= new Random(46);
final double[] realValues= new double[DEFAULT_LONG_DATA_SEGMENT_LENGTH * 2 + 13];
final double[] imaginaryValues= new double[DEFAULT_LONG_DATA_SEGMENT_LENGTH * 2 + 13];
for (int i= 0; i < realValues.length; i++) {
realValues[i]= rand.nextDouble();
}
datas.add(new CplxCaseData("randMultiSeg", realValues, imaginaryValues));
}
DEFAULT_DATA_SOURCES= datas;
}
public RComplexStoreTest() {
}
public static List<CplxCaseData> provideCaseDatas() {
return new ArrayList<>(DEFAULT_DATA_SOURCES);
}
protected abstract RComplexStore createStore(final CplxCaseData data);
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getStoreType(final CplxCaseData data) {
final RComplexStore store= createStore(data);
assertEquals(RStore.COMPLEX, store.getStoreType());
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getBaseVectorRClassName(final CplxCaseData data) {
final RComplexStore store= createStore(data);
assertEquals(RObject.CLASSNAME_COMPLEX, store.getBaseVectorRClassName());
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void length(final CplxCaseData data) {
final RComplexStore store= createStore(data);
checkLength(data, store);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void isNA(final CplxCaseData data) {
final RComplexStore store= createStore(data);
checkIsNA(data, store);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void isMissing(final CplxCaseData data) {
final RComplexStore store= createStore(data);
for (int i= 0; i < data.length; i++) {
final int i0= i;
if (data.nas[i0]
|| Double.isNaN(data.realValues[i0]) || Double.isNaN(data.imaginaryValues[i0])) {
assertTrue(store.isMissing(i0), storeDiffersAt(i0));
assertTrue(store.isMissing((long)i0), storeDiffersAt(i0));
}
else {
assertFalse(store.isMissing(i0), storeDiffersAt(i0));
assertFalse(store.isMissing((long)i0), storeDiffersAt(i0));
}
}
assertIndexOutOfBounds(data, store::isMissing, store::isMissing);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getLogi(final CplxCaseData data) {
final RComplexStore store= createStore(data);
assertUnsupported(data, store::getLogi, store::getLogi);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getInt(final CplxCaseData data) {
final RComplexStore store= createStore(data);
assertUnsupported(data, store::getInt, store::getInt);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getNum(final CplxCaseData data) {
final RComplexStore store= createStore(data);
assertUnsupported(data, store::getNum, store::getNum);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getCplx(final CplxCaseData data) {
final RComplexStore store= createStore(data);
for (int i= 0; i < data.length; i++) {
final int i0= i;
if (data.nas[i0]) {
// undefined
}
else {
final double expectedRe= data.realValues[i0];
final double expectedIm= data.imaginaryValues[i0];
assertEquals(expectedRe, store.getCplxRe(i0), storeDiffersAt(i0));
assertEquals(expectedRe, store.getCplxRe((long)i0), storeDiffersAt(i0));
assertEquals(expectedIm, store.getCplxIm(i0), storeDiffersAt(i0));
assertEquals(expectedIm, store.getCplxIm((long)i0), storeDiffersAt(i0));
}
}
assertIndexOutOfBounds(data, store::getCplxRe, store::getCplxRe);
assertIndexOutOfBounds(data, store::getCplxIm, store::getCplxIm);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getChar(final CplxCaseData data) {
final RComplexStore store= createStore(data);
for (int i= 0; i < data.length; i++) {
final int i0= i;
if (data.nas[i0]) {
// undefined
}
else {
final String reStr= Double.toString(data.realValues[i0]).replace("Infinity", "Inf");
final String imStr= Double.toString(data.imaginaryValues[i0]).replace("Infinity", "Inf");
final String expected= (imStr.charAt(0) != '-') ?
(reStr + '+' + imStr + 'i') :
(reStr + imStr + 'i');
assertEquals(expected, store.getChar(i0), storeDiffersAt(i0));
assertEquals(expected, store.getChar((long)i0), storeDiffersAt(i0));
}
}
assertIndexOutOfBounds(data, store::getChar, store::getChar);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getRaw(final CplxCaseData data) {
final RComplexStore store= createStore(data);
assertUnsupported(data, store::getRaw, store::getRaw);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void get(final CplxCaseData data) {
final RComplexStore store= createStore(data);
for (int i= 0; i < data.length; i++) {
final int i0= i;
if (data.nas[i0]) {
assertNull(store.get(i0), storeDiffersAt(i0));
}
else {
final Complex expected= new Complex(data.realValues[i0], data.imaginaryValues[i0]);
assertEquals(expected, store.get(i0), storeDiffersAt(i0));
assertEquals(expected, store.get((long)i0), storeDiffersAt(i0));
}
}
assertIndexOutOfBounds(data, store::get, store::get);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void toArray(final CplxCaseData data) {
final RComplexStore store= createStore(data);
final @Nullable Complex[] array= store.toArray();
assertEquals(data.realValues.length, array.length);
for (int i= 0; i < data.length; i++) {
final int i0= i;
if (data.nas[i0]) {
assertNull(array[i0], arrayDiffersAt(i0));
}
else {
final Complex expected= new Complex(data.realValues[i0], data.imaginaryValues[i0]);
assertEquals(expected, array[i0], arrayDiffersAt(i0));
}
}
}
}