protected function gradient(Matrix $p, Matrix $y, Matrix $distances) : Matrix
    {
        $q = $distances->square()
            ->divide($this->degrees)
            ->add(1.)
            ->pow((1. + $this->degrees) / -2.);

        $qSigma = $q->sum()->multiply(2.);

        $q = $q->divide($qSigma)
            ->clipLower(EPSILON);

        $pqd = $p->subtract($q)
            ->multiply($distances);

        $c = 2. * (1. + $this->degrees) / $this->degrees;

        $gradient = [];

        foreach ($pqd->asVectors() as $i => $row) {
            $yHat = $y->rowAsVector($i)
                ->subtract($y);
            
            $gradient[] = $row->matmul($yHat)
                ->multiply($c)
                ->row(0);
        }

        return Matrix::quick($gradient);
    }
protected function gradient(Matrix $p, Matrix $y, Matrix $distances) : Matrix
    {
        $q = $distances->square()
            ->divide($this->degrees)
            ->add(1.)
            ->pow((1. + $this->degrees) / -2.);

        $qSigma = $q->sum()->multiply(2.);

        $q = $q->divide($qSigma)
            ->clipLower(EPSILON);

        $pqd = $p->subtract($q)
            ->multiply($distances);

        $c = 2. * (1. + $this->degrees) / $this->degrees;

        $gradient = [];

        foreach ($pqd->asVectors() as $i => $row) {
            $yHat = $y->rowAsVector($i)
                ->subtract($y);
            
            $gradient[] = $row->matmul($yHat)
                ->multiply($c)
                ->row(0);
        }

        return Matrix::quick($gradient);
    }
protected function gradient ( Matrix $ p , Matrix $ y , Matrix $ distances ) : Matrix { $ q = $ distances -> square ( ) -> divide ( $ this -> degrees ) -> add ( 1. ) -> pow ( ( 1. + $ this -> degrees ) / - 2. ) ; $ qSigma = $ q -> sum ( ) -> multiply ( 2. ) ; $ q = $ q -> divide ( $ qSigma ) -> clipLower ( EPSILON ) ; $ pqd = $ p -> subtract ( $ q ) -> multiply ( $ distances ) ; $ c = 2. * ( 1. + $ this -> degrees ) / $ this -> degrees ; $ gradient = [ ] ; foreach ( $ pqd -> asVectors ( ) as $ i => $ row ) { $ yHat = $ y -> rowAsVector ( $ i ) -> subtract ( $ y ) ; $ gradient [ ] = $ row -> matmul ( $ yHat ) -> multiply ( $ c ) -> row ( 0 ) ; } return Matrix :: quick ( $ gradient ) ; }
Compute the gradient of the KL Divergence cost function with respect to
the embedding.

@param \Rubix\Tensor\Matrix $p
@param \Rubix\Tensor\Matrix $y
@param \Rubix\Tensor\Matrix $distances
@return \Rubix\Tensor\Matrix
Compute the gradient of the KL Divergence cost function with respect to the embedding .