class MathFunctions {

    @Description("Cosine similarity between the given sparse vectors")
    @ScalarFunction
    @SqlNullable
    @SqlType(StandardTypes.DOUBLE)
    public static Double cosineSimilarity(
            @OperatorDependency(
                    operator = EQUAL,
                    argumentTypes = {"varchar", "varchar"},
                    convention = @Convention(arguments = {BLOCK_POSITION, BLOCK_POSITION}, result = NULLABLE_RETURN)) BlockPositionEqual varcharEqual,
            @OperatorDependency(
                    operator = HASH_CODE,
                    argumentTypes = "varchar",
                    convention = @Convention(arguments = BLOCK_POSITION, result = FAIL_ON_NULL)) BlockPositionHashCode varcharHashCode,
            @SqlType("map(varchar,double)") Block leftMap,
            @SqlType("map(varchar,double)") Block rightMap)
    {
        Double normLeftMap = mapL2Norm(leftMap);
        Double normRightMap = mapL2Norm(rightMap);

        if (normLeftMap == null || normRightMap == null) {
            return null;
        }

        double dotProduct = mapDotProduct(varcharEqual, varcharHashCode, leftMap, rightMap);

        return dotProduct / (normLeftMap * normRightMap);
    }

    private  MathFunctions();

}