diff --git a/src/Functions/array/arrayDistance.cpp b/src/Functions/array/arrayDistance.cpp index 3f7900b6c62..fda93bceedd 100644 --- a/src/Functions/array/arrayDistance.cpp +++ b/src/Functions/array/arrayDistance.cpp @@ -70,6 +70,33 @@ struct L2Distance } }; +struct L2SquaredDistance +{ + static inline String name = "L2Squared"; + + struct ConstParams + { + }; + + template + struct State + { + FloatType sum = 0; + }; + + template + static void accumulate(State & state, ResultType x, ResultType y, const ConstParams &) + { + state.sum += (x - y) * (x - y); + } + + template + static ResultType finalize(const State & state, const ConstParams &) + { + return state.sum; + } +}; + struct LpDistance { static inline String name = "Lp"; @@ -195,12 +222,12 @@ public: ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Arguments of function {} has nested type {}. " "Support: UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, Float32, Float64.", - getName(), common_type->getName()); + getName(), + common_type->getName()); } } - ColumnPtr - executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override + ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override { switch (result_type->getTypeId()) { @@ -248,7 +275,8 @@ private: ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Arguments of function {} has nested type {}. " "Support: UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, Float32, Float64.", - getName(), type_x->getName()); + getName(), + type_x->getName()); } } @@ -273,7 +301,8 @@ private: ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Arguments of function {} has nested type {}. " "Support: UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, Float32, Float64.", - getName(), type_y->getName()); + getName(), + type_y->getName()); } } @@ -310,7 +339,9 @@ private: throw Exception( ErrorCodes::SIZES_OF_ARRAYS_DOESNT_MATCH, "Arguments of function {} have different array sizes: {} and {}", - getName(), offsets_x[row] - prev_offset, offsets_y[row] - prev_offset); + getName(), + offsets_x[row] - prev_offset, + offsets_y[row] - prev_offset); } } @@ -360,7 +391,9 @@ private: throw Exception( ErrorCodes::SIZES_OF_ARRAYS_DOESNT_MATCH, "Arguments of function {} have different array sizes: {} and {}", - getName(), offsets_x[0], offsets_y[row] - prev_offset); + getName(), + offsets_x[0], + offsets_y[row] - prev_offset); } prev_offset = offsets_y[row]; } @@ -430,8 +463,8 @@ LpDistance::ConstParams FunctionArrayDistance::initConstParams(const /// These functions are used by TupleOrArrayFunction FunctionPtr createFunctionArrayL1Distance(ContextPtr context_) { return FunctionArrayDistance::create(context_); } FunctionPtr createFunctionArrayL2Distance(ContextPtr context_) { return FunctionArrayDistance::create(context_); } +FunctionPtr createFunctionArrayL2SquaredDistance(ContextPtr context_) { return FunctionArrayDistance::create(context_); } FunctionPtr createFunctionArrayLpDistance(ContextPtr context_) { return FunctionArrayDistance::create(context_); } FunctionPtr createFunctionArrayLinfDistance(ContextPtr context_) { return FunctionArrayDistance::create(context_); } FunctionPtr createFunctionArrayCosineDistance(ContextPtr context_) { return FunctionArrayDistance::create(context_); } - } diff --git a/src/Functions/array/arrayNorm.cpp b/src/Functions/array/arrayNorm.cpp index 2142abc4c90..a9d1885c136 100644 --- a/src/Functions/array/arrayNorm.cpp +++ b/src/Functions/array/arrayNorm.cpp @@ -57,6 +57,25 @@ struct L2Norm } }; +struct L2SquaredNorm +{ + static inline String name = "L2Squared"; + + struct ConstParams {}; + + template + inline static ResultType accumulate(ResultType result, ResultType value, const ConstParams &) + { + return result + value * value; + } + + template + inline static ResultType finalize(ResultType result, const ConstParams &) + { + return result; + } +}; + struct LpNorm { @@ -265,6 +284,7 @@ LpNorm::ConstParams FunctionArrayNorm::initConstParams(const ColumnsWith /// These functions are used by TupleOrArrayFunction FunctionPtr createFunctionArrayL1Norm(ContextPtr context_) { return FunctionArrayNorm::create(context_); } FunctionPtr createFunctionArrayL2Norm(ContextPtr context_) { return FunctionArrayNorm::create(context_); } +FunctionPtr createFunctionArrayL2SquaredNorm(ContextPtr context_) { return FunctionArrayNorm::create(context_); } FunctionPtr createFunctionArrayLpNorm(ContextPtr context_) { return FunctionArrayNorm::create(context_); } FunctionPtr createFunctionArrayLinfNorm(ContextPtr context_) { return FunctionArrayNorm::create(context_); } diff --git a/src/Functions/vectorFunctions.cpp b/src/Functions/vectorFunctions.cpp index 411b30040cc..d26eb40e1a8 100644 --- a/src/Functions/vectorFunctions.cpp +++ b/src/Functions/vectorFunctions.cpp @@ -25,6 +25,7 @@ struct DivideName { static constexpr auto name = "divide"; }; struct L1Label { static constexpr auto name = "1"; }; struct L2Label { static constexpr auto name = "2"; }; +struct L2SquaredLabel { static constexpr auto name = "2Squared"; }; struct LinfLabel { static constexpr auto name = "inf"; }; struct LpLabel { static constexpr auto name = "p"; }; @@ -625,6 +626,108 @@ public: }; using FunctionL2Norm = FunctionLNorm; +template <> +class FunctionLNorm : public ITupleFunction +{ +public: + static constexpr auto name = "L2SquaredNorm"; + + explicit FunctionLNorm(ContextPtr context_) : ITupleFunction(context_) {} + static FunctionPtr create(ContextPtr context_) { return std::make_shared(context_); } + + String getName() const override { return name; } + + size_t getNumberOfArguments() const override { return 1; } + + DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override + { + const auto * cur_tuple = checkAndGetDataType(arguments[0].type.get()); + + if (!cur_tuple) + throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Argument 0 of function {} should be tuple, got {}", + getName(), arguments[0].type->getName()); + + const auto & cur_types = cur_tuple->getElements(); + + Columns cur_elements; + if (arguments[0].column) + cur_elements = getTupleElements(*arguments[0].column); + + size_t tuple_size = cur_types.size(); + if (tuple_size == 0) + return std::make_shared(); + + auto multiply = FunctionFactory::instance().get("multiply", context); + auto plus = FunctionFactory::instance().get("plus", context); + DataTypePtr res_type; + for (size_t i = 0; i < tuple_size; ++i) + { + try + { + ColumnWithTypeAndName cur{cur_elements.empty() ? nullptr : cur_elements[i], cur_types[i], {}}; + auto elem_multiply = multiply->build(ColumnsWithTypeAndName{cur, cur}); + + if (i == 0) + { + res_type = elem_multiply->getResultType(); + continue; + } + + ColumnWithTypeAndName left_type{res_type, {}}; + ColumnWithTypeAndName right_type{elem_multiply->getResultType(), {}}; + auto plus_elem = plus->build({left_type, right_type}); + res_type = plus_elem->getResultType(); + } + catch (DB::Exception & e) + { + e.addMessage("While executing function {} for tuple element {}", getName(), i); + throw; + } + } + + return res_type; + } + + ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override + { + const auto * cur_tuple = checkAndGetDataType(arguments[0].type.get()); + const auto & cur_types = cur_tuple->getElements(); + auto cur_elements = getTupleElements(*arguments[0].column); + + size_t tuple_size = cur_elements.size(); + if (tuple_size == 0) + return DataTypeUInt8().createColumnConstWithDefaultValue(input_rows_count); + + auto multiply = FunctionFactory::instance().get("multiply", context); + auto plus = FunctionFactory::instance().get("plus", context); + ColumnWithTypeAndName res; + for (size_t i = 0; i < tuple_size; ++i) + { + ColumnWithTypeAndName cur{cur_elements[i], cur_types[i], {}}; + auto elem_multiply = multiply->build(ColumnsWithTypeAndName{cur, cur}); + + ColumnWithTypeAndName column; + column.type = elem_multiply->getResultType(); + column.column = elem_multiply->execute({cur, cur}, column.type, input_rows_count); + + if (i == 0) + { + res = std::move(column); + } + else + { + auto plus_elem = plus->build({res, column}); + auto res_type = plus_elem->getResultType(); + res.column = plus_elem->execute({res, column}, res_type, input_rows_count); + res.type = res_type; + } + } + + return res.column; + } +}; +using FunctionL2SquaredNorm = FunctionLNorm; + template <> class FunctionLNorm : public ITupleFunction { @@ -930,6 +1033,8 @@ using FunctionL1Distance = FunctionLDistance; using FunctionL2Distance = FunctionLDistance; +using FunctionL2SquaredDistance = FunctionLDistance; + using FunctionLinfDistance = FunctionLDistance; using FunctionLpDistance = FunctionLDistance; @@ -1111,11 +1216,13 @@ private: extern FunctionPtr createFunctionArrayL1Norm(ContextPtr context_); extern FunctionPtr createFunctionArrayL2Norm(ContextPtr context_); +extern FunctionPtr createFunctionArrayL2SquaredNorm(ContextPtr context_); extern FunctionPtr createFunctionArrayLpNorm(ContextPtr context_); extern FunctionPtr createFunctionArrayLinfNorm(ContextPtr context_); extern FunctionPtr createFunctionArrayL1Distance(ContextPtr context_); extern FunctionPtr createFunctionArrayL2Distance(ContextPtr context_); +extern FunctionPtr createFunctionArrayL2SquaredDistance(ContextPtr context_); extern FunctionPtr createFunctionArrayLpDistance(ContextPtr context_); extern FunctionPtr createFunctionArrayLinfDistance(ContextPtr context_); extern FunctionPtr createFunctionArrayCosineDistance(ContextPtr context_); @@ -1136,6 +1243,14 @@ struct L2NormTraits static constexpr auto CreateArrayFunction = createFunctionArrayL2Norm; }; +struct L2SquaredNormTraits +{ + static inline String name = "L2SquaredNorm"; + + static constexpr auto CreateTupleFunction = FunctionL2SquaredNorm::create; + static constexpr auto CreateArrayFunction = createFunctionArrayL2SquaredNorm; +}; + struct LpNormTraits { static inline String name = "LpNorm"; @@ -1168,6 +1283,14 @@ struct L2DistanceTraits static constexpr auto CreateArrayFunction = createFunctionArrayL2Distance; }; +struct L2SquaredDistanceTraits +{ + static inline String name = "L2SquaredDistance"; + + static constexpr auto CreateTupleFunction = FunctionL2SquaredDistance::create; + static constexpr auto CreateArrayFunction = createFunctionArrayL2SquaredDistance; +}; + struct LpDistanceTraits { static inline String name = "LpDistance"; @@ -1194,11 +1317,13 @@ struct CosineDistanceTraits using TupleOrArrayFunctionL1Norm = TupleOrArrayFunction; using TupleOrArrayFunctionL2Norm = TupleOrArrayFunction; +using TupleOrArrayFunctionL2SquaredNorm = TupleOrArrayFunction; using TupleOrArrayFunctionLpNorm = TupleOrArrayFunction; using TupleOrArrayFunctionLinfNorm = TupleOrArrayFunction; using TupleOrArrayFunctionL1Distance = TupleOrArrayFunction; using TupleOrArrayFunctionL2Distance = TupleOrArrayFunction; +using TupleOrArrayFunctionL2SquaredDistance = TupleOrArrayFunction; using TupleOrArrayFunctionLpDistance = TupleOrArrayFunction; using TupleOrArrayFunctionLinfDistance = TupleOrArrayFunction; using TupleOrArrayFunctionCosineDistance = TupleOrArrayFunction; @@ -1221,21 +1346,25 @@ void registerVectorFunctions(FunctionFactory & factory) factory.registerFunction(); factory.registerFunction(); + factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); factory.registerAlias("normL1", TupleOrArrayFunctionL1Norm::name, FunctionFactory::CaseInsensitive); factory.registerAlias("normL2", TupleOrArrayFunctionL2Norm::name, FunctionFactory::CaseInsensitive); + factory.registerAlias("normL2Squared", TupleOrArrayFunctionL2SquaredNorm::name, FunctionFactory::CaseInsensitive); factory.registerAlias("normLinf", TupleOrArrayFunctionLinfNorm::name, FunctionFactory::CaseInsensitive); factory.registerAlias("normLp", FunctionLpNorm::name, FunctionFactory::CaseInsensitive); factory.registerFunction(); factory.registerFunction(); + factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); factory.registerAlias("distanceL1", FunctionL1Distance::name, FunctionFactory::CaseInsensitive); factory.registerAlias("distanceL2", FunctionL2Distance::name, FunctionFactory::CaseInsensitive); + factory.registerAlias("distanceL2Squared", FunctionL2SquaredDistance::name, FunctionFactory::CaseInsensitive); factory.registerAlias("distanceLinf", FunctionLinfDistance::name, FunctionFactory::CaseInsensitive); factory.registerAlias("distanceLp", FunctionLpDistance::name, FunctionFactory::CaseInsensitive); diff --git a/tests/queries/0_stateless/02011_tuple_vector_functions.reference b/tests/queries/0_stateless/02011_tuple_vector_functions.reference index 4c5067c7da2..1b54179cc87 100644 --- a/tests/queries/0_stateless/02011_tuple_vector_functions.reference +++ b/tests/queries/0_stateless/02011_tuple_vector_functions.reference @@ -21,7 +21,9 @@ 6 7.1 1.4142135623730951 +2 13 +169 1.5 -3 2.3 @@ -34,8 +36,10 @@ 2.0000887587111964 4 2.8284271247461903 +8 1 0 +0 -4.413254828250501e-8 (0.2,-0.8) (0.6,0.8) @@ -48,6 +52,7 @@ (NULL,NULL) \N \N +\N (2,4,NULL) \N \N diff --git a/tests/queries/0_stateless/02011_tuple_vector_functions.sql b/tests/queries/0_stateless/02011_tuple_vector_functions.sql index f34fb91586c..14f013937bb 100644 --- a/tests/queries/0_stateless/02011_tuple_vector_functions.sql +++ b/tests/queries/0_stateless/02011_tuple_vector_functions.sql @@ -28,7 +28,9 @@ SELECT scalarProduct(tuple(1), tuple(0)); SELECT L1Norm((-1, 2, -3)); SELECT L1Norm((-1, 2.5, -3.6)); SELECT L2Norm((1, 1.0)); +SELECT L2SquaredNorm((1, 1.0)); SELECT L2Norm(materialize((-12, 5))); +SELECT L2SquaredNorm(materialize((-12, 5))); SELECT max2(materialize(1), 1.5); SELECT min2(-1, -3); @@ -44,8 +46,10 @@ SELECT LpNorm((-1, -2), 11.); SELECT L1Distance((1, 2, 3), (2, 3, 1)); SELECT L2Distance(materialize((1, 1)), (3, -1)); +SELECT L2SquaredDistance(materialize((1, 1)), (3, -1)); SELECT LinfDistance((1, 1), (1, 2)); SELECT L2Distance((5, 5), (5, 5)); +SELECT L2SquaredDistance((5, 5), (5, 5)); SELECT LpDistance((1800, 1900), (18, 59), 12) - LpDistance(tuple(-22), tuple(1900), 12.); SELECT L1Normalize(materialize((1, -4))); @@ -61,6 +65,7 @@ SELECT cosineDistance((1, 0), (0.5, sqrt(3) / 2)); SELECT (NULL, 1) + (1, NULL); SELECT (NULL, 1) * materialize((1, NULL)); SELECT L2Norm((NULL, 3, 4)); +SELECT L2SquaredNorm((NULL, 3, 4)); SELECT 2 * (1, 2, NULL); SELECT (1, 1.0, NULL) / NULL; SELECT (1, 1.0, NULL) / materialize(NULL); diff --git a/tests/queries/0_stateless/02282_array_distance.reference b/tests/queries/0_stateless/02282_array_distance.reference index ebce2788fe9..e5bc46df295 100644 --- a/tests/queries/0_stateless/02282_array_distance.reference +++ b/tests/queries/0_stateless/02282_array_distance.reference @@ -1,17 +1,22 @@ 6 3.7416573867739413 +14 3.2071843327373397 3 0.00258509695694209 \N +\N nan -0 0 0 0 +0 0 0 0 0 12 14 21 7.0710678118654755 9.16515138991168 12.12435565298214 +50 +84 +147 5.917593844525055 8.308858759453505 9.932246380845738 @@ -27,21 +32,21 @@ nan 0.020204102886728692 0.11808289631180313 0 -1 1 218.74642854227358 -1 2 1348.2117786164013 -2 1 219.28064210048274 -2 2 1347.4008312302617 -3 1 214.35251339790725 -3 2 1342.8856987845243 -1 1 218.74642854227358 -1 2 1348.2117786164013 -2 1 219.28064210048274 -2 2 1347.4008312302617 -3 1 214.35251339790725 -3 2 1342.8856987845243 -1 1 218.74642854227358 -1 2 1348.2117786164013 -2 1 219.28064210048274 -2 2 1347.4008312302617 -3 1 214.35251339790725 -3 2 1342.8856987845243 +1 1 218.74642854227358 47850 +1 2 1348.2117786164013 1817675 +2 1 219.28064210048274 48084 +2 2 1347.4008312302617 1815489 +3 1 214.35251339790725 45947 +3 2 1342.8856987845243 1803342 +1 1 218.74642854227358 47850 +1 2 1348.2117786164013 1817675 +2 1 219.28064210048274 48084 +2 2 1347.4008312302617 1815489 +3 1 214.35251339790725 45947 +3 2 1342.8856987845243 1803342 +1 1 218.74642854227358 47850 +1 2 1348.2117786164013 1817675 +2 1 219.28064210048274 48084 +2 2 1347.4008312302617 1815489 +3 1 214.35251339790725 45947 +3 2 1342.8856987845243 1803342 diff --git a/tests/queries/0_stateless/02282_array_distance.sql b/tests/queries/0_stateless/02282_array_distance.sql index 75e4b0d653e..431704abd40 100644 --- a/tests/queries/0_stateless/02282_array_distance.sql +++ b/tests/queries/0_stateless/02282_array_distance.sql @@ -1,10 +1,12 @@ SELECT L1Distance([0, 0, 0], [1, 2, 3]); SELECT L2Distance([1, 2, 3], [0, 0, 0]); +SELECT L2SquaredDistance([1, 2, 3], [0, 0, 0]); SELECT LpDistance([1, 2, 3], [0, 0, 0], 3.5); SELECT LinfDistance([1, 2, 3], [0, 0, 0]); SELECT cosineDistance([1, 2, 3], [3, 5, 7]); SELECT L2Distance([1, 2, 3], NULL); +SELECT L2SquaredDistance([1, 2, 3], NULL); SELECT cosineDistance([1, 2, 3], [0, 0, 0]); -- Overflows @@ -12,6 +14,7 @@ WITH CAST([-547274980, 1790553898, 1981517754, 1908431500, 1352428565, -57341255 SELECT L1Distance(a,a), L2Distance(a,a), + L2SquaredDistance(a,a), LinfDistance(a,a), cosineDistance(a, a); @@ -27,6 +30,7 @@ CREATE TABLE vec2d (id UInt64, v Array(Float64)) ENGINE = Memory; INSERT INTO vec1 VALUES (1, [3, 4, 5]), (2, [2, 4, 8]), (3, [7, 7, 7]); SELECT L1Distance(v, [0, 0, 0]) FROM vec1; SELECT L2Distance(v, [0, 0, 0]) FROM vec1; +SELECT L2SquaredDistance(v, [0, 0, 0]) FROM vec1; SELECT LpDistance(v, [0, 0, 0], 3.14) FROM vec1; SELECT LinfDistance([5, 4, 3], v) FROM vec1; SELECT cosineDistance([3, 2, 1], v) FROM vec1; @@ -34,16 +38,17 @@ SELECT LinfDistance(v, materialize([0, -2, 0])) FROM vec1; SELECT cosineDistance(v, materialize([1., 1., 1.])) FROM vec1; INSERT INTO vec2 VALUES (1, [100, 200, 0]), (2, [888, 777, 666]); -SELECT v1.id, v2.id, L2Distance(v1.v, v2.v) as dist FROM vec1 v1, vec2 v2; +SELECT v1.id, v2.id, L2Distance(v1.v, v2.v), L2SquaredDistance(v1.v, v2.v) as dist FROM vec1 v1, vec2 v2; INSERT INTO vec2f VALUES (1, [100, 200, 0]), (2, [888, 777, 666]); -SELECT v1.id, v2.id, L2Distance(v1.v, v2.v) as dist FROM vec1 v1, vec2f v2; +SELECT v1.id, v2.id, L2Distance(v1.v, v2.v), L2SquaredDistance(v1.v, v2.v) as dist FROM vec1 v1, vec2f v2; INSERT INTO vec2d VALUES (1, [100, 200, 0]), (2, [888, 777, 666]); -SELECT v1.id, v2.id, L2Distance(v1.v, v2.v) as dist FROM vec1 v1, vec2d v2; +SELECT v1.id, v2.id, L2Distance(v1.v, v2.v), L2SquaredDistance(v1.v, v2.v) as dist FROM vec1 v1, vec2d v2; SELECT L1Distance([0, 0], [1]); -- { serverError 190 } SELECT L2Distance([1, 2], (3,4)); -- { serverError 43 } +SELECT L2SquaredDistance([1, 2], (3,4)); -- { serverError 43 } SELECT LpDistance([1, 2], [3,4]); -- { serverError 42 } SELECT LpDistance([1, 2], [3,4], -1.); -- { serverError 69 } SELECT LpDistance([1, 2], [3,4], 'aaa'); -- { serverError 43 } diff --git a/tests/queries/0_stateless/02283_array_norm.reference b/tests/queries/0_stateless/02283_array_norm.reference index ebaadee321f..86a77e27172 100644 --- a/tests/queries/0_stateless/02283_array_norm.reference +++ b/tests/queries/0_stateless/02283_array_norm.reference @@ -1,28 +1,29 @@ 6 7.0710678118654755 +50 10.882246697870885 2 -10803059573 4234902446.7343364 10803059573 4234902446.7343364 3122003357.3280888 2096941042 -1 7 5 4.601724723020627 4 -2 2 2 2 2 -3 9 5.196152422706632 4.506432087111623 3 -4 0 0 0 0 +10803059573 4234902446.7343364 17934398733356468000 10803059573 4234902446.7343364 3122003357.3280888 2096941042 +1 7 5 25 4.601724723020627 4 +2 2 2 4 2 2 +3 9 5.196152422706632 27 4.506432087111623 3 +4 0 0 0 0 0 1 11 2 11 3 11 4 11 -1 7 5 4.601724723020627 4 -2 2 2 2 2 -3 9 5.196152422706632 4.506432087111623 3 -4 0 0 0 0 +1 7 5 25 4.601724723020627 4 +2 2 2 4 2 2 +3 9 5.196152422706632 27 4.506432087111623 3 +4 0 0 0 0 0 1 11 2 11 3 11 4 11 -1 7 5 4.601724723020627 4 -2 2 2 2 2 -3 9 5.196152422706632 4.506432087111623 3 -4 0 0 0 0 +1 7 5 25 4.601724723020627 4 +2 2 2 4 2 2 +3 9 5.196152422706632 27 4.506432087111623 3 +4 0 0 0 0 0 1 11 2 11 3 11 diff --git a/tests/queries/0_stateless/02283_array_norm.sql b/tests/queries/0_stateless/02283_array_norm.sql index 6938618d633..2f5753f9943 100644 --- a/tests/queries/0_stateless/02283_array_norm.sql +++ b/tests/queries/0_stateless/02283_array_norm.sql @@ -1,5 +1,6 @@ SELECT L1Norm([1, 2, 3]); SELECT L2Norm([3., 4., 5.]); +SELECT L2SquaredNorm([3., 4., 5.]); SELECT LpNorm([3., 4., 5.], 1.1); SELECT LinfNorm([0, 0, 2]); @@ -8,6 +9,7 @@ WITH CAST([-547274980, 1790553898, 1981517754, 1908431500, 1352428565, -57341255 SELECT L1Norm(a), L2Norm(a), + L2SquaredNorm(a), LpNorm(a,1), LpNorm(a,2), LpNorm(a,3.14), @@ -23,13 +25,13 @@ INSERT INTO vec1 VALUES (1, [3, 4]), (2, [2]), (3, [3, 3, 3]), (4, NULL); INSERT INTO vec1f VALUES (1, [3, 4]), (2, [2]), (3, [3, 3, 3]), (4, NULL); INSERT INTO vec1d VALUES (1, [3, 4]), (2, [2]), (3, [3, 3, 3]), (4, NULL); -SELECT id, L1Norm(v), L2Norm(v), LpNorm(v, 2.7), LinfNorm(v) FROM vec1; +SELECT id, L1Norm(v), L2Norm(v), L2SquaredNorm(v), LpNorm(v, 2.7), LinfNorm(v) FROM vec1; SELECT id, L1Norm(materialize([5., 6.])) FROM vec1; -SELECT id, L1Norm(v), L2Norm(v), LpNorm(v, 2.7), LinfNorm(v) FROM vec1f; +SELECT id, L1Norm(v), L2Norm(v), L2SquaredNorm(v), LpNorm(v, 2.7), LinfNorm(v) FROM vec1f; SELECT id, L1Norm(materialize([5., 6.])) FROM vec1f; -SELECT id, L1Norm(v), L2Norm(v), LpNorm(v, 2.7), LinfNorm(v) FROM vec1d; +SELECT id, L1Norm(v), L2Norm(v), L2SquaredNorm(v), LpNorm(v, 2.7), LinfNorm(v) FROM vec1d; SELECT id, L1Norm(materialize([5., 6.])) FROM vec1d; SELECT L1Norm(1, 2); -- { serverError 42 }