]> git.proxmox.com Git - ceph.git/blob - ceph/src/arrow/java/vector/src/main/java/org/apache/arrow/vector/compare/ApproxEqualsVisitor.java
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / java / vector / src / main / java / org / apache / arrow / vector / compare / ApproxEqualsVisitor.java
1 /*
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
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 */
17
18 package org.apache.arrow.vector.compare;
19
20 import java.util.function.BiFunction;
21
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;
27
28 /**
29 * Visitor to compare floating point vectors approximately.
30 */
31 public class ApproxEqualsVisitor extends RangeEqualsVisitor {
32
33 /**
34 * Functions to calculate difference between float/double values.
35 */
36 private final VectorValueEqualizer<Float4Vector> floatDiffFunction;
37 private final VectorValueEqualizer<Float8Vector> doubleDiffFunction;
38
39 /**
40 * Default epsilons for diff functions.
41 */
42 public static final float DEFAULT_FLOAT_EPSILON = 1.0E-6f;
43 public static final double DEFAULT_DOUBLE_EPSILON = 1.0E-6;
44
45 /**
46 * Constructs a new instance with default tolerances.
47 * @param left left vector
48 * @param right right vector
49 */
50 public ApproxEqualsVisitor(ValueVector left, ValueVector right) {
51 this (left, right, DEFAULT_FLOAT_EPSILON, DEFAULT_DOUBLE_EPSILON);
52 }
53
54 /**
55 * Constructs a new instance.
56 *
57 * @param left left vector
58 * @param right right vector
59 * @param floatEpsilon difference for float values
60 * @param doubleEpsilon difference for double values
61 */
62 public ApproxEqualsVisitor(ValueVector left, ValueVector right, float floatEpsilon, double doubleEpsilon) {
63 this (left, right,
64 new ValueEpsilonEqualizers.Float4EpsilonEqualizer(floatEpsilon),
65 new ValueEpsilonEqualizers.Float8EpsilonEqualizer(doubleEpsilon));
66 }
67
68 /**
69 * Constructs a new instance.
70 */
71 public ApproxEqualsVisitor(ValueVector left, ValueVector right,
72 VectorValueEqualizer<Float4Vector> floatDiffFunction,
73 VectorValueEqualizer<Float8Vector> doubleDiffFunction) {
74 this (left, right, floatDiffFunction, doubleDiffFunction, DEFAULT_TYPE_COMPARATOR);
75 }
76
77 /**
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.
84 */
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;
92 }
93
94 @Override
95 public Boolean visit(BaseFixedWidthVector left, Range range) {
96 if (left instanceof Float4Vector) {
97 if (!validate(left)) {
98 return false;
99 }
100 return float4ApproxEquals(range);
101 } else if (left instanceof Float8Vector) {
102 if (!validate(left)) {
103 return false;
104 }
105 return float8ApproxEquals(range);
106 } else {
107 return super.visit(left, range);
108 }
109 }
110
111 @Override
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);
116 }
117
118 private boolean float4ApproxEquals(Range range) {
119 Float4Vector leftVector = (Float4Vector) getLeft();
120 Float4Vector rightVector = (Float4Vector) getRight();
121
122 for (int i = 0; i < range.getLength(); i++) {
123 int leftIndex = range.getLeftStart() + i;
124 int rightIndex = range.getRightStart() + i;
125
126 if (!floatDiffFunction.valuesEqual(leftVector, leftIndex, rightVector, rightIndex)) {
127 return false;
128 }
129 }
130 return true;
131 }
132
133 private boolean float8ApproxEquals(Range range) {
134 Float8Vector leftVector = (Float8Vector) getLeft();
135 Float8Vector rightVector = (Float8Vector) getRight();
136
137 for (int i = 0; i < range.getLength(); i++) {
138 int leftIndex = range.getLeftStart() + i;
139 int rightIndex = range.getRightStart() + i;
140
141 if (!doubleDiffFunction.valuesEqual(leftVector, leftIndex, rightVector, rightIndex)) {
142 return false;
143 }
144 }
145 return true;
146 }
147 }