Return the similarity using the JaroWinkler algorithm
@param string $text1
@param string $text2
@return real
436110
public function similarity($text1, $text2)
    {
        if($text1 === $text2) {
            return 1.0;
        }
        
        // ensure that s1 is shorter than or same length as s2
        if (strlen($text1) > strlen($text2)) {
            $tmp = $text1;
            $text1 = $text2;
            $text2 = $tmp;
        }

        $strLen1 = strlen($text1);
        $strLen2 = strlen($text2);
        
        $maxDistance = (int)$strLen2 / 2;
        $commonCounter = 0; // count of common characters
        $transpositionCounter = 0; // count of transpositions
        $prevPosition = -1;
        for ($index = 0; $index < $strLen1; $index++) 
        {
            $char = $text1[$index];
            // init inner loop 
            $jindex = max(0, $index - $maxDistance);
            while($jindex < min($strLen2, $index + $maxDistance))
            {
                if ($char === $text2[$jindex]) {
                    $commonCounter++; // common char found
                    if ($prevPosition != -1 && $jindex < $prevPosition) {
                        $transpositionCounter++; 
                    }
                  $prevPosition = $jindex;
                  break;
                }
                
                $jindex++;
            }
        }
        // no common characters between strings
        if($commonCounter === 0) {
            return 0.0;
        }
        
        // first compute the score
        $score = (
                ($commonCounter / $strLen1) +
                ($commonCounter / $strLen2) +
               (($commonCounter - $transpositionCounter) / $commonCounter)) / 3.0;

        //init values
        $prefixLength = 0; // length of prefix
        $last = min($this->minPrefixLength, $strLen1);        
        while($prefixLength < $last && $text1[$prefixLength] == $text2[$prefixLength])
        {
            $prefixLength++;
        }
        
        return $score + (($prefixLength * (1 - $score)) / 10);     
    }
286159
public char match(String str1, String str2) {
        if (str1 == null || str2 == null)
            return IMappingElement.IDK;
        if (str1.equals(str2)) {
            return IMappingElement.EQUIVALENCE;
        } else
            return IMappingElement.IDK;
    }
317061
@Override
    public double similarity(String label1, String label2) {
        if (label1 == null || label2 == null) {
            log.debug("LABELS: " + label1 + ": " + (label1 == null ? "null" : "exists") + ";" + label2 + " vec2:"
                            + (label2 == null ? "null" : "exists"));
            return Double.NaN;
        }

        INDArray vec1 = getWordVectorMatrix(label1).dup();
        INDArray vec2 = getWordVectorMatrix(label2).dup();

        if (vec1 == null || vec2 == null) {
            log.debug(label1 + ": " + (vec1 == null ? "null" : "exists") + ";" + label2 + " vec2:"
                            + (vec2 == null ? "null" : "exists"));
            return Double.NaN;
        }

        if (label1.equals(label2))
            return 1.0;

        vec1 = Transforms.unitVec(vec1);
        vec2 = Transforms.unitVec(vec2);

        return Transforms.cosineSim(vec1, vec2);
    }
264819
public function DeepEqualByNavigator( $nav1, $nav2 )
	{
		/**
		 * @var XPathNodeIterator $iter1
		 * @var XPathNodeIterator $iter2
		 */
		// $iter1 = $nav1->SelectChildrenByType( XPathNodeType::All );
		// $iter2 = $nav2->SelectChildrenByType( XPathNodeType::All );

		$nodeTest = null; // XmlQualifiedNameTest::create();
		$iter1 = ChildNodeIterator::fromNodeTest( $this->context, $nodeTest, XPath2NodeIterator::Create( $nav1 ) );
		$iter1->excludeComments = true; // $this->excludeComments;
		$iter1->excludeWhitespace = $this->excludeWhitespace;

		$iter2 = ChildNodeIterator::fromNodeTest( $this->context, $nodeTest, XPath2NodeIterator::Create( $nav2 ) );
		$iter2->excludeComments = true; // $this->excludeComments;
		$iter2->excludeWhitespace = $this->excludeWhitespace;

		$leftCount = $iter1->getCount();
		$rightCount = $iter2->getCount();

		if ( $leftCount != $rightCount )
		{
			// Maybe one or both iterators have skipped comments and all the nodes are text nodes.
			// If this is the case join them to see if they compare.
			$leftTextCount = $iter1->getCountType( XPathNodeType::Text );
			$rightTextCount = $iter2->getCountType( XPathNodeType::Text );

			if ( $leftTextCount != $leftCount ) return false;
			if ( $rightTextCount != $rightCount ) return false;

			// By this time all the nodes are text so see if when concatenated they are equal
			$text1 = ExtFuncs::StringJoin( $iter1, "" );
			$text2 = ExtFuncs::StringJoin( $iter2, "" );

			return $text1 == $text2;
		}

		$leftElementCount = $iter1->getCountType( XPathNodeType::Element );

		if ( $leftElementCount )
		{
			$textMatched = $nav1->getValue() == $nav2->getValue();

			return $this->DeepEqualByIterator( $iter1, $iter2, $textMatched );
		}

		if ( ! $this->ItemEqual( $nav1, $nav2 ) )
		{
			return false;
		}
		return true;
	}
387165
public static function keyMatch($key1, $key2)
    {
        if (false === strpos($key2, '*')) {
            return $key1 == $key2;
        }

        $needle = rtrim($key2, '*');

        return substr($key1, 0, \strlen($needle)) === (string) $needle;
    }
