mirror of
https://github.com/enso-org/enso.git
synced 2024-12-22 18:38:11 +03:00
impl
This commit is contained in:
parent
2bbb32034b
commit
baeea8989f
@ -411,6 +411,8 @@ type Column
|
||||
example_lt = Examples.integer_column < 1
|
||||
< : Column | Any -> Column
|
||||
< self other = Value_Type.expect_comparable self other <|
|
||||
if other.is_a Column then
|
||||
IO.println "AAA "+self.value_type.to_text+" :: "+other.value_type.to_text
|
||||
Incomparable_Values.handle_errors <|
|
||||
run_vectorized_binary_op self Java_Storage.Maps.LT fallback_fn=(<) other expected_result_type=Value_Type.Boolean
|
||||
|
||||
|
@ -4,10 +4,12 @@ import static org.enso.table.data.column.operation.map.numeric.helpers.DoubleArr
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.BitSet;
|
||||
|
||||
import org.enso.base.CompareException;
|
||||
import org.enso.base.polyglot.NumericConverter;
|
||||
import org.enso.table.data.column.operation.map.BinaryMapOperation;
|
||||
import org.enso.table.data.column.operation.map.MapOperationProblemAggregator;
|
||||
import org.enso.table.data.column.operation.map.numeric.helpers.BigDecimalArrayAdapter;
|
||||
import org.enso.table.data.column.operation.map.numeric.helpers.BigIntegerArrayAdapter;
|
||||
import org.enso.table.data.column.operation.map.numeric.helpers.DoubleArrayAdapter;
|
||||
import org.enso.table.data.column.storage.BoolStorage;
|
||||
@ -47,6 +49,8 @@ public abstract class NumericComparison<T extends Number, I extends Storage<? su
|
||||
BigIntegerArrayAdapter.fromStorage(s), bigInteger, problemAggregator);
|
||||
case BigIntegerStorage s -> runBigIntegerMap(
|
||||
BigIntegerArrayAdapter.fromStorage(s), bigInteger, problemAggregator);
|
||||
case BigDecimalStorage s -> runBigDecimalMap(
|
||||
BigIntegerArrayAdapter.fromStorage(s), new BigDecimal(bigInteger), problemAggregator);
|
||||
case DoubleStorage s -> runDoubleMap(s, bigInteger.doubleValue(), problemAggregator);
|
||||
default -> throw new IllegalStateException(
|
||||
"Unsupported lhs storage: " + storage.getClass().getCanonicalName());
|
||||
@ -57,14 +61,21 @@ public abstract class NumericComparison<T extends Number, I extends Storage<? su
|
||||
case AbstractLongStorage s -> runLongMap(s, rhs, problemAggregator);
|
||||
case BigIntegerStorage s -> runBigIntegerMap(
|
||||
BigIntegerArrayAdapter.fromStorage(s), BigInteger.valueOf(rhs), problemAggregator);
|
||||
case BigDecimalStorage s -> runBigDecimalMap(
|
||||
BigDecimalArrayAdapter.fromStorage(s), BigDecimal.valueOf(rhs), problemAggregator);
|
||||
case DoubleStorage s -> runDoubleMap(s, (double) rhs, problemAggregator);
|
||||
default -> throw new IllegalStateException(
|
||||
"Unsupported lhs storage: " + storage.getClass().getCanonicalName());
|
||||
};
|
||||
} else if (NumericConverter.isCoercibleToDouble(arg)) {
|
||||
DoubleArrayAdapter lhs = DoubleArrayAdapter.fromAnyStorage(storage);
|
||||
double rhs = NumericConverter.coerceToDouble(arg);
|
||||
return runDoubleMap(lhs, rhs, problemAggregator);
|
||||
return switch (storage) {
|
||||
case BigDecimalStorage s -> runBigDecimalMap(
|
||||
BigDecimalArrayAdapter.fromStorage(s), BigDecimal.valueOf(arg), problemAggregator);
|
||||
default -> {
|
||||
DoubleArrayAdapter lhs = DoubleArrayAdapter.fromAnyStorage(storage);
|
||||
double rhs = NumericConverter.coerceToDouble(arg);
|
||||
yield runDoubleMap(lhs, rhs, problemAggregator);
|
||||
}
|
||||
} else {
|
||||
int n = storage.size();
|
||||
BitSet isNothing = new BitSet();
|
||||
@ -155,15 +166,44 @@ public abstract class NumericComparison<T extends Number, I extends Storage<? su
|
||||
return new BoolStorage(comparisonResults, isNothing, n, false);
|
||||
}
|
||||
|
||||
protected BoolStorage runBigDecimalMap(
|
||||
BigDecimalArrayAdapter lhs, BigDecimal rhs, MapOperationProblemAggregator problemAggregator) {
|
||||
int n = lhs.size();
|
||||
BitSet comparisonResults = new BitSet();
|
||||
BitSet isNothing = new BitSet();
|
||||
Context context = Context.getCurrent();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
BigDecimal item = lhs.getItem(i);
|
||||
if (item == null) {
|
||||
isNothing.set(i);
|
||||
} else {
|
||||
boolean r = doBigDecimal(item, rhs);
|
||||
if (r) {
|
||||
comparisonResults.set(i);
|
||||
}
|
||||
}
|
||||
|
||||
context.safepoint();
|
||||
}
|
||||
|
||||
return new BoolStorage(comparisonResults, isNothing, n, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoolStorage runZip(
|
||||
I storage, Storage<?> arg, MapOperationProblemAggregator problemAggregator) {
|
||||
return switch (storage) {
|
||||
case DoubleStorage lhs -> {
|
||||
if (arg.getType() instanceof AnyObjectType) {
|
||||
yield runMixedZip(lhs, arg, problemAggregator);
|
||||
} else {
|
||||
yield runDoubleZip(lhs, fromAnyStorage(arg), problemAggregator);
|
||||
case BigDecimalStorage rhs -> runBigDecimalZip(
|
||||
new BigDecimalArrayAdapter(lhs),
|
||||
new BigDecimalArrayAdapter(rhs),
|
||||
problemAggregator);
|
||||
default -> {
|
||||
if (arg.getType() instanceof AnyObjectType) {
|
||||
yield runMixedZip(lhs, arg, problemAggregator);
|
||||
} else {
|
||||
yield runDoubleZip(lhs, fromAnyStorage(arg), problemAggregator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,22 +214,31 @@ public abstract class NumericComparison<T extends Number, I extends Storage<? su
|
||||
BigIntegerArrayAdapter right = BigIntegerArrayAdapter.fromStorage(rhs);
|
||||
yield runBigIntegerZip(left, right, problemAggregator);
|
||||
}
|
||||
case BigDecimalStorage rhs -> runBigDecimalZip(
|
||||
new BigDecimalArrayAdapter(lhs),
|
||||
new BigDecimalArrayAdapter(rhs),
|
||||
problemAggregator);
|
||||
case DoubleStorage rhs -> runDoubleZip(
|
||||
DoubleArrayAdapter.fromStorage(lhs), rhs, problemAggregator);
|
||||
default -> runMixedZip(lhs, arg, problemAggregator);
|
||||
};
|
||||
|
||||
case BigIntegerStorage lhs -> {
|
||||
BigIntegerArrayAdapter left = BigIntegerArrayAdapter.fromStorage(lhs);
|
||||
yield switch (arg) {
|
||||
case AbstractLongStorage rhs -> {
|
||||
BigIntegerArrayAdapter left = BigIntegerArrayAdapter.fromStorage(lhs);
|
||||
BigIntegerArrayAdapter right = BigIntegerArrayAdapter.fromStorage(rhs);
|
||||
yield runBigIntegerZip(left, right, problemAggregator);
|
||||
}
|
||||
case BigIntegerStorage rhs -> {
|
||||
BigIntegerArrayAdapter left = BigIntegerArrayAdapter.fromStorage(lhs);
|
||||
BigIntegerArrayAdapter right = BigIntegerArrayAdapter.fromStorage(rhs);
|
||||
yield runBigIntegerZip(left, right, problemAggregator);
|
||||
}
|
||||
case BigDecimalStorage rhs -> runBigDecimalZip(
|
||||
new BigDecimalArrayAdapter(lhs),
|
||||
new BigDecimalArrayAdapter(rhs),
|
||||
problemAggregator);
|
||||
case DoubleStorage rhs -> runDoubleZip(
|
||||
DoubleArrayAdapter.fromStorage(lhs), rhs, problemAggregator);
|
||||
default -> runMixedZip(lhs, arg, problemAggregator);
|
||||
@ -294,6 +343,37 @@ public abstract class NumericComparison<T extends Number, I extends Storage<? su
|
||||
return new BoolStorage(comparisonResults, isNothing, n, false);
|
||||
}
|
||||
|
||||
protected BoolStorage runBigDecimalZip(
|
||||
BigDecimalArrayAdapter lhs,
|
||||
BigDecimalArrayAdapter rhs,
|
||||
MapOperationProblemAggregator problemAggregator) {
|
||||
int n = lhs.size();
|
||||
int m = Math.min(lhs.size(), rhs.size());
|
||||
BitSet comparisonResults = new BitSet();
|
||||
BitSet isNothing = new BitSet();
|
||||
Context context = Context.getCurrent();
|
||||
for (int i = 0; i < m; ++i) {
|
||||
BigDecimal x = lhs.getItem(i);
|
||||
BigDecimal y = rhs.getItem(i);
|
||||
if (x == null || y == null) {
|
||||
isNothing.set(i);
|
||||
} else {
|
||||
boolean r = doBigDecimal(x, y);
|
||||
if (r) {
|
||||
comparisonResults.set(i);
|
||||
}
|
||||
}
|
||||
|
||||
context.safepoint();
|
||||
}
|
||||
|
||||
if (m < n) {
|
||||
isNothing.set(m, n);
|
||||
}
|
||||
|
||||
return new BoolStorage(comparisonResults, isNothing, n, false);
|
||||
}
|
||||
|
||||
protected BoolStorage runMixedZip(
|
||||
Storage<?> lhs, Storage<?> rhs, MapOperationProblemAggregator problemAggregator) {
|
||||
int n = lhs.size();
|
||||
|
@ -649,26 +649,75 @@ add_specs suite_builder setup =
|
||||
|
||||
suite_builder.group prefix+"(Column_Operations_Spec) Column Comparisons" group_builder->
|
||||
table_builder = build_sorted_table table_builder=setup.light_table_builder
|
||||
|
||||
group_builder.specify "should infer the correct precise value type for mixed columns" <|
|
||||
with_mixed_columns_if_supported [["i", [1, 4, 5, Nothing]], ["f", [2.0, 3.25, 5.0, Nothing]], ["d", [dec "2.0", dec "3.25", dec "5.0", Nothing]]] t->
|
||||
setup.is_integer_type (t.at "i").inferred_precise_value_type . should_be_true
|
||||
(t.at "f").inferred_precise_value_type . should_be_a (Value_Type.Float ...)
|
||||
(t.at "d").inferred_precise_value_type . should_be_a (Value_Type.Decimal ...)
|
||||
|
||||
group_builder.specify "should allow to compare numbers" <|
|
||||
with_mixed_columns_if_supported [["x", [1, 4, 5, Nothing]], ["y", [2.0, 3.25, 5.0, Nothing]]] t2->
|
||||
x = t2.at "x"
|
||||
y = t2.at "y"
|
||||
setup.is_integer_type x.inferred_precise_value_type . should_be_true
|
||||
y.inferred_precise_value_type . should_be_a (Value_Type.Float ...)
|
||||
x_values = [1.25, 4.5, 5.0]
|
||||
y_values = [2.0, 3.25, 5.0]
|
||||
|
||||
(x < y).to_vector . should_equal [True, False, False, Nothing]
|
||||
(x <= y).to_vector . should_equal [True, False, True, Nothing]
|
||||
(x > y).to_vector . should_equal (x <= y).not.to_vector
|
||||
(x >= y).to_vector . should_equal (x < y).not.to_vector
|
||||
converters = [.truncate, x->x, dec]
|
||||
converters.map x_converter -> converters.map y_converter ->
|
||||
x_values_converted = x_values.map x_converter
|
||||
y_values_converted = y_values.map y_converter
|
||||
with_mixed_columns_if_supported [['x', x_values_converted + [Nothing]], ['y', y_values_converted + [Nothing]]
|
||||
clue = x.value_type.to_text+', '+y.value_type.to_text
|
||||
#IO.println "CLUE "+clue
|
||||
Test.with_clue clue <|
|
||||
(x < y).to_vector . should_equal [True, False, False, Nothing]
|
||||
(x <= y).to_vector . should_equal [True, False, True, Nothing]
|
||||
(x > y).to_vector . should_equal (x <= y).not.to_vector
|
||||
(x >= y).to_vector . should_equal (x < y).not.to_vector
|
||||
|
||||
(x < 1000).to_vector . should_equal [True, True, True, Nothing]
|
||||
[6.5, 1000.5].map const_float->
|
||||
converters.map converter->
|
||||
constant = converter const_float
|
||||
(x < -constant).to_vector . should_equal [False, False, False, Nothing]
|
||||
(x < constant).to_vector . should_equal [True, True, True, Nothing]
|
||||
(x < -constant).to_vector . should_equal [False, False, False, Nothing]
|
||||
(x < constant).to_vector . should_equal [True, True, True, Nothing]
|
||||
|
||||
[(<), (<=), (>), (>=)].each op->
|
||||
op x y . value_type . should_equal Value_Type.Boolean
|
||||
op x y . to_vector . should_succeed
|
||||
op x 23 . to_vector . should_succeed
|
||||
op y 23 . to_vector . should_succeed
|
||||
op x 1.5 . to_vector . should_succeed
|
||||
op x (dec 1.5) . to_vector . should_succeed
|
||||
|
||||
##
|
||||
with_mixed_columns_if_supported [["x", [1, 4, 5, Nothing]], ["yf", [2.0, 3.25, 5.0, Nothing]], ["yd", [Decimal.new "2.0", Decimal.new "3.25", Decimal.new "5.0", Nothing]]] t->
|
||||
setup.is_integer_type (t.at "x").inferred_precise_value_type . should_be_true
|
||||
(t.at "yf").inferred_precise_value_type . should_be_a (Value_Type.Float ...)
|
||||
(t.at "yd").inferred_precise_value_type . should_be_a (Value_Type.Decimal ...)
|
||||
|
||||
x = t.at "x"
|
||||
#q0 = (x < (t.at "yf")).to_vector
|
||||
#q1 = (x < (t.at "yd")).to_vector
|
||||
|
||||
[t.at "yf", t.at "yd"].map y->
|
||||
clue = x.value_type.to_text+', '+y.value_type.to_text
|
||||
IO.println "CLUE "+clue
|
||||
Test.with_clue clue <|
|
||||
|
||||
(x < y).to_vector . should_equal [True, False, False, Nothing]
|
||||
(x <= y).to_vector . should_equal [True, False, True, Nothing]
|
||||
(x > y).to_vector . should_equal (x <= y).not.to_vector
|
||||
(x >= y).to_vector . should_equal (x < y).not.to_vector
|
||||
|
||||
(x < 1000).to_vector . should_equal [True, True, True, Nothing]
|
||||
|
||||
[(<), (<=), (>), (>=)].each op->
|
||||
op x y . value_type . should_equal Value_Type.Boolean
|
||||
op x y . to_vector . should_succeed
|
||||
op x 23 . to_vector . should_succeed
|
||||
op y 23 . to_vector . should_succeed
|
||||
op x 1.5 . to_vector . should_succeed
|
||||
|
||||
[(<), (<=), (>), (>=)].each op->
|
||||
op x y . value_type . should_equal Value_Type.Boolean
|
||||
op x y . to_vector . should_succeed
|
||||
op x 23 . to_vector . should_succeed
|
||||
op y 23 . to_vector . should_succeed
|
||||
op x 1.5 . to_vector . should_succeed
|
||||
|
||||
group_builder.specify "should allow to compare texts" <|
|
||||
t0 = table_builder [["X", ["a", "b", "c"]], ["Y", ["a", "b", "d"]]]
|
||||
|
Loading…
Reference in New Issue
Block a user