void ExperimentalTrajectory::calculateVarianceParameters()
{
    numberOfKernels = nWaypoints;

    maxCovariance = ( waypoints - waypoints.rowwise().mean().replicate(1, waypoints.cols()) ).array().square().rowwise().sum() / (waypoints.cols() - 1) ;


    kernelCenters = Eigen::VectorXd::Zero(numberOfKernels);
    for(int i=0; i<numberOfKernels-1; i++){
        kernelCenters(i+1) = kernelCenters(i) + pointToPointDurationVector(i);
    }

    designMatrix = kernelFunction(kernelCenters);
    designMatrixInv = designMatrix.inverse();



    calculateRbfnWeights();
    varianceStartTrigger = true;

    // std::cout << "rbfn weights: " << rbfnWeights << std::endl;
    // std::cout << "maxCovariance\n" << maxCovariance << std::endl;
    // std::cout << "kernelLengthParameter\n" << kernelLengthParameter << std::endl;
    // std::cout << "kernelCenters\n" << kernelCenters << std::endl;

}
Eigen::MatrixXd ExperimentalTrajectory::kernelFunction(Eigen::VectorXd& evalVec)
{
    int sizeVec = evalVec.rows();
    int nC = kernelCenters.rows();
    int nS = maxCovariance.rows();

    Eigen::MatrixXd blockDiagonalResult = Eigen::MatrixXd::Zero((nS*sizeVec), (nS*nC));

    for(int i=0; i<sizeVec; i++)
    {
        blockDiagonalResult.middleRows(i*nS, nS) = kernelFunction(evalVec(i));
    }

    return blockDiagonalResult;

}
UMatrix_Float* AImportVectorMachine::makeRegressorMatrix( const FSupervisedLearnDataEntrySet& data ) const
{
	UMatrix_Float* regMatrix = NewObject<UMatrix_Float>();
	regMatrix->AddInitialized(data.Entries.Num(), data.Entries.Num());
	float sigma = 1;

	for (int32 x = 0; x < data.Entries.Num(); x++)
	{
		float* col = &regMatrix->Rows[x].Columns[0];
		for (int32 y = 0; y < data.Entries.Num(); y++)
		{
			*col = kernelFunction(data.Entries[x].Input, data.Entries[y].Input );
			col++;
		}
	}

	return regMatrix;
}
Eigen::VectorXd ExperimentalTrajectory::getVariance(double time)
{
    if (varianceStartTrigger) {
        t0_variance = time;
        varianceStartTrigger = false;
    }


    double t = time - t0_variance;


    Eigen::VectorXd variance;

    if (t<=pointToPointDurationVector.sum()) {
        Eigen::MatrixXd Ks = kernelFunction(t);
        variance = maxCovariance - (Ks * designMatrixInv * Ks.transpose()).diagonal();
    }
    else{
        variance = Eigen::VectorXd::Zero(maxCovariance.rows());
    }

    return variance;
}