2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package org
.apache
.arrow
.vector
.compare
;
20 import java
.util
.function
.BiFunction
;
22 import org
.apache
.arrow
.vector
.BaseFixedWidthVector
;
23 import org
.apache
.arrow
.vector
.Float4Vector
;
24 import org
.apache
.arrow
.vector
.Float8Vector
;
25 import org
.apache
.arrow
.vector
.ValueVector
;
26 import org
.apache
.arrow
.vector
.compare
.util
.ValueEpsilonEqualizers
;
29 * Visitor to compare floating point vectors approximately.
31 public class ApproxEqualsVisitor
extends RangeEqualsVisitor
{
34 * Functions to calculate difference between float/double values.
36 private final VectorValueEqualizer
<Float4Vector
> floatDiffFunction
;
37 private final VectorValueEqualizer
<Float8Vector
> doubleDiffFunction
;
40 * Default epsilons for diff functions.
42 public static final float DEFAULT_FLOAT_EPSILON
= 1.0E-6f
;
43 public static final double DEFAULT_DOUBLE_EPSILON
= 1.0E-6;
46 * Constructs a new instance with default tolerances.
47 * @param left left vector
48 * @param right right vector
50 public ApproxEqualsVisitor(ValueVector left
, ValueVector right
) {
51 this (left
, right
, DEFAULT_FLOAT_EPSILON
, DEFAULT_DOUBLE_EPSILON
);
55 * Constructs a new instance.
57 * @param left left vector
58 * @param right right vector
59 * @param floatEpsilon difference for float values
60 * @param doubleEpsilon difference for double values
62 public ApproxEqualsVisitor(ValueVector left
, ValueVector right
, float floatEpsilon
, double doubleEpsilon
) {
64 new ValueEpsilonEqualizers
.Float4EpsilonEqualizer(floatEpsilon
),
65 new ValueEpsilonEqualizers
.Float8EpsilonEqualizer(doubleEpsilon
));
69 * Constructs a new instance.
71 public ApproxEqualsVisitor(ValueVector left
, ValueVector right
,
72 VectorValueEqualizer
<Float4Vector
> floatDiffFunction
,
73 VectorValueEqualizer
<Float8Vector
> doubleDiffFunction
) {
74 this (left
, right
, floatDiffFunction
, doubleDiffFunction
, DEFAULT_TYPE_COMPARATOR
);
78 * Constructs a new instance.
79 * @param left the left vector.
80 * @param right the right vector.
81 * @param floatDiffFunction the equalizer for float values.
82 * @param doubleDiffFunction the equalizer for double values.
83 * @param typeComparator type comparator to compare vector type.
85 public ApproxEqualsVisitor(ValueVector left
, ValueVector right
,
86 VectorValueEqualizer
<Float4Vector
> floatDiffFunction
,
87 VectorValueEqualizer
<Float8Vector
> doubleDiffFunction
,
88 BiFunction
<ValueVector
, ValueVector
, Boolean
> typeComparator
) {
89 super(left
, right
, typeComparator
);
90 this.floatDiffFunction
= floatDiffFunction
;
91 this.doubleDiffFunction
= doubleDiffFunction
;
95 public Boolean
visit(BaseFixedWidthVector left
, Range range
) {
96 if (left
instanceof Float4Vector
) {
97 if (!validate(left
)) {
100 return float4ApproxEquals(range
);
101 } else if (left
instanceof Float8Vector
) {
102 if (!validate(left
)) {
105 return float8ApproxEquals(range
);
107 return super.visit(left
, range
);
112 protected ApproxEqualsVisitor
createInnerVisitor(
113 ValueVector left
, ValueVector right
,
114 BiFunction
<ValueVector
, ValueVector
, Boolean
> typeComparator
) {
115 return new ApproxEqualsVisitor(left
, right
, floatDiffFunction
.clone(), doubleDiffFunction
.clone(), typeComparator
);
118 private boolean float4ApproxEquals(Range range
) {
119 Float4Vector leftVector
= (Float4Vector
) getLeft();
120 Float4Vector rightVector
= (Float4Vector
) getRight();
122 for (int i
= 0; i
< range
.getLength(); i
++) {
123 int leftIndex
= range
.getLeftStart() + i
;
124 int rightIndex
= range
.getRightStart() + i
;
126 if (!floatDiffFunction
.valuesEqual(leftVector
, leftIndex
, rightVector
, rightIndex
)) {
133 private boolean float8ApproxEquals(Range range
) {
134 Float8Vector leftVector
= (Float8Vector
) getLeft();
135 Float8Vector rightVector
= (Float8Vector
) getRight();
137 for (int i
= 0; i
< range
.getLength(); i
++) {
138 int leftIndex
= range
.getLeftStart() + i
;
139 int rightIndex
= range
.getRightStart() + i
;
141 if (!doubleDiffFunction
.valuesEqual(leftVector
, leftIndex
, rightVector
, rightIndex
)) {