454361
public function compare($object1, $object2)
    {
        if (! is_scalar($object1) && ! is_null($object1)) {
            throw new ComparatorException('$object1 (type: ' . gettype($object1) . ') is not a primitive numeric type.');
        }
        if (! is_scalar($object2) && ! is_null($object2)) {
            throw new ComparatorException('$object2 (type: ' . gettype($object2) . ') is not a primitive numeric type.');
        }
        if (1 * $object1 < 1 * $object2) {
            return - 1;
        } elseif (1 * $object1 > 1 * $object2) {
            return 1;
        } else {
            return 0;
        }
    }
1359107
public static function diffAssocRecursive($array1, $array2)
    {
        $difference = array();

        foreach ($array1 as $key => $value) {
            if (is_array($value)) {
                if (!isset($array2[$key]) || !is_array($array2[$key])) {
                    $difference[$key] = $value;
                } else {
                    $new_diff = self::diffAssocRecursive($value, $array2[$key]);
                    if (!empty($new_diff)) {
                        $difference[$key] = $new_diff;
                    }
                }
            } elseif (!array_key_exists($key, $array2) || $array2[$key] !== $value) {
                $difference[$key] = $value;
            }
        }

        return $difference;
    }
411833
private function performCompare($image1, $image2)
    {
        $result = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR);
        return $result[1];
    }
422983
public static boolean nullSafeEquals(String text1, String text2) {
        if (text1 == null || text2 == null) {
            return false;
        } else {
            return text1.equals(text2);
        }
    }
1227377
public static function compareStr($str1, $str2) {
		$len1 = static::binaryStrlen($str1);
		$len2 = static::binaryStrlen($str2);
		$len = min($len1, $len2);
		$diff = $len1 ^ $len2;

		for ($i = 0; $i < $len; $i++) {
			$diff |= ord($str1[$i]) ^ ord($str2[$i]);
		}

		return $diff === 0;
	}
1306834
private function compareHash( $hash1, $hash2 ) {
		$result = strlen( $hash1 ) ^ strlen( $hash2 );
		$len = min( strlen( $hash1 ), strlen( $hash2 ) ) - 1;
		for ( $i = 0; $i < $len; $i++ ) {
			$result |= ord( $hash1{$i} ) ^ ord( $hash2{$i} );
		}
		return $result == 0;
	}
1358242
public static boolean equalsText(String s1, String s2) {
		if (s1 == null) {
			if (s2 != null) {
				return false;
			}
		} else {
			if (s2 == null) {
				return false;
			}
		}
		if ((s1 != null) && (s2 != null)) {
			s1 = s1.replaceAll("\\s", "").toLowerCase();
			s2 = s2.replaceAll("\\s", "").toLowerCase();
			if (!s1.equals(s2)) {
				return false;
			}
		}
		return true;
	}
42389
def cosine_similarity(sent1: str, sent2: str) -> float:
    

    WORD = re.compile(r'\w+')
    def get_cosine(vec1, vec2):
        intersection = set(vec1.keys()) & set(vec2.keys())
        numerator = sum([vec1[x] * vec2[x] for x in intersection])

        sum1 = sum([vec1[x]**2 for x in vec1.keys()])
        sum2 = sum([vec2[x]**2 for x in vec2.keys()])
        denominator = math.sqrt(sum1) * math.sqrt(sum2)

        if not denominator:
            return 0.0
        else:
            return float(numerator) / denominator

    def text_to_vector(text):
        words = WORD.findall(text)
        return Counter(words)

    vector1 = text_to_vector(sent1)
    vector2 = text_to_vector(sent2)
    cosine = get_cosine(vector1, vector2)

    return cosine
582600
@Override
    public double similarScore(String text1, String text2) {
        if(LOGGER.isDebugEnabled()) {
            LOGGER.debug("文本1：");
            LOGGER.debug("\t" + text1);
            LOGGER.debug("文本2：");
            LOGGER.debug("\t" + text2);
        }
        if(text1 == null || text2 == null){
            //只要有一个文本为null，规定相似度分值为0，表示完全不相等
            return 0.0;
        }
        //分词
        List<Word> words1 = seg(text1);
        List<Word> words2 = seg(text2);
        //计算相似度分值
        return similarScore(words1, words2);
    }
1136764
private static function callbackEquals( $callback1, $callback2 ) {

			if ( is_array( $callback1 ) && is_array( $callback2 ) ) {
				
				if ( count( $callback1 ) == count( $callback2 ) ) {
				
					for ( $i=0, $len = count( $callback1 ); $i<$len; $i++ ) {
						if ( $callback1[$i] != $callback2[$i] ) {
							return false;
						}
					}

					return true;

				} else {
					
					return false;
				
				}

			} else {

				return $callback1 == $callback2;

			}

		}
972992
public static double similarityPercentage(String txt1, String txt2) {
        double sim = similarityChars(txt1, txt2);
        return sim * 200.0 / (txt1.length() + txt2.length());
    }
625206
public static function keyMatch2($key1, $key2)
    {
        $key2 = str_replace(['/*'], ['/.*'], $key2);

        $pattern = '/(.*):[^\/]+(.*)/';
        for (; ;) {
            if (false === strpos($key2, '/:')) {
                break;
            }
            $key2 = preg_replace_callback(
                $pattern,
                function ($m) {
                    return $m[1].'[^\/]+'.$m[2];
                },
                $key2
            );
            $key2 = '^'.$key2.'$';
        }

        return self::regexMatch($key1, $key2);
    }