예제 #1
0
void L2Sphere::DiffRetraction(Variable *x, Vector *etax, Variable *y, Vector *xix, Vector *result, bool IsEtaXiSameDir) const
{
	if (IsEtaXiSameDir)
	{
		VectorTransport(x, etax, y, xix, result);

		if (IsEtaXiSameDir && (HasHHR || UpdBetaAlone))
		{
			const double *etaxTV = etax->ObtainReadData();
			const double *xixTV = xix->ObtainReadData();
			double EtatoXi = sqrt(Metric(x, etax, etax) / Metric(x, xix, xix));
			SharedSpace *beta = new SharedSpace(1, 3);
			double *betav = beta->ObtainWriteEntireData();
			betav[0] = sqrt(Metric(x, etax, etax) / Metric(x, result, result)) / EtatoXi;
			betav[1] = Metric(x, etax, etax);
			betav[2] = Metric(x, result, result) * EtatoXi * EtatoXi;
			etax->AddToTempData("beta", beta);

			if (HasHHR)
			{
				Vector *TReta = result->ConstructEmpty();
				result->CopyTo(TReta);
				ScaleTimesVector(x, betav[0] * EtatoXi, TReta, TReta);
				SharedSpace *SharedTReta = new SharedSpace(TReta);
				etax->AddToTempData("betaTReta", SharedTReta);
			}
		}
		return;
	}
	std::cout << "Warning: The differentiated retraction has not been implemented!" << std::endl;
	xix->CopyTo(result);
};
예제 #2
0
void L2Sphere::Retraction(Variable *x, Vector *etax, Variable *result) const
{// exponential mapping
	double norm = sqrt(Metric(x, etax, etax));
	if (norm < std::numeric_limits<double>::epsilon())
		ScaleTimesVector(x, cos(norm), x, result);
	else
		VectorLinearCombination(x, cos(norm), x, sin(norm) / norm, etax, result);
};
예제 #3
0
void L2Sphere::ObtainEtaxFlat(Variable *x, Vector *etax, Vector *etaxflat) const
{
	etax->CopyTo(etaxflat);
	double *etaxflatTV = etaxflat->ObtainWritePartialData();
	double intv = 1.0 / (n - 1);
	ScaleTimesVector(x, intv, etaxflat, etaxflat);
	etaxflatTV[0] /= 2;
	etaxflatTV[n - 1] /= 2;
};
예제 #4
0
void ProductManifold::DiffRetraction(Variable *x, Vector *etax, Variable *y, Vector *xix, Vector *result, bool IsEtaXiSameDir) const
{
	ProdVariable *prodx = dynamic_cast<ProdVariable *> (x);
	ProdVector *prodetax = dynamic_cast<ProdVector *> (etax);
	ProdVariable *prody = dynamic_cast<ProdVariable *> (y);
	ProdVector *prodxix = dynamic_cast<ProdVector *> (xix);
	ProdVector *prodresult = dynamic_cast<ProdVector *> (result);
	if (xix == result)
	{
		ProdVector *prodresultTemp = prodresult->ConstructEmpty();
		prodresultTemp->NewMemoryOnWrite();
		for (integer i = 0; i < numofmani; i++)
		{
			for (integer j = powsinterval[i]; j < powsinterval[i + 1]; j++)
			{
				manifolds[i]->DiffRetraction(prodx->GetElement(j), prodetax->GetElement(j), prody->GetElement(j), prodxix->GetElement(j), prodresultTemp->GetElement(j), IsEtaXiSameDir);
			}
		}
		prodresultTemp->CopyTo(prodresult);
		delete prodresultTemp;
	}
	else
	{
		prodresult->NewMemoryOnWrite();
		for (integer i = 0; i < numofmani; i++)
		{
			for (integer j = powsinterval[i]; j < powsinterval[i + 1]; j++)
			{
				manifolds[i]->DiffRetraction(prodx->GetElement(j), prodetax->GetElement(j), prody->GetElement(j), prodxix->GetElement(j), prodresult->GetElement(j), IsEtaXiSameDir);
			}
		}
	}

#ifdef CHECKMEMORY
	prodresult->CheckMemory();
#endif

	if (IsEtaXiSameDir)
	{
		const double *etaxTV = etax->ObtainReadData();
		const double *xixTV = xix->ObtainReadData();
		double EtatoXi = sqrt(Metric(x, etax, etax) / Metric(x, xix, xix));
		SharedSpace *beta = new SharedSpace(1, 1);
		double *betav = beta->ObtainWriteEntireData();
		betav[0] = sqrt(Metric(x, etax, etax) / Metric(x, result, result)) / EtatoXi;
		etax->AddToTempData("beta", beta);

		Vector *TReta = result->ConstructEmpty();
		result->CopyTo(TReta);
		ScaleTimesVector(x, betav[0] * EtatoXi, TReta, TReta);
		SharedSpace *SharedTReta = new SharedSpace(TReta);
		etax->AddToTempData("betaTReta", SharedTReta);
	}
};
예제 #5
0
void L2Sphere::InverseVectorTransport(Variable *x, Vector *etax, Variable *y, Vector *xiy, Vector *result) const
{
	if (!etax->TempDataExist("xdydn2"))
	{
		Vector *xdy = x->ConstructEmpty();
		SharedSpace *Sharedxdy = new SharedSpace(xdy);
		VectorAddVector(x, x, y, xdy);
		ScaleTimesVector(x, 1.0 / Metric(x, xdy, xdy), xdy, xdy);
		etax->AddToTempData("xdydn2", Sharedxdy);
	}
	const SharedSpace *Sharedxdydn2 = etax->ObtainReadTempData("xdydn2");
	Vector *xdydn2 = Sharedxdydn2->GetSharedElement();
	scalarVectorAddVector(x, -2.0 * Metric(x, xiy, x), xdydn2, xiy, result);
};
예제 #6
0
void L2Sphere::TranH(Variable *x, Vector *etax, Variable *y, LinearOPE *Hx, integer start, integer end, LinearOPE *result) const
{
	if (!etax->TempDataExist("xdydn2"))
	{
		Vector *xdy = x->ConstructEmpty();
		SharedSpace *Sharedxdy = new SharedSpace(xdy);
		VectorAddVector(x, x, y, xdy);
		ScaleTimesVector(x, 1.0 / Metric(x, xdy, xdy), xdy, xdy);
		etax->AddToTempData("xdydn2", Sharedxdy);
	}

	integer ell = Hx->Getsize()[0];
	integer length = etax->Getlength();
	const double *M = Hx->ObtainReadData();
	double *Hty = new double[ell];

	Variable *yflat = y->ConstructEmpty();
	y->CopyTo(yflat);
	double *yflatptr = yflat->ObtainWritePartialData();
	yflatptr[0] /= (2 * (n - 1));
	yflatptr[n - 1] /= (2 * (n - 1));
	for (integer i = 1; i < n - 1; i++)
	{
		yflatptr[i] /= (n - 1);
	}

	char *transt = const_cast<char *> ("t");
	double one = 1, zero = 0;
	integer inc = 1, N = ell;
	dgemv_(transt, &length, &N, &one, const_cast<double *> (M + start), &N, yflatptr, &inc, &zero, Hty, &inc);

	double scalar = -2.0;
	Hx->CopyTo(result);


	const SharedSpace *Sharedxdydn2 = etax->ObtainReadTempData("xdydn2");
	Vector *xdydn2 = Sharedxdydn2->GetSharedElement();
	const double *xdydn2TV = xdydn2->ObtainReadData();

	double *resultL = result->ObtainWritePartialData();
	dger_(&length, &N, &scalar, const_cast<double *> (xdydn2TV), &inc, Hty, &inc, resultL + start, &N);
	delete[] Hty;
	delete yflat;
};
예제 #7
0
파일: Stiefel.cpp 프로젝트: cran/fdasrvf
void Stiefel::DiffqfRetraction(Variable *x, Vector *etax, Variable *y, Vector *xix, Vector *result, bool IsEtaXiSameDir) const
{
	Vector *extempx = EMPTYEXTR->ConstructEmpty();
	const double *extempxTV;
	if (IsIntrApproach)
	{
		ObtainExtr(x, xix, extempx);
		extempxTV = extempx->ObtainReadData();
	}
	else
	{
		xix->CopyTo(extempx);
		extempxTV = extempx->ObtainWritePartialData();
	}
	const double *yM = y->ObtainReadData();
	double *resultTV = result->ObtainWriteEntireData();
	const SharedSpace *HHR = y->ObtainReadTempData("HHR");
	const double *ptrHHR = HHR->ObtainReadData();
	double *YtVRinv = new double[p * p];
	integer inc = 1, N = n, P = p;
	char *left = const_cast<char *> ("r"), *up = const_cast<char *> ("u"),
		*transn = const_cast<char *> ("n"), *transt = const_cast<char *> ("t"), *nonunit = const_cast<char *> ("n");
	double one = 1, zero = 0;
	dtrsm_(left, up, transn, nonunit, &N, &P, &one, const_cast<double *> (ptrHHR), &N, const_cast<double *> (extempxTV), &N);

	double sign;
	for (integer i = 0; i < P; i++)
	{
		sign = (ptrHHR[i + i * N] >= 0) ? 1 : -1;
		dscal_(&N, &sign, const_cast<double *> (extempxTV + i * N), &inc);
	}
	dgemm_(transt, transn, &P, &P, &N, &one, const_cast<double *> (yM), &N, const_cast<double *> (extempxTV), &N, &zero, YtVRinv, &P);
	for (integer i = 0; i < p; i++)
	{
		YtVRinv[i + p * i] = -YtVRinv[i + p * i];
		for (integer j = i + 1; j < p; j++)
		{
			YtVRinv[i + p * j] = -YtVRinv[j + p * i] - YtVRinv[i + p * j];
			YtVRinv[j + p * i] = 0;
		}
	}
	dgemm_(transn, transn, &N, &P, &P, &one, const_cast<double *> (yM), &N, YtVRinv, &P, &one, const_cast<double *> (extempxTV), &N);
	if (IsIntrApproach)
	{
		ObtainIntr(y, extempx, result);
	}
	else
	{
		extempx->CopyTo(result);
	}
	delete[] YtVRinv;
	delete extempx;

	if (IsEtaXiSameDir && (HasHHR || UpdBetaAlone))
	{
		const double *etaxTV = etax->ObtainReadData();
		const double *xixTV = xix->ObtainReadData();
		double EtatoXi = sqrt(Metric(x, etax, etax) / Metric(x, xix, xix));
		SharedSpace *beta = new SharedSpace(1, 3);
		double *betav = beta->ObtainWriteEntireData();
		betav[0] = sqrt(Metric(x, etax, etax) / Metric(x, result, result)) / EtatoXi;
		betav[1] = Metric(x, etax, etax);
		betav[2] = Metric(x, result, result) * EtatoXi * EtatoXi;
		etax->AddToTempData("beta", beta);

		if (HasHHR)
		{
			Vector *TReta = result->ConstructEmpty();
			result->CopyTo(TReta);
			ScaleTimesVector(x, betav[0] * EtatoXi, TReta, TReta);
			SharedSpace *SharedTReta = new SharedSpace(TReta);
			etax->AddToTempData("betaTReta", SharedTReta);
		}
	}
};