30 #include <Eigen/Eigen>
63 template<
typename Der1,
typename Der2>
66 {
using namespace Eigen; EIGEN_STATIC_ASSERT_LVALUE(Der2); }
69 eigen_assert(cart.cols() == 1 && rtheta.cols() == 1);
70 eigen_assert(cart.rows() == rtheta.rows());
72 const size_t ds = cart.rows()-1;
91 rtheta.
block(1,0,ds-1,1).setZero();
95 Scalar val = pow(cart(ds),2);
96 for (i = ds-1; i >= 1; --i) {
97 val = val + pow(cart(i),2);
101 for (i = 1; i < ds; i++) {
102 rtheta(i) = atan2(sqrt(rtheta(i)), cart(i-1));
106 val = sqrt(pow(cart(ds), 2) + pow(cart(ds-1), 2)) + cart(ds-1);
108 rtheta(ds) = 2.0 * atan2(cart(ds), val);
133 template<
typename Der1,
typename Der2>
137 {
using namespace Eigen; EIGEN_STATIC_ASSERT_LVALUE(Der2); }
143 eigen_assert(cart.cols() == 1 && theta.cols() == 1);
144 eigen_assert(cart.rows() == theta.rows() + 1);
146 const size_t ds = theta.rows();
153 for (i = 0; i < ds; ++i) {
154 cart(i) *= cos(theta(i));
155 cart.
block(i+1, 0, ds+1 - (i+1), 1) *= sin(theta(i));
173 template<
typename Der1,
typename Der2>
176 {
using namespace Eigen; EIGEN_STATIC_ASSERT_LVALUE(Der2); }
179 eigen_assert(cart.cols() == 1 && rtheta.cols() == 1);
180 eigen_assert(cart.rows() == rtheta.rows());
182 const size_t ds = rtheta.rows()-1;
207 template<
typename Der1>
210 const size_t ds = rtheta.rows()-1;
214 for (i = 0; i < ds-1; ++i) {
215 jac *= pow(sin(rtheta(1+i)), (
int)(ds-1-i));
241 template<
typename Der1>
244 const size_t ds = theta.rows();
249 for (i = 0; i < ds-1; ++i) {
250 jac *= pow(sin(theta(i)), (
int)(ds-1-i));
273 template<
typename Der1,
typename Der2>
281 {
using namespace Eigen; EIGEN_STATIC_ASSERT_LVALUE(Der1); }
284 const size_t ds = theta.rows();
285 const size_t n = ds + 1;
287 eigen_assert(theta.cols() == 1);
288 eigen_assert(dxdtheta.rows() == (int)n);
289 eigen_assert(dxdtheta.cols() == (int)ds);
292 sintheta = theta.
array().sin();
294 costheta = theta.
array().cos();
297 for (i = 0; i < ds; ++i) {
298 for (k = 0; k < n; ++k) {
305 }
else if (i == k && k < n - 1) {
308 for (mm = 0; mm <= i; ++mm) {
311 }
else if (i == k && k == n-1) {
314 for (mm = 0; mm < i; ++mm) {
317 }
else if (i < k && k < n-1) {
319 val = costheta(i) * costheta(k);
320 for (mm = 0; mm < k; ++mm) {
329 for (mm = 0; mm < n-1; ++mm) {
357 template<
typename Der1,
typename Der2>
365 {
using namespace Eigen; EIGEN_STATIC_ASSERT_LVALUE(Der1); }
368 const size_t ds = theta.rows();
369 const size_t n = ds + 1;
371 eigen_assert(theta.cols() == 1);
372 eigen_assert(ddxddtheta.rows() == (int)n);
373 eigen_assert(ddxddtheta.cols() == (int)(ds*ds));
376 sintheta = theta.
array().sin();
378 costheta = theta.
array().cos();
381 for (k = 0; k < n; ++k) {
382 for (i = 0; i < ds; ++i) {
383 for (j = 0; j <= i; ++j) {
388 }
else if (i == k && k < n-1) {
390 for (mm = 0; mm <= i; ++mm) {
396 }
else if (i == k && k == n-1) {
399 for (mm = 0; mm <= i; ++mm) {
403 val = costheta(i)*costheta(j);
404 for (mm = 0; mm < i; ++mm) {
411 }
else if (i < k && k < n-1) {
414 for (mm = 0; mm < k; ++mm) {
418 val = costheta(j)*costheta(i)*costheta(k);
419 for (mm = 0; mm < k; ++mm) {
420 if (mm == j || mm == i) {
429 for (mm = 0; mm < n-1; ++mm) {
433 val = costheta(i)*costheta(j);
434 for (mm = 0; mm < n-1; ++mm) {
435 if (mm == i || mm == j) {
443 ddxddtheta(k, i+ds*j) = val;
444 ddxddtheta(k, j+ds*i) = val;
void sphsurf_to_cart(Eigen::MatrixBase< Der2 > &cart, const Eigen::MatrixBase< Der1 > &theta, const typename Eigen::MatrixBase< Der1 >::Scalar R=1.0)
Convert spherical angles to Cartesian coordinates in N dimensions.
Base namespace for the Tomographer project.
void cart_to_sph(Eigen::MatrixBase< Der2 > &rtheta, const Eigen::MatrixBase< Der1 > &cart)
Convert Cartesian coordinates to spherical coordinates in N dimensions.
void sphsurf_diffjac2(Eigen::ArrayBase< Der1 > &ddxddtheta, const Eigen::MatrixBase< Der2 > &theta)
The second order differential of passing from spherical to cartesian coordinates on the sphere of uni...
Eigen::MatrixBase< Der1 >::Scalar surf_sph_jacobian(const Eigen::MatrixBase< Der1 > &theta)
Surface element of the hypersphere.
void sphsurf_diffjac(Eigen::ArrayBase< Der1 > &dxdtheta, const Eigen::MatrixBase< Der2 > &theta)
The differential of passing from spherical to cartesian coordinates on the sphere of unit radius...
Derived & setConstant(const Scalar &value)
Block< Derived > block(Index startRow, Index startCol, Index blockRows, Index blockCols)
ArrayWrapper< Derived > array()
Eigen::MatrixBase< Der1 >::Scalar cart_to_sph_jacobian(const Eigen::MatrixBase< Der1 > &rtheta)
Volume element of the hypersphere.
Eigen::Transpose< Derived > transpose()
void sph_to_cart(Eigen::MatrixBase< Der2 > &cart, const Eigen::MatrixBase< Der1 > &rtheta)
Convert spherical coordinates to Cartesian coordinates in N dimensions.