protected function highAffinities(Matrix $distances) : Matrix
    {
        $zeros = array_fill(0, count($distances), 0);

        $p = [];

        foreach ($distances as $i => $row) {
            $affinities = $zeros;
            $minBeta = -INF;
            $maxBeta = INF;
            $beta = 1.;

            for ($l = 0; $l < self::BINARY_PRECISION; $l++) {
                $affinities = [];
                $pSigma = 0.;

                foreach ($row as $j => $distance) {
                    if ($i !== $j) {
                        $affinity = exp(-$distance * $beta);
                    } else {
                        $affinity = 0.;
                    }

                    $affinities[] = $affinity;
                    $pSigma += $affinity;
                }

                if ($pSigma === 0.) {
                    $pSigma = EPSILON;
                }

                $distSigma = 0.;

                foreach ($affinities as $j => &$prob) {
                    $prob /= $pSigma;
                    $distSigma += $row[$j] * $prob;
                }

                $entropy = log($pSigma) + $beta * $distSigma;

                $diff = $entropy - $this->entropy;

                if (abs($diff) < self::SEARCH_TOLERANCE) {
                    break 1;
                }

                if ($diff > 0.) {
                    $minBeta = $beta;

                    if ($maxBeta === INF) {
                        $beta *= 2.;
                    } else {
                        $beta = ($beta + $maxBeta) / 2.;
                    }
                } else {
                    $maxBeta = $beta;

                    if ($minBeta === -INF) {
                        $beta /= 2.;
                    } else {
                        $beta = ($beta + $minBeta) / 2.;
                    }
                }
            }

            $p[] = $affinities;
        }

        $p = Matrix::quick($p);

        $pHat = $p->add($p->transpose());

        $sigma = $pHat->sum()
            ->clipLower(EPSILON);

        return $pHat->divide($sigma);
    }
protected function highAffinities(Matrix $distances) : Matrix
    {
        $zeros = array_fill(0, count($distances), 0);

        $p = [];

        foreach ($distances as $i => $row) {
            $affinities = $zeros;
            $minBeta = -INF;
            $maxBeta = INF;
            $beta = 1.;

            for ($l = 0; $l < self::BINARY_PRECISION; $l++) {
                $affinities = [];
                $pSigma = 0.;

                foreach ($row as $j => $distance) {
                    if ($i !== $j) {
                        $affinity = exp(-$distance * $beta);
                    } else {
                        $affinity = 0.;
                    }

                    $affinities[] = $affinity;
                    $pSigma += $affinity;
                }

                if ($pSigma === 0.) {
                    $pSigma = EPSILON;
                }

                $distSigma = 0.;

                foreach ($affinities as $j => &$prob) {
                    $prob /= $pSigma;
                    $distSigma += $row[$j] * $prob;
                }

                $entropy = log($pSigma) + $beta * $distSigma;

                $diff = $entropy - $this->entropy;

                if (abs($diff) < self::SEARCH_TOLERANCE) {
                    break 1;
                }

                if ($diff > 0.) {
                    $minBeta = $beta;

                    if ($maxBeta === INF) {
                        $beta *= 2.;
                    } else {
                        $beta = ($beta + $maxBeta) / 2.;
                    }
                } else {
                    $maxBeta = $beta;

                    if ($minBeta === -INF) {
                        $beta /= 2.;
                    } else {
                        $beta = ($beta + $minBeta) / 2.;
                    }
                }
            }

            $p[] = $affinities;
        }

        $p = Matrix::quick($p);

        $pHat = $p->add($p->transpose());

        $sigma = $pHat->sum()
            ->clipLower(EPSILON);

        return $pHat->divide($sigma);
    }
protected function highAffinities ( Matrix $ distances ) : Matrix { $ zeros = array_fill ( 0 , count ( $ distances ) , 0 ) ; $ p = [ ] ; foreach ( $ distances as $ i => $ row ) { $ affinities = $ zeros ; $ minBeta = - INF ; $ maxBeta = INF ; $ beta = 1. ; for ( $ l = 0 ; $ l < self :: BINARY_PRECISION ; $ l ++ ) { $ affinities = [ ] ; $ pSigma = 0. ; foreach ( $ row as $ j => $ distance ) { if ( $ i !== $ j ) { $ affinity = exp ( - $ distance * $ beta ) ; } else { $ affinity = 0. ; } $ affinities [ ] = $ affinity ; $ pSigma += $ affinity ; } if ( $ pSigma === 0. ) { $ pSigma = EPSILON ; } $ distSigma = 0. ; foreach ( $ affinities as $ j => & $ prob ) { $ prob /= $ pSigma ; $ distSigma += $ row [ $ j ] * $ prob ; } $ entropy = log ( $ pSigma ) + $ beta * $ distSigma ; $ diff = $ entropy - $ this -> entropy ; if ( abs ( $ diff ) < self :: SEARCH_TOLERANCE ) { break 1 ; } if ( $ diff > 0. ) { $ minBeta = $ beta ; if ( $ maxBeta === INF ) { $ beta *= 2. ; } else { $ beta = ( $ beta + $ maxBeta ) / 2. ; } } else { $ maxBeta = $ beta ; if ( $ minBeta === - INF ) { $ beta /= 2. ; } else { $ beta = ( $ beta + $ minBeta ) / 2. ; } } } $ p [ ] = $ affinities ; } $ p = Matrix :: quick ( $ p ) ; $ pHat = $ p -> add ( $ p -> transpose ( ) ) ; $ sigma = $ pHat -> sum ( ) -> clipLower ( EPSILON ) ; return $ pHat -> divide ( $ sigma ) ; }
Calculate the joint likelihood of each sample in the high dimensional
space as being nearest neighbor to each other sample.

@param \Rubix\Tensor\Matrix $distances
@return \Rubix\Tensor\Matrix
Calculate the joint likelihood of each sample in the high dimensional space as being nearest neighbor to each other sample .