From 1bb7741e4e4c1990d5d16173faaf00ad394decb9 Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Tue, 29 Aug 2023 10:09:48 -0400 Subject: [PATCH 01/21] Planar Coils are working now --- CMakeLists.txt | 2 +- src/simsopt/geo/curve.py | 40 +- src/simsopt/geo/curveplanarfourier.py | 39 ++ src/simsoptpp/curveplanarfourier.cpp | 632 ++++++++++++++++++++++++ src/simsoptpp/curveplanarfourier.h | 122 +++++ src/simsoptpp/python_curves.cpp | 35 ++ tests/geo/test_curve.py | 10 +- tests/test_files/input.NewConfiguration | 113 +++++ 8 files changed, 986 insertions(+), 7 deletions(-) create mode 100644 src/simsopt/geo/curveplanarfourier.py create mode 100644 src/simsoptpp/curveplanarfourier.cpp create mode 100644 src/simsoptpp/curveplanarfourier.h create mode 100644 tests/test_files/input.NewConfiguration diff --git a/CMakeLists.txt b/CMakeLists.txt index eb573c647..1371d44ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,7 +116,7 @@ pybind11_add_module(${PROJECT_NAME} src/simsoptpp/biot_savart_py.cpp src/simsoptpp/biot_savart_vjp_py.cpp src/simsoptpp/regular_grid_interpolant_3d_py.cpp - src/simsoptpp/curve.cpp src/simsoptpp/curverzfourier.cpp src/simsoptpp/curvexyzfourier.cpp + src/simsoptpp/curve.cpp src/simsoptpp/curverzfourier.cpp src/simsoptpp/curvexyzfourier.cpp src/simsoptpp/curveplanarfourier.cpp src/simsoptpp/surface.cpp src/simsoptpp/surfacerzfourier.cpp src/simsoptpp/surfacexyzfourier.cpp src/simsoptpp/integral_BdotN.cpp src/simsoptpp/dipole_field.cpp src/simsoptpp/permanent_magnet_optimization.cpp diff --git a/src/simsopt/geo/curve.py b/src/simsopt/geo/curve.py index 104d4c1d5..40f48e188 100644 --- a/src/simsopt/geo/curve.py +++ b/src/simsopt/geo/curve.py @@ -11,7 +11,7 @@ from .jit import jit from .plotting import fix_matplotlib_3d -__all__ = ['Curve', 'RotatedCurve', 'curves_to_vtk', 'create_equally_spaced_curves'] +__all__ = ['Curve', 'RotatedCurve', 'curves_to_vtk', 'create_equally_spaced_curves', 'create_equally_spaced_planar_curves'] @jit @@ -879,3 +879,41 @@ def create_equally_spaced_curves(ncurves, nfp, stellsym, R0=1.0, R1=0.5, order=6 curve.x = curve.x # need to do this to transfer data to C++ curves.append(curve) return curves + +def create_equally_spaced_planar_curves(ncurves, nfp, stellsym, R0=1.0, R1=0.5, order=6, numquadpoints=None): + """ + Insert text here + """ + + if numquadpoints is None: + numquadpoints = 15 * order + curves = [] + from simsopt.geo.curveplanarfourier import CurvePlanarFourier + for k in range(ncurves): + angle = k*(2*np.pi) / ((1+int(stellsym))*nfp*ncurves) + curve = CurvePlanarFourier(numquadpoints, order, nfp, stellsym) + + rcCoeffs = np.zeros(order+1) + rcCoeffs[0] = R1 + rsCoeffs = np.zeros(order) + center = [R0 * cos(angle), R0 * sin(angle), 0] + rotation = [1, -cos(angle), -sin(angle), 0] + dofs = np.zeros(len(curve.get_dofs())) + + j = 0 + for i in rcCoeffs: + dofs[j] = i + j += 1 + for i in rsCoeffs: + dofs[j] = i + j += 1 + for i in rotation: + dofs[j] = i + j += 1 + for i in center: + dofs[j] = i + j += 1 + + curve.set_dofs(dofs) + curves.append(curve) + return curves \ No newline at end of file diff --git a/src/simsopt/geo/curveplanarfourier.py b/src/simsopt/geo/curveplanarfourier.py new file mode 100644 index 000000000..78b590548 --- /dev/null +++ b/src/simsopt/geo/curveplanarfourier.py @@ -0,0 +1,39 @@ +import numpy as np + +import simsoptpp as sopp +from .._core.json import GSONDecoder +from .curve import Curve + +__all__ = ['CurvePlanarFourier'] + + +class CurvePlanarFourier(sopp.CurvePlanarFourier, Curve): + r""" + Insert text here + """ + + def __init__(self, quadpoints, order, nfp, stellsym, dofs=None): + if isinstance(quadpoints, int): + quadpoints = list(np.linspace(0, 1., quadpoints, endpoint=False)) + elif isinstance(quadpoints, np.ndarray): + quadpoints = list(quadpoints) + sopp.CurvePlanarFourier.__init__(self, quadpoints, order, nfp, stellsym) + if dofs is None: + Curve.__init__(self, external_dof_setter=CurvePlanarFourier.set_dofs_impl, + x0=self.get_dofs()) + else: + Curve.__init__(self, external_dof_setter=CurvePlanarFourier.set_dofs_impl, + dofs=dofs) + + def get_dofs(self): + """ + This function returns the dofs associated to this object. + """ + return np.asarray(sopp.CurvePlanarFourier.get_dofs(self)) + + def set_dofs(self, dofs): + """ + This function sets the dofs associated to this object. + """ + self.local_x = dofs + sopp.CurvePlanarFourier.set_dofs(self, dofs) diff --git a/src/simsoptpp/curveplanarfourier.cpp b/src/simsoptpp/curveplanarfourier.cpp new file mode 100644 index 000000000..66398db6b --- /dev/null +++ b/src/simsoptpp/curveplanarfourier.cpp @@ -0,0 +1,632 @@ +#include "curveplanarfourier.h" + + +template +void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { + int numquadpoints = quadpoints.size(); + data *= 0; + for (int k = 0; k < numquadpoints; ++k) { + double phi = 2 * M_PI * quadpoints[k]; + for (int i = 0; i < order+1; ++i) { + data(k, 0) += rc[i] * cos(i*phi) * cos(phi); + data(k, 1) += rc[i] * cos(i*phi) * sin(phi); + } + } + for (int k = 0; k < numquadpoints; ++k) { + double phi = 2 * M_PI * quadpoints[k]; + for (int i = 1; i < order+1; ++i) { + data(k, 0) += rs[i-1] * sin(i*phi) * cos(phi); + data(k, 1) += rs[i-1] * sin(i*phi) * sin(phi); + } + } + for (int m = 0; m < numquadpoints; ++m) { + double i; + double j; + double k; + i = data(m, 0); + j = data(m, 1); + k = data(m, 2); + + data(m, 0) = (i - 2 * (q[2] * q[2] + q[3] * q[3]) * i + 2 * (q[1] * q[2] - q[3] * q[0]) * j + 2 * (q[1] * q[3] + q[2] * q[0]) * k) + center[0]; + data(m, 1) = (2 * (q[1] * q[2] + q[3] * q[0]) * i + j - 2 * (q[1] * q[1] + q[3] * q[3]) * j + 2 * (q[2] * q[3] - q[1] * q[0]) * k) + center[1]; + data(m, 2) = (2 * (q[1] * q[3] - q[2] * q[0]) * i + 2 * (q[2] * q[3] + q[1] * q[0]) * j + k - 2 * (q[1] * q[1] + q[2] * q[2]) * k) + center[2]; + } +} + +template +void CurvePlanarFourier::gammadash_impl(Array& data) { + data *= 0; + for (int k = 0; k < numquadpoints; ++k) { + double phi = 2 * M_PI * quadpoints[k]; + for (int i = 0; i < order+1; ++i) { + data(k, 0) += rc[i] * ( -(i) * sin(i*phi) * cos(phi) - cos(i*phi) * sin(phi)); + data(k, 1) += rc[i] * ( -(i) * sin(i*phi) * sin(phi) + cos(i*phi) * cos(phi)); + } + } + for (int k = 0; k < numquadpoints; ++k) { + double phi = 2 * M_PI * quadpoints[k]; + for (int i = 1; i < order+1; ++i) { + data(k, 0) += rs[i-1] * ( (i) * cos(i*phi) * cos(phi) - sin(i*phi) * sin(phi)); + data(k, 1) += rs[i-1] * ( (i) * cos(i*phi) * sin(phi) + sin(i*phi) * cos(phi)); + } + } + data *= (2*M_PI); + for (int m = 0; m < numquadpoints; ++m) { + Array i = xt::zeros({1}); + i[0] = data(m, 0); + Array j = xt::zeros({1}); + j[0] = data(m, 1); + Array k = xt::zeros({1}); + k[0] = data(m, 2); + + data(m, 0) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); + data(m, 1) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); + data(m, 2) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + } + +} + +template +void CurvePlanarFourier::gammadashdash_impl(Array& data) { + data *= 0; + for (int k = 0; k < numquadpoints; ++k) { + double phi = 2 * M_PI * quadpoints[k]; + for (int i = 0; i < order+1; ++i) { + data(k, 0) += rc[i] * (+2*(i)*sin(i*phi)*sin(phi)-(pow(i, 2)+1)*cos(i*phi)*cos(phi)); + data(k, 1) += rc[i] * (-2*(i)*sin(i*phi)*cos(phi)-(pow(i, 2)+1)*cos(i*phi)*sin(phi)); + } + data(k, 2) = 0; + } + for (int k = 0; k < numquadpoints; ++k) { + double phi = 2 * M_PI * quadpoints[k]; + for (int i = 1; i < order+1; ++i) { + data(k, 0) += rs[i-1] * (-(pow(i,2)+1)*sin(i*phi)*cos(phi) - 2*(i)*cos(i*phi)*sin(phi)); + data(k, 1) += rs[i-1] * (-(pow(i,2)+1)*sin(i*phi)*sin(phi) + 2*(i)*cos(i*phi)*cos(phi)); + } + data(k, 2) = 0; + } + data *= 2*M_PI*2*M_PI; + for (int m = 0; m < numquadpoints; ++m) { + Array i = xt::zeros({1}); + i[0] = data(m, 0); + Array j = xt::zeros({1}); + j[0] = data(m, 1); + Array k = xt::zeros({1}); + k[0] = data(m, 2); + + data(m, 0) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); + data(m, 1) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); + data(m, 2) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + + } +} + +template +void CurvePlanarFourier::gammadashdashdash_impl(Array& data) { + data *= 0; + for (int k = 0; k < numquadpoints; ++k) { + double phi = 2 * M_PI * quadpoints[k]; + for (int i = 0; i < order+1; ++i) { + data(k, 0) += rc[i]*( + +(3*pow(i, 2) + 1)*cos(i*phi)*sin(phi) + +(pow(i, 2) + 3)*(i)*sin(i*phi)*cos(phi) + ); + data(k, 1) += rc[i]*( + +(pow(i, 2) + 3)*(i)*sin(i*phi)*sin(phi) + -(3*pow(i, 2) + 1)*cos(i*phi)*cos(phi) + ); + } + } + for (int k = 0; k < numquadpoints; ++k) { + double phi = 2 * M_PI * quadpoints[k]; + for (int i = 1; i < order+1; ++i) { + data(k, 0) += rs[i-1]*( + -(pow(i,2)+3) * (i) * cos(i*phi)*cos(phi) + +(3*pow(i,2)+1) * sin(i*phi)*sin(phi) + ); + data(k, 1) += rs[i-1]*( + -(pow(i,2)+3)*(i)*cos(i*phi)*sin(phi) + -(3*pow(i,2)+1)*sin(i*phi)*cos(phi) + ); + } + } + data *= 2*M_PI*2*M_PI*2*M_PI; + for (int m = 0; m < numquadpoints; ++m) { + Array i = xt::zeros({1}); + i[0] = data(m, 0); + Array j = xt::zeros({1}); + j[0] = data(m, 1); + Array k = xt::zeros({1}); + k[0] = data(m, 2); + + data(m, 0) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); + data(m, 1) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); + data(m, 2) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + + } +} + +template +void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { + data *= 0; + for (int m = 0; m < numquadpoints; ++m) { + double phi = 2 * M_PI * quadpoints[m]; + int counter = 0; + Array i = xt::zeros({1}); + Array j = xt::zeros({1}); + Array k = xt::zeros({1}); + + for (int n = 0; n < order+1; ++n) { + i[0] = cos(n*phi) * cos(phi); + j[0] = cos(n*phi) * sin(phi); + k[0] = 0; + + data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); + data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); + data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + + counter++; + } + + for (int n = 1; n < order+1; ++n) { + i[0] = sin(n*phi) * cos(phi); + j[0] = sin(n*phi) * sin(phi); + k[0] = 0; + + data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); + data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); + data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + + counter++; + } + + i[0] = 0; + j[0] = 0; + k[0] = 0; + + for (int n = 0; n < order+1; ++n) { + i[0] += rc[n] * cos(n*phi) * cos(phi); + j[0] += rc[n] * cos(n*phi) * sin(phi); + } + for (int n = 1; n < order+1; ++n) { + i[0] += rs[n-1] * sin(n*phi) * cos(phi); + j[0] += rs[n-1] * sin(n*phi) * sin(phi); + } + + data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[0] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[0] + - 2 * j[0] * q[3]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[0] + + 2 * i[0] * q[3] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[0]; + data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[0] + - 2 * i[0] * q[2] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[0] + + 2 * j[0] * q[1]; + counter++; + + data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[1] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[1] + + 2 * j[0] * q[2]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[1] + + 2 * i[0] * q[2] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[1] + - 4 * j[0] * q[1]; + data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[1] + + 2 * i[0] * q[3] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[1] + + 2 * j[0] * q[0]; + counter++; + + data(m, 0, counter) = - 4 * i[0] * (q[0] * q[0] + q[1] * q[1]) * q[2] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[2] + + 2 * j[0] * q[1]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[2] + + 2 * i[0] * q[1] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[2]; + data(m, 2, counter) = - 2 * i[0] * q[0] + - 4 * i[0] * (q[1] * q[3] - q[0] * q[2]) * q[2] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[2] + + 2 * j[0] * q[3]; + counter++; + + data(m, 0, counter) = - 4 * i[0] * (q[1] * q[1] + q[0] * q[0]) * q[3] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[3] + - 2 * j[0] * q[0]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[3] + + 2 * i[0] * q[0] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[3] + - 4 * j[0] * q[3]; + data(m, 2, counter) = 2 * i[0] * q[1] + + 4 * i[0] * (q[2] * q[0] - q[1] * q[3]) * q[3] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[3] + + 2 * j[0] * q[2]; + counter++; + + + for (int i = 0; i < 3; ++i) { + data(m, 0, counter) = 0; + data(m, 1, counter) = 0; + data(m, 2, counter) = 0; + data(m, i, counter) = 1; + + counter++; + } + } +} + +template +void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { + data *= 0; + for (int m = 0; m < numquadpoints; ++m) { + double phi = 2 * M_PI * quadpoints[m]; + int counter = 0; + Array i = xt::zeros({1}); + Array j = xt::zeros({1}); + Array k = xt::zeros({1}); + for (int n = 0; n < order+1; ++n) { + i[0] = ( -(n) * sin(n*phi) * cos(phi) - cos(n*phi) * sin(phi)); + j[0] = ( -(n) * sin(n*phi) * sin(phi) + cos(n*phi) * cos(phi)); + k[0] = 0; + + i[0] *= (2*M_PI); + j[0] *= (2*M_PI); + + data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); + data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); + data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + + + counter++; + } + + for (int n = 1; n < order+1; ++n) { + i[0] = ( (n) * cos(n*phi) * cos(phi) - sin(n*phi) * sin(phi)); + j[0] = ( (n) * cos(n*phi) * sin(phi) + sin(n*phi) * cos(phi)); + k[0] = 0; + + i[0] *= (2*M_PI); + j[0] *= (2*M_PI); + + data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); + data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); + data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + + counter++; + + } + + i[0] = 0; + j[0] = 0; + k[0] = 0; + for (int n = 0; n < order+1; ++n) { + i[0] += rc[n] * ( -(n) * sin(n*phi) * cos(phi) - cos(n*phi) * sin(phi)) * 2 * M_PI; + j[0] += rc[n] * ( -(n) * sin(n*phi) * sin(phi) + cos(n*phi) * cos(phi)) * 2 * M_PI; + } + for (int n = 1; n < order+1; ++n) { + i[0] += rs[n-1] * ( (n) * cos(n*phi) * cos(phi) - sin(n*phi) * sin(phi)) * 2 * M_PI; + j[0] += rs[n-1] * ( (n) * cos(n*phi) * sin(phi) + sin(n*phi) * cos(phi)) * 2 * M_PI; + } + + data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[0] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[0] + - 2 * j[0] * q[3]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[0] + + 2 * i[0] * q[3] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[0]; + data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[0] + - 2 * i[0] * q[2] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[0] + + 2 * j[0] * q[1]; + counter++; + + data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[1] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[1] + + 2 * j[0] * q[2]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[1] + + 2 * i[0] * q[2] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[1] + - 4 * j[0] * q[1]; + data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[1] + + 2 * i[0] * q[3] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[1] + + 2 * j[0] * q[0]; + counter++; + + data(m, 0, counter) = - 4 * i[0] * (q[0] * q[0] + q[1] * q[1]) * q[2] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[2] + + 2 * j[0] * q[1]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[2] + + 2 * i[0] * q[1] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[2]; + data(m, 2, counter) = - 2 * i[0] * q[0] + - 4 * i[0] * (q[1] * q[3] - q[0] * q[2]) * q[2] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[2] + + 2 * j[0] * q[3]; + counter++; + + data(m, 0, counter) = - 4 * i[0] * (q[1] * q[1] + q[0] * q[0]) * q[3] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[3] + - 2 * j[0] * q[0]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[3] + + 2 * i[0] * q[0] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[3] + - 4 * j[0] * q[3]; + data(m, 2, counter) = 2 * i[0] * q[1] + + 4 * i[0] * (q[2] * q[0] - q[1] * q[3]) * q[3] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[3] + + 2 * j[0] * q[2]; + counter++; + + for (int i = 0; i < 2; ++i) { + data(m, 0, counter) = 0; + data(m, 1, counter) = 0; + data(m, 2, counter) = 0; + + counter++; + } + + } +} + +template +void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { + data *= 0; + for (int m = 0; m < numquadpoints; ++m) { + double phi = 2 * M_PI * quadpoints[m]; + int counter = 0; + Array i = xt::zeros({1}); + Array j = xt::zeros({1}); + Array k = xt::zeros({1}); + for (int n = 0; n < order+1; ++n) { + i[0] = (+2*(n)*sin(n*phi)*sin(phi)-(pow(n, 2)+1)*cos(n*phi)*cos(phi)); + j[0] = (-2*(n)*sin(n*phi)*cos(phi)-(pow(n, 2)+1)*cos(n*phi)*sin(phi)); + k[0] = 0; + + i[0] *= 2*M_PI*2*M_PI; + j[0] *= 2*M_PI*2*M_PI; + k[0] *= 2*M_PI*2*M_PI; + + data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); + data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); + data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + + counter++; + } + + for (int n = 1; n < order+1; ++n) { + i[0] = (-(pow(n,2)+1)*sin(n*phi)*cos(phi) - 2*(n)*cos(n*phi)*sin(phi)); + j[0] = (-(pow(n,2)+1)*sin(n*phi)*sin(phi) + 2*(n)*cos(n*phi)*cos(phi)); + k[0] = 0; + + i[0] *= 2*M_PI*2*M_PI; + j[0] *= 2*M_PI*2*M_PI; + k[0] *= 2*M_PI*2*M_PI; + + data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); + data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); + data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + + counter++; + } + + i[0] = 0; + j[0] = 0; + k[0] = 0; + for (int n = 0; n < order+1; ++n) { + i[0] += rc[n] * (+2*(n)*sin(n*phi)*sin(phi)-(pow(n, 2)+1)*cos(n*phi)*cos(phi)); + j[0] += rc[n] * (-2*(n)*sin(n*phi)*cos(phi)-(pow(n, 2)+1)*cos(n*phi)*sin(phi)); + } + for (int n = 1; n < order+1; ++n) { + i[0] += rs[n-1] * (-(pow(n,2)+1)*sin(n*phi)*cos(phi) - 2*(n)*cos(n*phi)*sin(phi)); + j[0] += rs[n-1] * (-(pow(n,2)+1)*sin(n*phi)*sin(phi) + 2*(n)*cos(n*phi)*cos(phi)); + } + i[0] *= 2*M_PI*2*M_PI; + j[0] *= 2*M_PI*2*M_PI; + k[0] *= 2*M_PI*2*M_PI; + + data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[0] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[0] + - 2 * j[0] * q[3]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[0] + + 2 * i[0] * q[3] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[0]; + data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[0] + - 2 * i[0] * q[2] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[0] + + 2 * j[0] * q[1]; + counter++; + + data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[1] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[1] + + 2 * j[0] * q[2]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[1] + + 2 * i[0] * q[2] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[1] + - 4 * j[0] * q[1]; + data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[1] + + 2 * i[0] * q[3] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[1] + + 2 * j[0] * q[0]; + counter++; + + data(m, 0, counter) = - 4 * i[0] * (q[0] * q[0] + q[1] * q[1]) * q[2] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[2] + + 2 * j[0] * q[1]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[2] + + 2 * i[0] * q[1] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[2]; + data(m, 2, counter) = - 2 * i[0] * q[0] + - 4 * i[0] * (q[1] * q[3] - q[0] * q[2]) * q[2] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[2] + + 2 * j[0] * q[3]; + counter++; + + data(m, 0, counter) = - 4 * i[0] * (q[1] * q[1] + q[0] * q[0]) * q[3] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[3] + - 2 * j[0] * q[0]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[3] + + 2 * i[0] * q[0] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[3] + - 4 * j[0] * q[3]; + data(m, 2, counter) = 2 * i[0] * q[1] + + 4 * i[0] * (q[2] * q[0] - q[1] * q[3]) * q[3] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[3] + + 2 * j[0] * q[2]; + counter++; + + for (int i = 0; i < 3; ++i) { + data(m, 0, counter) = 0; + data(m, 1, counter) = 0; + data(m, 2, counter) = 0; + + counter++; + } + } +} + +template +void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { + data *= 0; + for (int m = 0; m < numquadpoints; ++m) { + double phi = 2 * M_PI * quadpoints[m]; + int counter = 0; + Array i = xt::zeros({1}); + Array j = xt::zeros({1}); + Array k = xt::zeros({1}); + for (int n = 0; n < order+1; ++n) { + i[0] = ( + +(3*pow(n, 2) + 1)*cos(n*phi)*sin(phi) + +(pow(n, 2) + 3)*(n)*sin(n*phi)*cos(phi) + ); + j[0] = ( + +(pow(n, 2) + 3)*(n)*sin(n*phi)*sin(phi) + -(3*pow(n, 2) + 1)*cos(n*phi)*cos(phi) + ); + k[0] = 0; + + i[0] *= 2*M_PI*2*M_PI*2*M_PI; + j[0] *= 2*M_PI*2*M_PI*2*M_PI; + k[0] *= 2*M_PI*2*M_PI*2*M_PI; + + data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); + data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); + data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + + counter++; + } + + for (int n = 1; n < order+1; ++n) { + i[0] = ( + -(pow(n,2)+3) * (n) * cos(n*phi)*cos(phi) + +(3*pow(n,2)+1) * sin(n*phi)*sin(phi) + ); + j[0] = ( + -(pow(n,2)+3)*(n)*cos(n*phi)*sin(phi) + -(3*pow(n,2)+1)*sin(n*phi)*cos(phi) + ); + k[0] = 0; + + i[0] *= 2*M_PI*2*M_PI*2*M_PI; + j[0] *= 2*M_PI*2*M_PI*2*M_PI; + k[0] *= 2*M_PI*2*M_PI*2*M_PI; + + data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); + data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); + data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + + counter++; + } + + i[0] = 0; + j[0] = 0; + k[0] = 0; + for (int n = 0; n < order+1; ++n) { + i[0] += rc[n]*( + +(3*pow(n, 2) + 1)*cos(n*phi)*sin(phi) + +(pow(n, 2) + 3)*(n)*sin(n*phi)*cos(phi) + ); + j[0] += rc[n]*( + +(pow(n, 2) + 3)*(n)*sin(n*phi)*sin(phi) + -(3*pow(n, 2) + 1)*cos(n*phi)*cos(phi) + ); + } + for (int n = 1; n < order+1; ++n) { + i[0] += rs[n-1]*( + -(pow(n,2)+3) * (n) * cos(n*phi)*cos(phi) + +(3*pow(n,2)+1) * sin(n*phi)*sin(phi) + ); + j[0] += rs[n-1]*( + -(pow(n,2)+3)*(n)*cos(n*phi)*sin(phi) + -(3*pow(n,2)+1)*sin(n*phi)*cos(phi) + ); + } + i[0] *= 2*M_PI*2*M_PI*2*M_PI; + j[0] *= 2*M_PI*2*M_PI*2*M_PI; + k[0] *= 2*M_PI*2*M_PI*2*M_PI; + + data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[0] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[0] + - 2 * j[0] * q[3]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[0] + + 2 * i[0] * q[3] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[0]; + data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[0] + - 2 * i[0] * q[2] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[0] + + 2 * j[0] * q[1]; + counter++; + + data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[1] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[1] + + 2 * j[0] * q[2]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[1] + + 2 * i[0] * q[2] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[1] + - 4 * j[0] * q[1]; + data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[1] + + 2 * i[0] * q[3] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[1] + + 2 * j[0] * q[0]; + counter++; + + data(m, 0, counter) = - 4 * i[0] * (q[0] * q[0] + q[1] * q[1]) * q[2] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[2] + + 2 * j[0] * q[1]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[2] + + 2 * i[0] * q[1] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[2]; + data(m, 2, counter) = - 2 * i[0] * q[0] + - 4 * i[0] * (q[1] * q[3] - q[0] * q[2]) * q[2] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[2] + + 2 * j[0] * q[3]; + counter++; + + data(m, 0, counter) = - 4 * i[0] * (q[1] * q[1] + q[0] * q[0]) * q[3] + - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[3] + - 2 * j[0] * q[0]; + data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[3] + + 2 * i[0] * q[0] + + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[3] + - 4 * j[0] * q[3]; + data(m, 2, counter) = 2 * i[0] * q[1] + + 4 * i[0] * (q[2] * q[0] - q[1] * q[3]) * q[3] + - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[3] + + 2 * j[0] * q[2]; + counter++; + + for (int i = 0; i < 3; ++i) { + data(m, 0, counter) = 0; + data(m, 1, counter) = 0; + data(m, 2, counter) = 0; + + counter++; + } + } +} + + + +#include "xtensor-python/pyarray.hpp" // Numpy bindings +typedef xt::pyarray Array; +template class CurvePlanarFourier; diff --git a/src/simsoptpp/curveplanarfourier.h b/src/simsoptpp/curveplanarfourier.h new file mode 100644 index 000000000..4febd687d --- /dev/null +++ b/src/simsoptpp/curveplanarfourier.h @@ -0,0 +1,122 @@ +#pragma once + +#include "curve.h" + +template +class CurvePlanarFourier : public Curve { + /* + CurvePlanarFourier is a curve that is represented as a plane rotated about the + x and y axis using the following Fourier series: + + r(phi) = \sum_{n=0}^{order} x_{c,n}cos(n*nfp*phi) + \sum_{n=1}^order x_{s,n}sin(n*nfp*phi) + + with rotation about an axis and angle determine by a set of quarternions + q = [cos(\theta/2), x * sin(\theta/2), y * sin(\theta/2), z * sin(\theta/2)] + + The dofs are stored in the order + + [r_{c,0},...,r_{c,order},r_{s,1},...,r_{s,order},t_{x},t_{y}] + + */ + public: + const int order; + const int nfp; + const bool stellsym; + using Curve::quadpoints; + using Curve::numquadpoints; + using Curve::check_the_persistent_cache; + + Array rc; + Array rs; + Array q; + Array center; + + CurvePlanarFourier(int _numquadpoints, int _order, int _nfp, bool _stellsym) : Curve(_numquadpoints), order(_order), nfp(_nfp), stellsym(_stellsym) { + rc = xt::zeros({order + 1}); + rs = xt::zeros({order}); + q = xt::zeros({4}); + center = xt::zeros({3}); + } + + CurvePlanarFourier(vector _quadpoints, int _order, int _nfp, bool _stellsym) : Curve(_quadpoints), order(_order), nfp(_nfp), stellsym(_stellsym) { + rc = xt::zeros({order + 1}); + rs = xt::zeros({order}); + q = xt::zeros({4}); + center = xt::zeros({3}); + } + + CurvePlanarFourier(Array _quadpoints, int _order, int _nfp, bool _stellsym) : Curve(_quadpoints), order(_order), nfp(_nfp), stellsym(_stellsym) { + rc = xt::zeros({order + 1}); + rs = xt::zeros({order}); + q = xt::zeros({4}); + center = xt::zeros({3}); + } + + inline int num_dofs() override { + return (2*order+1)+7; + } + + void set_dofs_impl(const vector& dofs) override { + int counter = 0; + double s = 0; + for (int i = 0; i < order + 1; ++i) + rc.data()[i] = dofs[counter++]; + for (int i = 0; i < order; ++i) + rs.data()[i] = dofs[counter++]; + for (int i = 0; i < 4; ++i){ + q.data()[i] = dofs[counter++]; + s += q[i] * q[i]; + } + /* Converts to unit quaternion */ + if(s != 0) { + for (int i = 0; i < 4; ++i) + q.data()[i] = q[i] / std::sqrt(s); + } + else { + q.data()[0] = 1; + } + for (int i = 0; i < 3; ++i){ + center.data()[i] = dofs[counter++]; + } + } + + vector get_dofs() override { + auto res = vector(num_dofs(), 0.); + int counter = 0; + for (int i = 0; i < order + 1; ++i) + res[counter++] = rc[i]; + for (int i = 0; i < order; ++i) + res[counter++] = rs[i]; + for (int i = 0; i < 4; ++i) + res[counter++] = q[i]; + for (int i = 0; i < 3; ++i) + res[counter++] = center[i]; + return res; + } + + Array& dgamma_by_dcoeff() override { + return check_the_persistent_cache("dgamma_by_dcoeff", {numquadpoints, 3, num_dofs()}, [this](Array& A) { return dgamma_by_dcoeff_impl(A);}); + } + Array& dgammadash_by_dcoeff() override { + return check_the_persistent_cache("dgammadash_by_dcoeff", {numquadpoints, 3, num_dofs()}, [this](Array& A) { return dgammadash_by_dcoeff_impl(A);}); + } + Array& dgammadashdash_by_dcoeff() override { + return check_the_persistent_cache("dgammadashdash_by_dcoeff", {numquadpoints, 3, num_dofs()}, [this](Array& A) { return dgammadashdash_by_dcoeff_impl(A);}); + } + Array& dgammadashdashdash_by_dcoeff() override { + return check_the_persistent_cache("dgammadashdashdash_by_dcoeff", {numquadpoints, 3, num_dofs()}, [this](Array& A) { return dgammadashdashdash_by_dcoeff_impl(A);}); + } + + + void gamma_impl(Array& data, Array& quadpoints) override; + void gammadash_impl(Array& data) override; + void gammadashdash_impl(Array& data) override; + void gammadashdashdash_impl(Array& data) override; + void dgamma_by_dcoeff_impl(Array& data) override; + void dgammadash_by_dcoeff_impl(Array& data) override; + void dgammadashdash_by_dcoeff_impl(Array& data) override; + void dgammadashdashdash_by_dcoeff_impl(Array& data) override; + + + +}; diff --git a/src/simsoptpp/python_curves.cpp b/src/simsoptpp/python_curves.cpp index 58adbecd3..ada7a2225 100644 --- a/src/simsoptpp/python_curves.cpp +++ b/src/simsoptpp/python_curves.cpp @@ -13,6 +13,8 @@ namespace py = pybind11; typedef CurveXYZFourier PyCurveXYZFourier; #include "curverzfourier.h" typedef CurveRZFourier PyCurveRZFourier; +#include "curveplanarfourier.h" +typedef CurvePlanarFourier PyCurvePlanarFourier; template class PyCurveXYZFourierTrampoline : public PyCurveTrampoline { public: @@ -55,6 +57,27 @@ template class PyCurveRZFourierT PyCurveRZFourierBase::gamma_impl(data, quadpoints); } }; + +template class PyCurvePlanarFourierTrampoline : public PyCurveTrampoline { + public: + using PyCurveTrampoline::PyCurveTrampoline; // Inherit constructors + + int num_dofs() override { + return PyCurvePlanarFourierBase::num_dofs(); + } + + void set_dofs_impl(const vector& _dofs) override { + PyCurvePlanarFourierBase::set_dofs_impl(_dofs); + } + + vector get_dofs() override { + return PyCurvePlanarFourierBase::get_dofs(); + } + + void gamma_impl(PyArray& data, PyArray& quadpoints) override { + PyCurvePlanarFourierBase::gamma_impl(data, quadpoints); + } +}; template void register_common_curve_methods(S &c) { c.def("gamma", &T::gamma) .def("gamma_impl", &T::gamma_impl) @@ -110,4 +133,16 @@ void init_curves(py::module_ &m) { .def_readonly("stellsym", &PyCurveRZFourier::stellsym) .def_readonly("nfp", &PyCurveRZFourier::nfp); register_common_curve_methods(pycurverzfourier); + + auto pycurveplanarfourier = py::class_, PyCurvePlanarFourierTrampoline, PyCurve>(m, "CurvePlanarFourier") + //.def(py::init()) + .def(py::init, int, int, bool>()) + .def_readwrite("rc", &PyCurvePlanarFourier::rc) + .def_readwrite("rs", &PyCurvePlanarFourier::rs) + .def_readwrite("q", &PyCurvePlanarFourier::q) + .def_readwrite("center", &PyCurvePlanarFourier::center) + .def_readonly("order", &PyCurvePlanarFourier::order) + .def_readonly("stellsym", &PyCurvePlanarFourier::stellsym) + .def_readonly("nfp", &PyCurvePlanarFourier::nfp); + register_common_curve_methods(pycurveplanarfourier); } diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 5bd49ddc1..817430220 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -9,6 +9,7 @@ from simsopt._core.json import GSONEncoder, GSONDecoder, SIMSON from simsopt.geo.curvexyzfourier import CurveXYZFourier, JaxCurveXYZFourier from simsopt.geo.curverzfourier import CurveRZFourier +from simsopt.geo.curveplanarfourier import CurvePlanarFourier from simsopt.geo.curvehelical import CurveHelical from simsopt.geo.curve import RotatedCurve, curves_to_vtk from simsopt.geo import parameters @@ -46,7 +47,6 @@ def taylor_test(f, df, x, epsilons=None, direction=None): fminuseps = f(x - eps * direction) dfest = (fpluseps-fminuseps)/(2*eps) err = np.linalg.norm(dfest - dfx) - # print(err) assert err < 1e-9 or err < 0.3 * err_old if err < 1e-9: break @@ -72,6 +72,8 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): curve = CurveHelical(x, order, 5, 2, 1.0, 0.3) elif curvetype == "CurveHelicalInitx0": curve = CurveHelical(x, order, 5, 2, 1.0, 0.3, x0=np.ones((2*order,))) + elif curvetype == "CurvePlanarFourier": + curve = CurvePlanarFourier(x, order, 2, True) else: assert False @@ -80,7 +82,7 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): dofs[1] = 1. dofs[2*order + 3] = 1. dofs[4*order + 3] = 1. - elif curvetype in ["CurveRZFourier"]: + elif curvetype in ["CurveRZFourier", "CurvePlanarFourier"]: dofs[0] = 1. dofs[1] = 0.1 dofs[order+1] = 0.1 @@ -97,9 +99,7 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): class Testing(unittest.TestCase): - curvetypes = ["CurveXYZFourier", "JaxCurveXYZFourier", "CurveRZFourier", "CurveHelical", - "CurveHelicalInitx0"] - + curvetypes = ["CurveXYZFourier", "JaxCurveXYZFourier", "CurveRZFourier", "CurvePlanarFourier", "CurveHelical", "CurveHelicalInitx0"] def test_curve_helical_xyzfourier(self): x = np.asarray([0.6]) curve1 = CurveHelical(x, 2, 5, 2, 1.0, 0.3) diff --git a/tests/test_files/input.NewConfiguration b/tests/test_files/input.NewConfiguration new file mode 100644 index 000000000..9adf5fa4e --- /dev/null +++ b/tests/test_files/input.NewConfiguration @@ -0,0 +1,113 @@ +&INDATA +!----- Runtime Parameters ----- + DELT = 9.00E-01 + NITER = 10000 + NSTEP = 200 + TCON0 = 2.00E+00 + +! NS_ARRAY = 16 50 +! NITER_ARRAY = 600 3000 +! FTOL_ARRAY = 1.0E-16 1.0E-13 + +! NS_ARRAY = 12 25 50 +! NITER_ARRAY = 600 1000 6000 +! FTOL_ARRAY = 1.0E-17 1.0e-17 1.0e-15 + +! NS_ARRAY = 12 25 50 75 +! NITER_ARRAY = 600 1000 2500 10000 +! FTOL_ARRAY = 1.0E-17 1.0e-17 1.0e-17 1.0e-17 + + NS_ARRAY = 12 25 50 75 100 150 201 + NITER_ARRAY = 1200 2000 3000 4000 5000 6000 20000 + FTOL_ARRAY = 1.0E-17 1.0e-17 1.0e-17 1.0e-17 1.0e-17 1.0e-17 2.0e-17 + + PRECON_TYPE = 'none' + PREC2D_THRESHOLD = 1.000000E-19 +!----- Grid Parameters ----- + LASYM = F + NFP = 0004 + MPOL = 0008 + NTOR = 0008 + PHIEDGE = 0.0381790210242581 +!----- Free Boundary Parameters ----- + LFREEB = F + NVACSKIP = 6 +!----- Pressure Parameters ----- + GAMMA = 0.000000000000E+000 + BLOAT = 1.000000000000E+000 + SPRES_PED = 1.000000000000E+000 + PRES_SCALE = 1.000000000000E+000 + PMASS_TYPE = 'power_series' + AM = 000000000E+00 +!----- Current/Iota Parameters ----- + CURTOR = 0 + NCURR = 1 + PIOTA_TYPE = 'power_series' + PCURR_TYPE = 'power_series' +!----- Axis Parameters ----- + RAXIS_CC = 0 + ZAXIS_CS = 0 +!----- Boundary Parameters ----- +! n comes before m! +RBC( 0, 0) = 1.000000000000000e+00, ZBS( 0, 0) = -0.000000000000000e+00 +RBC( 1, 0) = 1.798197877372061e-01, ZBS( 1, 0) = 1.526874285925055e-01 +RBC( 2, 0) = 1.734951154350431e-02, ZBS( 2, 0) = 1.866334230413251e-02 +RBC( 3, 0) = 2.577160162049330e-03, ZBS( 3, 0) = 1.199711292212324e-03 +RBC( 4, 0) = -1.637889983682740e-04, ZBS( 4, 0) = 6.984345011786886e-05 +RBC( 5, 0) = -2.425305167830765e-05, ZBS( 5, 0) = -2.548557148257138e-05 +RBC( -5, 1) = -8.577683632032374e-05, ZBS( -5, 1) = 2.045490523320995e-05 +RBC( -4, 1) = -3.374047917343044e-04, ZBS( -4, 1) = 5.046849551418733e-04 +RBC( -3, 1) = -3.641359983759378e-03, ZBS( -3, 1) = 3.782490654681902e-03 +RBC( -2, 1) = -2.444833020873945e-02, ZBS( -2, 1) = 2.427925370183856e-02 +RBC( -1, 1) = -8.731762429558673e-02, ZBS( -1, 1) = 4.517210283176742e-02 +RBC( 0, 1) = 1.380390474734288e-01, ZBS( 0, 1) = 1.310968006001034e-01 +RBC( 1, 1) = 2.903189084133577e-02, ZBS( 1, 1) = 3.270191607891355e-02 +RBC( 2, 1) = 6.875247108489111e-03, ZBS( 2, 1) = 6.803576261710397e-03 +RBC( 3, 1) = 8.150566273801188e-04, ZBS( 3, 1) = 8.594345731469456e-04 +RBC( 4, 1) = -2.843729541521199e-05, ZBS( 4, 1) = -1.177273734326507e-05 +RBC( 5, 1) = 1.828959533446362e-05, ZBS( 5, 1) = -1.615216261142120e-05 +RBC( -5, 2) = 2.187727631099286e-05, ZBS( -5, 2) = -7.400469361173993e-05 +RBC( -4, 2) = 8.393516055641350e-04, ZBS( -4, 2) = -4.483876523047104e-04 +RBC( -3, 2) = 1.971788481361341e-03, ZBS( -3, 2) = -3.174905588243931e-03 +RBC( -2, 2) = 5.269805664655518e-03, ZBS( -2, 2) = -7.113162328175970e-03 +RBC( -1, 2) = 2.116933661799145e-02, ZBS( -1, 2) = 1.865602467381490e-02 +RBC( 0, 2) = 1.536055908756419e-02, ZBS( 0, 2) = 9.451140140723166e-03 +RBC( 1, 2) = -1.177074525788361e-03, ZBS( 1, 2) = -4.394443738790604e-04 +RBC( 2, 2) = 1.300915708157302e-03, ZBS( 2, 2) = 1.022384351225018e-03 +RBC( 3, 2) = 2.747377558866586e-05, ZBS( 3, 2) = -6.300323824473890e-05 +RBC( 4, 2) = 9.334314906640049e-05, ZBS( 4, 2) = 6.552426964270398e-05 +RBC( 5, 2) = -5.617421098748800e-06, ZBS( 5, 2) = -1.848848555889170e-07 +RBC( -5, 3) = 2.874225777670480e-06, ZBS( -5, 3) = 7.868289246153724e-05 +RBC( -4, 3) = -1.903878083029936e-04, ZBS( -4, 3) = 3.682504964925082e-05 +RBC( -3, 3) = 2.220407427826208e-05, ZBS( -3, 3) = 6.281678187469348e-04 +RBC( -2, 3) = -1.082472074236150e-03, ZBS( -2, 3) = 6.445833193595944e-04 +RBC( -1, 3) = 6.435380216410359e-05, ZBS( -1, 3) = 1.141350665160774e-03 +RBC( 0, 3) = 1.069417168790915e-04, ZBS( 0, 3) = 3.802855234303916e-04 +RBC( 1, 3) = 4.983980241995697e-04, ZBS( 1, 3) = 6.843953564643375e-04 +RBC( 2, 3) = 3.325266953783200e-04, ZBS( 2, 3) = 2.395037991595740e-04 +RBC( 3, 3) = -8.380550535631315e-05, ZBS( 3, 3) = -2.858606506850391e-06 +RBC( 4, 3) = 8.168748496456451e-05, ZBS( 4, 3) = 3.828660987048127e-05 +RBC( 5, 3) = -1.172958658426462e-05, ZBS( 5, 3) = -2.567553564985603e-07 +RBC( -5, 4) = 1.930663967799810e-05, ZBS( -5, 4) = 5.848712999415494e-06 +RBC( -4, 4) = 5.914443815425555e-05, ZBS( -4, 4) = -9.777520270947895e-05 +RBC( -3, 4) = -1.535671893320628e-04, ZBS( -3, 4) = -1.968457634323347e-04 +RBC( -2, 4) = 9.254995677768834e-05, ZBS( -2, 4) = -1.254944494739196e-04 +RBC( -1, 4) = 2.217517688289458e-04, ZBS( -1, 4) = 7.133325449383868e-05 +RBC( 0, 4) = 4.623699812020439e-04, ZBS( 0, 4) = 3.336146039802283e-04 +RBC( 1, 4) = -4.834681321758439e-05, ZBS( 1, 4) = -1.984613542379469e-05 +RBC( 2, 4) = 1.449578757996227e-04, ZBS( 2, 4) = 3.445613069241063e-05 +RBC( 3, 4) = -5.390410338650556e-05, ZBS( 3, 4) = -6.043337987396479e-05 +RBC( 4, 4) = -2.755169485866935e-05, ZBS( 4, 4) = -3.234200905245086e-05 +RBC( 5, 4) = -1.031528435324214e-05, ZBS( 5, 4) = -8.346877197760745e-06 +RBC( -5, 5) = -8.230328283192286e-06, ZBS( -5, 5) = -4.962452471737940e-07 +RBC( -4, 5) = -4.283219579566894e-05, ZBS( -4, 5) = 2.554677526708830e-05 +RBC( -3, 5) = 7.171674894766820e-06, ZBS( -3, 5) = 4.411924318063437e-05 +RBC( -2, 5) = 1.686400668654943e-05, ZBS( -2, 5) = -5.849246530755695e-06 +RBC( -1, 5) = -3.106338530700742e-06, ZBS( -1, 5) = 1.479053323007641e-06 +RBC( 0, 5) = -3.106894329327918e-05, ZBS( 0, 5) = -4.555573189096034e-05 +RBC( 1, 5) = -2.117004285123679e-05, ZBS( 1, 5) = 4.954122546236333e-06 +RBC( 2, 5) = 1.404444565956858e-06, ZBS( 2, 5) = 2.921397801630777e-06 +RBC( 3, 5) = -1.491037166951584e-05, ZBS( 3, 5) = -1.337158933881559e-05 +RBC( 4, 5) = -1.062017757240239e-05, ZBS( 4, 5) = -1.038497225885287e-05 +RBC( 5, 5) = -3.055942324592806e-06, ZBS( 5, 5) = -2.630290187244904e-06 +/ From d282021621f9d559fa0386f7dc44e6e6086963fc Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Tue, 29 Aug 2023 11:53:02 -0400 Subject: [PATCH 02/21] unnormalized dofs --- src/simsoptpp/curveplanarfourier.cpp | 505 ++++++++++++++++----------- src/simsoptpp/curveplanarfourier.h | 16 +- 2 files changed, 303 insertions(+), 218 deletions(-) diff --git a/src/simsoptpp/curveplanarfourier.cpp b/src/simsoptpp/curveplanarfourier.cpp index 66398db6b..3bc8e755f 100644 --- a/src/simsoptpp/curveplanarfourier.cpp +++ b/src/simsoptpp/curveplanarfourier.cpp @@ -5,6 +5,19 @@ template void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { int numquadpoints = quadpoints.size(); data *= 0; + + /* Converts q dofs to unit quaternion */ + Array q_norm = xt::zeros({4}); + double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; + if(s != 0) { + for (int i = 0; i < 4; ++i) + q_norm[i] = q[i] / std::sqrt(s); + } + else { + q_norm[0] = 1; + } + + for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; for (int i = 0; i < order+1; ++i) { @@ -27,15 +40,27 @@ void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { j = data(m, 1); k = data(m, 2); - data(m, 0) = (i - 2 * (q[2] * q[2] + q[3] * q[3]) * i + 2 * (q[1] * q[2] - q[3] * q[0]) * j + 2 * (q[1] * q[3] + q[2] * q[0]) * k) + center[0]; - data(m, 1) = (2 * (q[1] * q[2] + q[3] * q[0]) * i + j - 2 * (q[1] * q[1] + q[3] * q[3]) * j + 2 * (q[2] * q[3] - q[1] * q[0]) * k) + center[1]; - data(m, 2) = (2 * (q[1] * q[3] - q[2] * q[0]) * i + 2 * (q[2] * q[3] + q[1] * q[0]) * j + k - 2 * (q[1] * q[1] + q[2] * q[2]) * k) + center[2]; + data(m, 0) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k) + center[0]; + data(m, 1) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k) + center[1]; + data(m, 2) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k) + center[2]; } } template void CurvePlanarFourier::gammadash_impl(Array& data) { data *= 0; + + /* Converts q dofs to unit quaternion */ + Array q_norm = xt::zeros({4}); + double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; + if(s != 0) { + for (int i = 0; i < 4; ++i) + q_norm[i] = q[i] / std::sqrt(s); + } + else { + q_norm[0] = 1; + } + for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; for (int i = 0; i < order+1; ++i) { @@ -59,9 +84,9 @@ void CurvePlanarFourier::gammadash_impl(Array& data) { Array k = xt::zeros({1}); k[0] = data(m, 2); - data(m, 0) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); - data(m, 1) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); - data(m, 2) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + data(m, 0) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); + data(m, 1) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); + data(m, 2) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); } } @@ -69,6 +94,18 @@ void CurvePlanarFourier::gammadash_impl(Array& data) { template void CurvePlanarFourier::gammadashdash_impl(Array& data) { data *= 0; + + /* Converts q dofs to unit quaternion */ + Array q_norm = xt::zeros({4}); + double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; + if(s != 0) { + for (int i = 0; i < 4; ++i) + q_norm[i] = q[i] / std::sqrt(s); + } + else { + q_norm[0] = 1; + } + for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; for (int i = 0; i < order+1; ++i) { @@ -94,9 +131,9 @@ void CurvePlanarFourier::gammadashdash_impl(Array& data) { Array k = xt::zeros({1}); k[0] = data(m, 2); - data(m, 0) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); - data(m, 1) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); - data(m, 2) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + data(m, 0) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); + data(m, 1) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); + data(m, 2) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); } } @@ -104,6 +141,18 @@ void CurvePlanarFourier::gammadashdash_impl(Array& data) { template void CurvePlanarFourier::gammadashdashdash_impl(Array& data) { data *= 0; + + /* Converts q dofs to unit quaternion */ + Array q_norm = xt::zeros({4}); + double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; + if(s != 0) { + for (int i = 0; i < 4; ++i) + q_norm[i] = q[i] / std::sqrt(s); + } + else { + q_norm[0] = 1; + } + for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; for (int i = 0; i < order+1; ++i) { @@ -139,9 +188,9 @@ void CurvePlanarFourier::gammadashdashdash_impl(Array& data) { Array k = xt::zeros({1}); k[0] = data(m, 2); - data(m, 0) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); - data(m, 1) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); - data(m, 2) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + data(m, 0) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); + data(m, 1) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); + data(m, 2) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); } } @@ -149,6 +198,18 @@ void CurvePlanarFourier::gammadashdashdash_impl(Array& data) { template void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { data *= 0; + + /* Converts q dofs to unit quaternion */ + Array q_norm = xt::zeros({4}); + double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; + if(s != 0) { + for (int i = 0; i < 4; ++i) + q_norm[i] = q[i] / std::sqrt(s); + } + else { + q_norm[0] = 1; + } + for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; int counter = 0; @@ -161,9 +222,9 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { j[0] = cos(n*phi) * sin(phi); k[0] = 0; - data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); - data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); - data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); counter++; } @@ -173,9 +234,9 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { j[0] = sin(n*phi) * sin(phi); k[0] = 0; - data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); - data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); - data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); counter++; } @@ -193,54 +254,54 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { j[0] += rs[n-1] * sin(n*phi) * sin(phi); } - data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[0] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[0] - - 2 * j[0] * q[3]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[0] - + 2 * i[0] * q[3] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[0]; - data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[0] - - 2 * i[0] * q[2] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[0] - + 2 * j[0] * q[1]; + data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]; + data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]; counter++; - data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[1] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[1] - + 2 * j[0] * q[2]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[1] - + 2 * i[0] * q[2] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[1] - - 4 * j[0] * q[1]; - data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[1] - + 2 * i[0] * q[3] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[1] - + 2 * j[0] * q[0]; + data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]; + data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]; counter++; - data(m, 0, counter) = - 4 * i[0] * (q[0] * q[0] + q[1] * q[1]) * q[2] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[2] - + 2 * j[0] * q[1]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[2] - + 2 * i[0] * q[1] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[2]; - data(m, 2, counter) = - 2 * i[0] * q[0] - - 4 * i[0] * (q[1] * q[3] - q[0] * q[2]) * q[2] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[2] - + 2 * j[0] * q[3]; + data(m, 0, counter) = - 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]; + data(m, 2, counter) = - 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]; counter++; - data(m, 0, counter) = - 4 * i[0] * (q[1] * q[1] + q[0] * q[0]) * q[3] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[3] - - 2 * j[0] * q[0]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[3] - + 2 * i[0] * q[0] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[3] - - 4 * j[0] * q[3]; - data(m, 2, counter) = 2 * i[0] * q[1] - + 4 * i[0] * (q[2] * q[0] - q[1] * q[3]) * q[3] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[3] - + 2 * j[0] * q[2]; + data(m, 0, counter) = - 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]; + data(m, 2, counter) = 2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]; counter++; @@ -258,6 +319,18 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { template void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { data *= 0; + + /* Converts q dofs to unit quaternion */ + Array q_norm = xt::zeros({4}); + double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; + if(s != 0) { + for (int i = 0; i < 4; ++i) + q_norm[i] = q[i] / std::sqrt(s); + } + else { + q_norm[0] = 1; + } + for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; int counter = 0; @@ -272,9 +345,9 @@ void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { i[0] *= (2*M_PI); j[0] *= (2*M_PI); - data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); - data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); - data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); counter++; @@ -288,9 +361,9 @@ void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { i[0] *= (2*M_PI); j[0] *= (2*M_PI); - data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); - data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); - data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); counter++; @@ -308,54 +381,54 @@ void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { j[0] += rs[n-1] * ( (n) * cos(n*phi) * sin(phi) + sin(n*phi) * cos(phi)) * 2 * M_PI; } - data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[0] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[0] - - 2 * j[0] * q[3]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[0] - + 2 * i[0] * q[3] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[0]; - data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[0] - - 2 * i[0] * q[2] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[0] - + 2 * j[0] * q[1]; + data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]; + data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]; counter++; - data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[1] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[1] - + 2 * j[0] * q[2]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[1] - + 2 * i[0] * q[2] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[1] - - 4 * j[0] * q[1]; - data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[1] - + 2 * i[0] * q[3] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[1] - + 2 * j[0] * q[0]; + data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]; + data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]; counter++; - data(m, 0, counter) = - 4 * i[0] * (q[0] * q[0] + q[1] * q[1]) * q[2] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[2] - + 2 * j[0] * q[1]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[2] - + 2 * i[0] * q[1] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[2]; - data(m, 2, counter) = - 2 * i[0] * q[0] - - 4 * i[0] * (q[1] * q[3] - q[0] * q[2]) * q[2] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[2] - + 2 * j[0] * q[3]; + data(m, 0, counter) = - 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]; + data(m, 2, counter) = - 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]; counter++; - data(m, 0, counter) = - 4 * i[0] * (q[1] * q[1] + q[0] * q[0]) * q[3] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[3] - - 2 * j[0] * q[0]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[3] - + 2 * i[0] * q[0] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[3] - - 4 * j[0] * q[3]; - data(m, 2, counter) = 2 * i[0] * q[1] - + 4 * i[0] * (q[2] * q[0] - q[1] * q[3]) * q[3] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[3] - + 2 * j[0] * q[2]; + data(m, 0, counter) = - 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]; + data(m, 2, counter) = 2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]; counter++; for (int i = 0; i < 2; ++i) { @@ -372,6 +445,18 @@ void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { template void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { data *= 0; + + /* Converts q dofs to unit quaternion */ + Array q_norm = xt::zeros({4}); + double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; + if(s != 0) { + for (int i = 0; i < 4; ++i) + q_norm[i] = q[i] / std::sqrt(s); + } + else { + q_norm[0] = 1; + } + for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; int counter = 0; @@ -387,9 +472,9 @@ void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { j[0] *= 2*M_PI*2*M_PI; k[0] *= 2*M_PI*2*M_PI; - data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); - data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); - data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); counter++; } @@ -403,9 +488,9 @@ void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { j[0] *= 2*M_PI*2*M_PI; k[0] *= 2*M_PI*2*M_PI; - data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); - data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); - data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); counter++; } @@ -425,54 +510,54 @@ void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { j[0] *= 2*M_PI*2*M_PI; k[0] *= 2*M_PI*2*M_PI; - data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[0] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[0] - - 2 * j[0] * q[3]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[0] - + 2 * i[0] * q[3] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[0]; - data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[0] - - 2 * i[0] * q[2] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[0] - + 2 * j[0] * q[1]; + data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]; + data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]; counter++; - data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[1] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[1] - + 2 * j[0] * q[2]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[1] - + 2 * i[0] * q[2] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[1] - - 4 * j[0] * q[1]; - data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[1] - + 2 * i[0] * q[3] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[1] - + 2 * j[0] * q[0]; + data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]; + data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]; counter++; - data(m, 0, counter) = - 4 * i[0] * (q[0] * q[0] + q[1] * q[1]) * q[2] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[2] - + 2 * j[0] * q[1]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[2] - + 2 * i[0] * q[1] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[2]; - data(m, 2, counter) = - 2 * i[0] * q[0] - - 4 * i[0] * (q[1] * q[3] - q[0] * q[2]) * q[2] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[2] - + 2 * j[0] * q[3]; + data(m, 0, counter) = - 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]; + data(m, 2, counter) = - 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]; counter++; - data(m, 0, counter) = - 4 * i[0] * (q[1] * q[1] + q[0] * q[0]) * q[3] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[3] - - 2 * j[0] * q[0]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[3] - + 2 * i[0] * q[0] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[3] - - 4 * j[0] * q[3]; - data(m, 2, counter) = 2 * i[0] * q[1] - + 4 * i[0] * (q[2] * q[0] - q[1] * q[3]) * q[3] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[3] - + 2 * j[0] * q[2]; + data(m, 0, counter) = - 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]; + data(m, 2, counter) = 2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]; counter++; for (int i = 0; i < 3; ++i) { @@ -488,6 +573,18 @@ void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { template void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { data *= 0; + + /* Converts q dofs to unit quaternion */ + Array q_norm = xt::zeros({4}); + double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; + if(s != 0) { + for (int i = 0; i < 4; ++i) + q_norm[i] = q[i] / std::sqrt(s); + } + else { + q_norm[0] = 1; + } + for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; int counter = 0; @@ -509,9 +606,9 @@ void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { j[0] *= 2*M_PI*2*M_PI*2*M_PI; k[0] *= 2*M_PI*2*M_PI*2*M_PI; - data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); - data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); - data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); counter++; } @@ -531,9 +628,9 @@ void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { j[0] *= 2*M_PI*2*M_PI*2*M_PI; k[0] *= 2*M_PI*2*M_PI*2*M_PI; - data(m, 0, counter) = (i[0] - 2 * (q[2] * q[2] + q[3] * q[3]) * i[0] + 2 * (q[1] * q[2] - q[3] * q[0]) * j[0] + 2 * (q[1] * q[3] + q[2] * q[0]) * k[0]); - data(m, 1, counter) = (2 * (q[1] * q[2] + q[3] * q[0]) * i[0] + j[0] - 2 * (q[1] * q[1] + q[3] * q[3]) * j[0] + 2 * (q[2] * q[3] - q[1] * q[0]) * k[0]); - data(m, 2, counter) = (2 * (q[1] * q[3] - q[2] * q[0]) * i[0] + 2 * (q[2] * q[3] + q[1] * q[0]) * j[0] + k[0] - 2 * (q[1] * q[1] + q[2] * q[2]) * k[0]); + data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); counter++; } @@ -565,54 +662,54 @@ void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { j[0] *= 2*M_PI*2*M_PI*2*M_PI; k[0] *= 2*M_PI*2*M_PI*2*M_PI; - data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[0] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[0] - - 2 * j[0] * q[3]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[0] - + 2 * i[0] * q[3] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[0]; - data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[0] - - 2 * i[0] * q[2] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[0] - + 2 * j[0] * q[1]; + data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]; + data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]; counter++; - data(m, 0, counter) = 4 * i[0] * (q[2] * q[2] + q[3] * q[3]) * q[1] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[1] - + 2 * j[0] * q[2]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[1] - + 2 * i[0] * q[2] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[1] - - 4 * j[0] * q[1]; - data(m, 2, counter) = - 4 * i[0] * (q[1] * q[3] - q[2] * q[0]) * q[1] - + 2 * i[0] * q[3] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[1] - + 2 * j[0] * q[0]; + data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]; + data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]; counter++; - data(m, 0, counter) = - 4 * i[0] * (q[0] * q[0] + q[1] * q[1]) * q[2] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[2] - + 2 * j[0] * q[1]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[2] - + 2 * i[0] * q[1] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[2]; - data(m, 2, counter) = - 2 * i[0] * q[0] - - 4 * i[0] * (q[1] * q[3] - q[0] * q[2]) * q[2] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[2] - + 2 * j[0] * q[3]; + data(m, 0, counter) = - 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]; + data(m, 2, counter) = - 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]; counter++; - data(m, 0, counter) = - 4 * i[0] * (q[1] * q[1] + q[0] * q[0]) * q[3] - - 4 * j[0] * (q[1] * q[2] - q[0] * q[3]) * q[3] - - 2 * j[0] * q[0]; - data(m, 1, counter) = - 4 * i[0] * (q[1] * q[2] + q[3] * q[0]) * q[3] - + 2 * i[0] * q[0] - + 4 * j[0] * (q[1] * q[1] + q[3] * q[3]) * q[3] - - 4 * j[0] * q[3]; - data(m, 2, counter) = 2 * i[0] * q[1] - + 4 * i[0] * (q[2] * q[0] - q[1] * q[3]) * q[3] - - 4 * j[0] * (q[1] * q[0] + q[2] * q[3]) * q[3] - + 2 * j[0] * q[2]; + data(m, 0, counter) = - 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]; + data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]; + data(m, 2, counter) = 2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]; counter++; for (int i = 0; i < 3; ++i) { diff --git a/src/simsoptpp/curveplanarfourier.h b/src/simsoptpp/curveplanarfourier.h index 4febd687d..d07d93c8b 100644 --- a/src/simsoptpp/curveplanarfourier.h +++ b/src/simsoptpp/curveplanarfourier.h @@ -58,26 +58,14 @@ class CurvePlanarFourier : public Curve { void set_dofs_impl(const vector& dofs) override { int counter = 0; - double s = 0; for (int i = 0; i < order + 1; ++i) rc.data()[i] = dofs[counter++]; for (int i = 0; i < order; ++i) rs.data()[i] = dofs[counter++]; - for (int i = 0; i < 4; ++i){ + for (int i = 0; i < 4; ++i) q.data()[i] = dofs[counter++]; - s += q[i] * q[i]; - } - /* Converts to unit quaternion */ - if(s != 0) { - for (int i = 0; i < 4; ++i) - q.data()[i] = q[i] / std::sqrt(s); - } - else { - q.data()[0] = 1; - } - for (int i = 0; i < 3; ++i){ + for (int i = 0; i < 3; ++i) center.data()[i] = dofs[counter++]; - } } vector get_dofs() override { From bc3ff7f281d2b4a6106b2daf408beca2f05ede0b Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Thu, 28 Sep 2023 11:59:30 -0400 Subject: [PATCH 03/21] planar coil unnormalized update --- src/simsoptpp/curveplanarfourier.cpp | 1096 +++++++++++++++++++++++--- 1 file changed, 1000 insertions(+), 96 deletions(-) diff --git a/src/simsoptpp/curveplanarfourier.cpp b/src/simsoptpp/curveplanarfourier.cpp index 3bc8e755f..ceda2e9aa 100644 --- a/src/simsoptpp/curveplanarfourier.cpp +++ b/src/simsoptpp/curveplanarfourier.cpp @@ -254,54 +254,280 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { j[0] += rs[n-1] * sin(n*phi) * sin(phi); } - data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]; - data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - 2 * i[0] * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]; + + 2 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + 2 * i[0] * q_norm[2] + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]; - data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + 2 * i[0] * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]; + + 2 * j[0] * q_norm[0]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = - 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]; - data(m, 2, counter) = - 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]; + + 2 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = - 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + 2 * i[0] * q_norm[0] + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]; - data(m, 2, counter) = 2 * i[0] * q_norm[1] + - 4 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]; + + 2 * j[0] * q_norm[2]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; @@ -381,54 +607,280 @@ void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { j[0] += rs[n-1] * ( (n) * cos(n*phi) * sin(phi) + sin(n*phi) * cos(phi)) * 2 * M_PI; } - data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]; - data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - 2 * i[0] * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]; + + 2 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + 2 * i[0] * q_norm[2] + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]; - data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + 2 * i[0] * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]; + + 2 * j[0] * q_norm[0]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = - 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]; - data(m, 2, counter) = - 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]; + + 2 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = - 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + 2 * i[0] * q_norm[0] + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]; - data(m, 2, counter) = 2 * i[0] * q_norm[1] + - 4 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]; + + 2 * j[0] * q_norm[2]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; for (int i = 0; i < 2; ++i) { @@ -510,54 +962,280 @@ void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { j[0] *= 2*M_PI*2*M_PI; k[0] *= 2*M_PI*2*M_PI; - data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]; - data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - 2 * i[0] * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]; + + 2 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + 2 * i[0] * q_norm[2] + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]; - data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + 2 * i[0] * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]; + + 2 * j[0] * q_norm[0]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = - 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]; - data(m, 2, counter) = - 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]; + + 2 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = - 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + 2 * i[0] * q_norm[0] + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]; - data(m, 2, counter) = 2 * i[0] * q_norm[1] + - 4 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]; + + 2 * j[0] * q_norm[2]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; for (int i = 0; i < 3; ++i) { @@ -662,54 +1340,280 @@ void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { j[0] *= 2*M_PI*2*M_PI*2*M_PI; k[0] *= 2*M_PI*2*M_PI*2*M_PI; - data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]; - data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - 2 * i[0] * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]; + + 2 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = 4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + 2 * i[0] * q_norm[2] + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]; - data(m, 2, counter) = - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + 2 * i[0] * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]; + + 2 * j[0] * q_norm[0]) + * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = - 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]; - data(m, 2, counter) = - 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i[0] * q_norm[0] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j[0] * q_norm[3]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]; + + 2 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j[0] * q_norm[2]) + * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; - data(m, 0, counter) = - 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j[0] * q_norm[3]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[2]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[1]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]; - data(m, 1, counter) = - 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + - 2 * j[0] * q_norm[0]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i[0] * q_norm[3] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[2] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j[0] * q_norm[1]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i[0] * q_norm[1] + + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + 2 * i[0] * q_norm[0] + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]; - data(m, 2, counter) = 2 * i[0] * q_norm[1] + - 4 * j[0] * q_norm[3]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + + + data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i[0] * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j[0] * q_norm[1]) + * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i[0] * q_norm[3] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j[0] * q_norm[0]) + * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (- 2 * i[0] * q_norm[0] + - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j[0] * q_norm[3]) + * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + + (2 * i[0] * q_norm[1] + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]; + + 2 * j[0] * q_norm[2]) + * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); counter++; for (int i = 0; i < 3; ++i) { From 8e7a2187eb521396feb804647a13f969d92a6dee Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Thu, 28 Sep 2023 12:43:09 -0400 Subject: [PATCH 04/21] Updated create_equally_spaced_planar_curves to prevent overlapping curves --- src/simsopt/geo/curve.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simsopt/geo/curve.py b/src/simsopt/geo/curve.py index 863c37f3c..ed5530c99 100644 --- a/src/simsopt/geo/curve.py +++ b/src/simsopt/geo/curve.py @@ -893,7 +893,7 @@ def create_equally_spaced_planar_curves(ncurves, nfp, stellsym, R0=1.0, R1=0.5, curves = [] from simsopt.geo.curveplanarfourier import CurvePlanarFourier for k in range(ncurves): - angle = k*(2*np.pi) / ((1+int(stellsym))*nfp*ncurves) + angle = (k+0.5)*(2*np.pi) / ((1+int(stellsym))*nfp*ncurves) curve = CurvePlanarFourier(numquadpoints, order, nfp, stellsym) rcCoeffs = np.zeros(order+1) From 77ed76f63dc362eac299d45f5950190bda77eea6 Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Tue, 3 Oct 2023 13:23:20 -0400 Subject: [PATCH 05/21] Added planar coil example file --- .../stage_two_optimization_planar_coils.py | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100755 examples/2_Intermediate/stage_two_optimization_planar_coils.py diff --git a/examples/2_Intermediate/stage_two_optimization_planar_coils.py b/examples/2_Intermediate/stage_two_optimization_planar_coils.py new file mode 100755 index 000000000..a621a10b1 --- /dev/null +++ b/examples/2_Intermediate/stage_two_optimization_planar_coils.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python +r""" +In this example we solve a FOCUS like Stage II coil optimisation problem: the +goal is to find coils that generate a specific target normal field on a given +surface. In this particular case we consider a vacuum field, so the target is +just zero. + +The objective is given by + + J = (1/2) \int |B dot n|^2 ds + + LENGTH_WEIGHT * (sum CurveLength) + + DISTANCE_WEIGHT * MininumDistancePenalty(DISTANCE_THRESHOLD) + + CURVATURE_WEIGHT * CurvaturePenalty(CURVATURE_THRESHOLD) + + MSC_WEIGHT * MeanSquaredCurvaturePenalty(MSC_THRESHOLD) + +if any of the weights are increased, or the thresholds are tightened, the coils +are more regular and better separated, but the target normal field may not be +achieved as well. This example demonstrates the adjustment of weights and +penalties via the use of the `Weight` class. + +The target equilibrium is the QA configuration of arXiv:2108.03711. +""" + +import os +from pathlib import Path +import numpy as np +from scipy.optimize import minimize +from simsopt.objectives import Weight +from simsopt.geo import SurfaceRZFourier +from simsopt.objectives import SquaredFlux +from simsopt.objectives import QuadraticPenalty +from simsopt.geo import curves_to_vtk, create_equally_spaced_planar_curves +from simsopt.field import BiotSavart +from simsopt.field import Current, coils_via_symmetries +from simsopt.geo import CurveLength, CurveCurveDistance, \ + MeanSquaredCurvature, LpCurveCurvature, CurveSurfaceDistance, LinkingNumber + +# Number of unique coil shapes, i.e. the number of coils per half field period: +# (Since the configuration has nfp = 2, multiply by 4 to get the total number of coils.) +ncoils = 4 + +# Major radius for the initial circular coils: +R0 = 1.0 + +# Minor radius for the initial circular coils: +R1 = 0.5 + +# Number of Fourier modes describing each Cartesian component of each coil: +order = 5 + +# Weight on the curve lengths in the objective function. We use the `Weight` +# class here to later easily adjust the scalar value and rerun the optimization +# without having to rebuild the objective. +LENGTH_WEIGHT = Weight(10) + +# Threshold and weight for the coil-to-coil distance penalty in the objective function: +CC_THRESHOLD = 0.08 +CC_WEIGHT = 1000 + +# Threshold and weight for the coil-to-surface distance penalty in the objective function: +CS_THRESHOLD = 0.12 +CS_WEIGHT = 10 + +# Threshold and weight for the curvature penalty in the objective function: +CURVATURE_THRESHOLD = 10. +CURVATURE_WEIGHT = 1e-6 + +# Threshold and weight for the mean squared curvature penalty in the objective function: +MSC_THRESHOLD = 10 +MSC_WEIGHT = 1e-6 + +# Number of iterations to perform: +ci = "CI" in os.environ and os.environ['CI'].lower() in ['1', 'true'] +MAXITER = 50 if ci else 400 + +# File for the desired boundary magnetic surface: +TEST_DIR = (Path(__file__).parent / ".." / ".." / "tests" / "test_files").resolve() +filename = TEST_DIR / 'input.LandremanPaul2021_QA' + +# Directory for output +OUT_DIR = "./output/" +os.makedirs(OUT_DIR, exist_ok=True) + +####################################################### +# End of input parameters. +####################################################### + +# Initialize the boundary magnetic surface: +nphi = 32 +ntheta = 32 +s = SurfaceRZFourier.from_vmec_input(filename, range="half period", nphi=nphi, ntheta=ntheta) + +# Create the initial coils: +base_curves = create_equally_spaced_planar_curves(ncoils, s.nfp, stellsym=True, R0=R0, R1=R1, order=order) +base_currents = [Current(1e5) for i in range(ncoils)] +# Since the target field is zero, one possible solution is just to set all +# currents to 0. To avoid the minimizer finding that solution, we fix one +# of the currents: +base_currents[0].fix_all() + +coils = coils_via_symmetries(base_curves, base_currents, s.nfp, True) +bs = BiotSavart(coils) +bs.set_points(s.gamma().reshape((-1, 3))) + +curves = [c.curve for c in coils] +curves_to_vtk(curves, OUT_DIR + "curves_init") +pointData = {"B_N": np.sum(bs.B().reshape((nphi, ntheta, 3)) * s.unitnormal(), axis=2)[:, :, None]} +s.to_vtk(OUT_DIR + "surf_init", extra_data=pointData) + +# Define the individual terms objective function: +Jf = SquaredFlux(s, bs) +Jls = [CurveLength(c) for c in base_curves] +Jccdist = CurveCurveDistance(curves, CC_THRESHOLD, num_basecurves=ncoils) #Error +Jcsdist = CurveSurfaceDistance(curves, s, CS_THRESHOLD) +Jcs = [LpCurveCurvature(c, 2, CURVATURE_THRESHOLD) for c in base_curves] +Jmscs = [MeanSquaredCurvature(c) for c in base_curves] +linkNum = LinkingNumber(curves) + +# Form the total objective function. To do this, we can exploit the +# fact that Optimizable objects with J() and dJ() functions can be +# multiplied by scalars and added: +JF = Jf \ + + LENGTH_WEIGHT * QuadraticPenalty(sum(Jls), 2.6*ncoils) \ + + CC_WEIGHT * Jccdist \ + + CS_WEIGHT * Jcsdist \ + + CURVATURE_WEIGHT * sum(Jcs) \ + + MSC_WEIGHT * sum(QuadraticPenalty(J, MSC_THRESHOLD) for J in Jmscs) \ + + QuadraticPenalty(linkNum, 0.1) + +# We don't have a general interface in SIMSOPT for optimisation problems that +# are not in least-squares form, so we write a little wrapper function that we +# pass directly to scipy.optimize.minimize + +def fun(dofs): + JF.x = dofs + J = JF.J() + grad = JF.dJ() + jf = Jf.J() + BdotN = np.mean(np.abs(np.sum(bs.B().reshape((nphi, ntheta, 3)) * s.unitnormal(), axis=2))) + MaxBdotN = np.max(np.abs(np.sum(bs.B().reshape((nphi, ntheta, 3)) * s.unitnormal(), axis=2))) + mean_AbsB = np.mean(bs.AbsB()) + outstr = f"J={J:.1e}, Jf={jf:.1e}, ⟨B·n⟩={BdotN:.1e}" + cl_string = ", ".join([f"{J.J():.1f}" for J in Jls]) + kap_string = ", ".join(f"{np.max(c.kappa()):.1f}" for c in base_curves) + msc_string = ", ".join(f"{J.J():.1f}" for J in Jmscs) + outstr += f", Len=sum([{cl_string}])={sum(J.J() for J in Jls):.1f}, ϰ=[{kap_string}], ∫ϰ²/L=[{msc_string}]" + outstr += f", C-C-Sep={Jccdist.shortest_distance():.2f}, C-S-Sep={Jcsdist.shortest_distance():.2f}" + outstr += f", ║∇J║={np.linalg.norm(grad):.1e}" + outstr += f", ⟨B·n⟩/|B|={BdotN/mean_AbsB:.1e}" + outstr += f", (Max B·n)/|B|={MaxBdotN/mean_AbsB:.1e}" + outstr += f", Link Number = {linkNum.J()}" + print(outstr) + return J, grad + + +print(""" +################################################################################ +### Perform a Taylor test ###################################################### +################################################################################ +""") +f = fun +dofs = JF.x +np.random.seed(1) +h = np.random.uniform(size=dofs.shape) +J0, dJ0 = f(dofs) +dJh = sum(dJ0 * h) +for eps in [1e-3, 1e-4, 1e-5, 1e-6, 1e-7]: + J1, _ = f(dofs + eps*h) + J2, _ = f(dofs - eps*h) + print("err", (J1-J2)/(2*eps) - dJh) + +print(""" +################################################################################ +### Run the optimisation ####################################################### +################################################################################ +""") +res = minimize(fun, dofs, jac=True, method='L-BFGS-B', options={'maxiter': MAXITER, 'maxcor': 300}, tol=1e-15) +curves_to_vtk(curves, OUT_DIR + f"curves_opt_short") +pointData = {"B_N": np.sum(bs.B().reshape((nphi, ntheta, 3)) * s.unitnormal(), axis=2)[:, :, None]} +s.to_vtk(OUT_DIR + "surf_opt_short", extra_data=pointData) + + +# We now use the result from the optimization as the initial guess for a +# subsequent optimization with reduced penalty for the coil length. This will +# result in slightly longer coils but smaller `B·n` on the surface. +dofs = res.x +LENGTH_WEIGHT *= 0.1 +res = minimize(fun, dofs, jac=True, method='L-BFGS-B', options={'maxiter': MAXITER, 'maxcor': 300}, tol=1e-15) +curves_to_vtk(curves, OUT_DIR + f"curves_opt_long") +pointData = {"B_N": np.sum(bs.B().reshape((nphi, ntheta, 3)) * s.unitnormal(), axis=2)[:, :, None]} +s.to_vtk(OUT_DIR + "surf_opt_long", extra_data=pointData) + +# Save the optimized coil shapes and currents so they can be loaded into other scripts for analysis: +bs.save(OUT_DIR + "biot_savart_opt.json") From 9d1f036418c2272e2396790963eb33f8f312331b Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Tue, 3 Oct 2023 13:42:33 -0400 Subject: [PATCH 06/21] Better documentation --- src/simsopt/geo/curve.py | 6 +++++- src/simsopt/geo/curveplanarfourier.py | 17 ++++++++++++++++- src/simsoptpp/curveplanarfourier.h | 15 ++++++++++----- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/simsopt/geo/curve.py b/src/simsopt/geo/curve.py index ed5530c99..925e01738 100644 --- a/src/simsopt/geo/curve.py +++ b/src/simsopt/geo/curve.py @@ -885,7 +885,11 @@ def create_equally_spaced_curves(ncurves, nfp, stellsym, R0=1.0, R1=0.5, order=6 def create_equally_spaced_planar_curves(ncurves, nfp, stellsym, R0=1.0, R1=0.5, order=6, numquadpoints=None): """ - Insert text here + Create ``ncurves`` curves of type + :obj:`~simsopt.geo.curveplanarfourier.CurvePlanarFourier` of order + ``order`` that will result in circular equally spaced coils (major + radius ``R0`` and minor radius ``R1``) after applying + :obj:`~simsopt.field.coil.coils_via_symmetries`. """ if numquadpoints is None: diff --git a/src/simsopt/geo/curveplanarfourier.py b/src/simsopt/geo/curveplanarfourier.py index 78b590548..1ef453d18 100644 --- a/src/simsopt/geo/curveplanarfourier.py +++ b/src/simsopt/geo/curveplanarfourier.py @@ -9,7 +9,22 @@ class CurvePlanarFourier(sopp.CurvePlanarFourier, Curve): r""" - Insert text here + ``CurvePlanarFourier`` is a curve that is represented by a polar coordinate fourier serires, a rotation quaternion, and a center point following the form: + .. math:: + r(\phi) &= \sum_{m=0}^{\text{order}} r_{c,m}\cos(n_{\text{fp}} m \phi) + \sum_{m=1}^{\text{order}} r_{s,m}\sin(n_{\text{fp}} m \phi) + \bf{q} &= [q_0,q_i,q_j,q_k] &= [\cos(\theta / 2), \hat{x}\sin(\theta / 2), \hat{y}\sin(\theta / 2), \hat{z}\sin(\theta / 2)] + where :math:'\theta' is the counterclockwise rotation about a unit axis :math:'(\hat{x},\hat{y},\hat{z})'. + + The quaternion is normalized for calculations to prevent scaling. The dofs themselves are not normalized. This results in a redundancy in the optimization, + where several different sets of dofs may correspond to the same normalized quaternion. + Normalizing the dofs directly would create a dependence between the quaternion dofs, which may cause issues during optimization. + + The dofs are stored in the order + + .. math:: + [r_{c,0}, \cdots, r_{c,\text{order}}, r_{s,1}, \cdots, r_{s,\text{order}}, q_0, q_i, q_j, q_k, x_{\text{center}}, y_{\text{center}}, z_{\text{center}}] + + """ def __init__(self, quadpoints, order, nfp, stellsym, dofs=None): diff --git a/src/simsoptpp/curveplanarfourier.h b/src/simsoptpp/curveplanarfourier.h index d07d93c8b..4b8b4baee 100644 --- a/src/simsoptpp/curveplanarfourier.h +++ b/src/simsoptpp/curveplanarfourier.h @@ -5,17 +5,22 @@ template class CurvePlanarFourier : public Curve { /* - CurvePlanarFourier is a curve that is represented as a plane rotated about the - x and y axis using the following Fourier series: + CurvePlanarFourier is a curve that is represented using the following Fourier series: r(phi) = \sum_{n=0}^{order} x_{c,n}cos(n*nfp*phi) + \sum_{n=1}^order x_{s,n}sin(n*nfp*phi) - with rotation about an axis and angle determine by a set of quarternions - q = [cos(\theta/2), x * sin(\theta/2), y * sin(\theta/2), z * sin(\theta/2)] + with rotation about an axis and angle determined by a set of quarternions + q = [q_0, q_1, q_2, q_3] = [cos(\theta/2), x * sin(\theta/2), y * sin(\theta/2), z * sin(\theta/2)] + + Quaternions are normalized to prevent scaling the curves, but remain unnormalized as dofs to prevent optimization error. + + A center vector is used to specify the location of the center of the curve: + + c = [c_x, c_y, c_z] The dofs are stored in the order - [r_{c,0},...,r_{c,order},r_{s,1},...,r_{s,order},t_{x},t_{y}] + [r_{c,0},...,r_{c,order},r_{s,1},...,r_{s,order}, q_0, q_1, q_2, q_3, c_x, c_y, c_z] */ public: From b03fa7d6404bfbb95792770ee326e41ecc97dcc1 Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Tue, 3 Oct 2023 13:50:01 -0400 Subject: [PATCH 07/21] Linted --- examples/2_Intermediate/stage_two_optimization_planar_coils.py | 3 ++- src/simsopt/geo/curve.py | 3 ++- src/simsopt/geo/curveplanarfourier.py | 2 +- tests/geo/test_curve.py | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/2_Intermediate/stage_two_optimization_planar_coils.py b/examples/2_Intermediate/stage_two_optimization_planar_coils.py index a621a10b1..e3eb2dfaf 100755 --- a/examples/2_Intermediate/stage_two_optimization_planar_coils.py +++ b/examples/2_Intermediate/stage_two_optimization_planar_coils.py @@ -110,7 +110,7 @@ # Define the individual terms objective function: Jf = SquaredFlux(s, bs) Jls = [CurveLength(c) for c in base_curves] -Jccdist = CurveCurveDistance(curves, CC_THRESHOLD, num_basecurves=ncoils) #Error +Jccdist = CurveCurveDistance(curves, CC_THRESHOLD, num_basecurves=ncoils) # Error Jcsdist = CurveSurfaceDistance(curves, s, CS_THRESHOLD) Jcs = [LpCurveCurvature(c, 2, CURVATURE_THRESHOLD) for c in base_curves] Jmscs = [MeanSquaredCurvature(c) for c in base_curves] @@ -131,6 +131,7 @@ # are not in least-squares form, so we write a little wrapper function that we # pass directly to scipy.optimize.minimize + def fun(dofs): JF.x = dofs J = JF.J() diff --git a/src/simsopt/geo/curve.py b/src/simsopt/geo/curve.py index 925e01738..1b68e47f5 100644 --- a/src/simsopt/geo/curve.py +++ b/src/simsopt/geo/curve.py @@ -883,6 +883,7 @@ def create_equally_spaced_curves(ncurves, nfp, stellsym, R0=1.0, R1=0.5, order=6 curves.append(curve) return curves + def create_equally_spaced_planar_curves(ncurves, nfp, stellsym, R0=1.0, R1=0.5, order=6, numquadpoints=None): """ Create ``ncurves`` curves of type @@ -906,7 +907,7 @@ def create_equally_spaced_planar_curves(ncurves, nfp, stellsym, R0=1.0, R1=0.5, center = [R0 * cos(angle), R0 * sin(angle), 0] rotation = [1, -cos(angle), -sin(angle), 0] dofs = np.zeros(len(curve.get_dofs())) - + j = 0 for i in rcCoeffs: dofs[j] = i diff --git a/src/simsopt/geo/curveplanarfourier.py b/src/simsopt/geo/curveplanarfourier.py index 1ef453d18..ddf8cec36 100644 --- a/src/simsopt/geo/curveplanarfourier.py +++ b/src/simsopt/geo/curveplanarfourier.py @@ -23,7 +23,7 @@ class CurvePlanarFourier(sopp.CurvePlanarFourier, Curve): .. math:: [r_{c,0}, \cdots, r_{c,\text{order}}, r_{s,1}, \cdots, r_{s,\text{order}}, q_0, q_i, q_j, q_k, x_{\text{center}}, y_{\text{center}}, z_{\text{center}}] - + """ diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 817430220..59c480c48 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -100,6 +100,7 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): class Testing(unittest.TestCase): curvetypes = ["CurveXYZFourier", "JaxCurveXYZFourier", "CurveRZFourier", "CurvePlanarFourier", "CurveHelical", "CurveHelicalInitx0"] + def test_curve_helical_xyzfourier(self): x = np.asarray([0.6]) curve1 = CurveHelical(x, 2, 5, 2, 1.0, 0.3) From e2a76499ef619439a7ea2ad11fd04baa9ed5878d Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Wed, 4 Oct 2023 06:56:36 -0400 Subject: [PATCH 08/21] Tweaks to docs --- docs/source/simsopt.geo.rst | 8 ++++++ .../stage_two_optimization_planar_coils.py | 26 +++++++++++-------- examples/run_serial_examples | 1 + src/simsopt/geo/__init__.py | 2 ++ src/simsopt/geo/curveplanarfourier.py | 26 ++++++++++++++----- 5 files changed, 45 insertions(+), 18 deletions(-) diff --git a/docs/source/simsopt.geo.rst b/docs/source/simsopt.geo.rst index 9bb006c3c..0a1bf5c32 100644 --- a/docs/source/simsopt.geo.rst +++ b/docs/source/simsopt.geo.rst @@ -60,6 +60,14 @@ simsopt.geo.curverzfourier module :undoc-members: :show-inheritance: +simsopt.geo.curveplanarfourier module +------------------------------------- + +.. automodule:: simsopt.geo.curveplanarfourier + :members: + :undoc-members: + :show-inheritance: + simsopt.geo.curvexyzfourier module ---------------------------------- diff --git a/examples/2_Intermediate/stage_two_optimization_planar_coils.py b/examples/2_Intermediate/stage_two_optimization_planar_coils.py index e3eb2dfaf..c84525868 100755 --- a/examples/2_Intermediate/stage_two_optimization_planar_coils.py +++ b/examples/2_Intermediate/stage_two_optimization_planar_coils.py @@ -1,5 +1,10 @@ #!/usr/bin/env python r""" +This coil optimization script is similar to stage_two_optimization.py. However +in this version, the coils are constrained to be planar, by using the curve type +CurvePlanarFourier. Also the LinkingNumber objective is used to prevent coils +from becoming topologically linked with each other. + In this example we solve a FOCUS like Stage II coil optimisation problem: the goal is to find coils that generate a specific target normal field on a given surface. In this particular case we consider a vacuum field, so the target is @@ -12,6 +17,7 @@ + DISTANCE_WEIGHT * MininumDistancePenalty(DISTANCE_THRESHOLD) + CURVATURE_WEIGHT * CurvaturePenalty(CURVATURE_THRESHOLD) + MSC_WEIGHT * MeanSquaredCurvaturePenalty(MSC_THRESHOLD) + + LinkingNumber if any of the weights are increased, or the thresholds are tightened, the coils are more regular and better separated, but the target normal field may not be @@ -25,15 +31,14 @@ from pathlib import Path import numpy as np from scipy.optimize import minimize -from simsopt.objectives import Weight -from simsopt.geo import SurfaceRZFourier -from simsopt.objectives import SquaredFlux -from simsopt.objectives import QuadraticPenalty -from simsopt.geo import curves_to_vtk, create_equally_spaced_planar_curves -from simsopt.field import BiotSavart -from simsopt.field import Current, coils_via_symmetries -from simsopt.geo import CurveLength, CurveCurveDistance, \ - MeanSquaredCurvature, LpCurveCurvature, CurveSurfaceDistance, LinkingNumber +from simsopt.field import BiotSavart, Current, coils_via_symmetries +from simsopt.geo import ( + CurveLength, CurveCurveDistance, + MeanSquaredCurvature, LpCurveCurvature, CurveSurfaceDistance, LinkingNumber, + SurfaceRZFourier, curves_to_vtk, create_equally_spaced_planar_curves, +) +from simsopt.objectives import Weight, SquaredFlux, QuadraticPenalty +from simsopt.util import in_github_actions # Number of unique coil shapes, i.e. the number of coils per half field period: # (Since the configuration has nfp = 2, multiply by 4 to get the total number of coils.) @@ -70,8 +75,7 @@ MSC_WEIGHT = 1e-6 # Number of iterations to perform: -ci = "CI" in os.environ and os.environ['CI'].lower() in ['1', 'true'] -MAXITER = 50 if ci else 400 +MAXITER = 50 if in_github_actions else 400 # File for the desired boundary magnetic surface: TEST_DIR = (Path(__file__).parent / ".." / ".." / "tests" / "test_files").resolve() diff --git a/examples/run_serial_examples b/examples/run_serial_examples index 163ff6ad4..4d7ee176a 100755 --- a/examples/run_serial_examples +++ b/examples/run_serial_examples @@ -16,6 +16,7 @@ set -ex ./2_Intermediate/QSC.py ./2_Intermediate/boozer.py ./2_Intermediate/stage_two_optimization.py +./2_Intermediate/stage_two_optimization_planar.py ./2_Intermediate/stage_two_optimization_stochastic.py ./2_Intermediate/stage_two_optimization_finite_beta.py ./2_Intermediate/strain_optimization.py diff --git a/src/simsopt/geo/__init__.py b/src/simsopt/geo/__init__.py index bc6d0efe2..beb5e57b6 100644 --- a/src/simsopt/geo/__init__.py +++ b/src/simsopt/geo/__init__.py @@ -8,6 +8,7 @@ from .curvexyzfourier import * from .curveperturbed import * from .curveobjectives import * +from .curveplanarfourier import * from .framedcurve import * from .finitebuild import * from .plotting import * @@ -28,6 +29,7 @@ __all__ = (curve.__all__ + curvehelical.__all__ + curverzfourier.__all__ + curvexyzfourier.__all__ + curveperturbed.__all__ + curveobjectives.__all__ + + curveplanarfourier.__all__ + finitebuild.__all__ + plotting.__all__ + boozersurface.__all__ + qfmsurface.__all__ + surface.__all__ + diff --git a/src/simsopt/geo/curveplanarfourier.py b/src/simsopt/geo/curveplanarfourier.py index ddf8cec36..476ff9600 100644 --- a/src/simsopt/geo/curveplanarfourier.py +++ b/src/simsopt/geo/curveplanarfourier.py @@ -9,15 +9,27 @@ class CurvePlanarFourier(sopp.CurvePlanarFourier, Curve): r""" - ``CurvePlanarFourier`` is a curve that is represented by a polar coordinate fourier serires, a rotation quaternion, and a center point following the form: + ``CurvePlanarFourier`` is a curve that is represented by a polar coordinate + Fourier serires, a rotation quaternion, and a center point following the + form: + .. math:: - r(\phi) &= \sum_{m=0}^{\text{order}} r_{c,m}\cos(n_{\text{fp}} m \phi) + \sum_{m=1}^{\text{order}} r_{s,m}\sin(n_{\text{fp}} m \phi) - \bf{q} &= [q_0,q_i,q_j,q_k] &= [\cos(\theta / 2), \hat{x}\sin(\theta / 2), \hat{y}\sin(\theta / 2), \hat{z}\sin(\theta / 2)] - where :math:'\theta' is the counterclockwise rotation about a unit axis :math:'(\hat{x},\hat{y},\hat{z})'. - The quaternion is normalized for calculations to prevent scaling. The dofs themselves are not normalized. This results in a redundancy in the optimization, - where several different sets of dofs may correspond to the same normalized quaternion. - Normalizing the dofs directly would create a dependence between the quaternion dofs, which may cause issues during optimization. + r(\phi) &= \sum_{m=0}^{\text{order}} r_{c,m}\cos(m \phi) + \sum_{m=1}^{\text{order}} r_{s,m}\sin(m \phi) + + \bf{q} &= [q_0,q_i,q_j,q_k] + + &= [\cos(\theta / 2), \hat{x}\sin(\theta / 2), \hat{y}\sin(\theta / 2), \hat{z}\sin(\theta / 2)] + + where :math:`\theta` is the counterclockwise rotation about a unit axis + :math:`(\hat{x},\hat{y},\hat{z})`. + + The quaternion is normalized for calculations to prevent scaling. The dofs + themselves are not normalized. This results in a redundancy in the + optimization, where several different sets of dofs may correspond to the + same normalized quaternion. Normalizing the dofs directly would create a + dependence between the quaternion dofs, which may cause issues during + optimization. The dofs are stored in the order From ae5daa811ce5a70c9959bee2b2b6447cc5df01c4 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Wed, 4 Oct 2023 07:58:12 -0400 Subject: [PATCH 09/21] fix filename --- examples/run_serial_examples | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/run_serial_examples b/examples/run_serial_examples index 4d7ee176a..b87f64702 100755 --- a/examples/run_serial_examples +++ b/examples/run_serial_examples @@ -16,7 +16,7 @@ set -ex ./2_Intermediate/QSC.py ./2_Intermediate/boozer.py ./2_Intermediate/stage_two_optimization.py -./2_Intermediate/stage_two_optimization_planar.py +./2_Intermediate/stage_two_optimization_planar_coils.py ./2_Intermediate/stage_two_optimization_stochastic.py ./2_Intermediate/stage_two_optimization_finite_beta.py ./2_Intermediate/strain_optimization.py From ff23c3c498241465bd1e6dfc48ada195bfb8d5ed Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Wed, 1 Nov 2023 21:08:09 -0400 Subject: [PATCH 10/21] Fixed several issues requested for commit --- .../stage_two_optimization_planar_coils.py | 2 +- src/simsopt/geo/curveplanarfourier.py | 15 +- src/simsoptpp/curveplanarfourier.cpp | 2573 ++++++++--------- src/simsoptpp/curveplanarfourier.h | 2 + tests/geo/test_curve.py | 1 - tests/geo/test_equally_spaced_planar_coils.py | 26 + 6 files changed, 1293 insertions(+), 1326 deletions(-) create mode 100644 tests/geo/test_equally_spaced_planar_coils.py diff --git a/examples/2_Intermediate/stage_two_optimization_planar_coils.py b/examples/2_Intermediate/stage_two_optimization_planar_coils.py index c84525868..d32ca4da8 100755 --- a/examples/2_Intermediate/stage_two_optimization_planar_coils.py +++ b/examples/2_Intermediate/stage_two_optimization_planar_coils.py @@ -114,7 +114,7 @@ # Define the individual terms objective function: Jf = SquaredFlux(s, bs) Jls = [CurveLength(c) for c in base_curves] -Jccdist = CurveCurveDistance(curves, CC_THRESHOLD, num_basecurves=ncoils) # Error +Jccdist = CurveCurveDistance(curves, CC_THRESHOLD, num_basecurves=ncoils) Jcsdist = CurveSurfaceDistance(curves, s, CS_THRESHOLD) Jcs = [LpCurveCurvature(c, 2, CURVATURE_THRESHOLD) for c in base_curves] Jmscs = [MeanSquaredCurvature(c) for c in base_curves] diff --git a/src/simsopt/geo/curveplanarfourier.py b/src/simsopt/geo/curveplanarfourier.py index 476ff9600..264e85a86 100644 --- a/src/simsopt/geo/curveplanarfourier.py +++ b/src/simsopt/geo/curveplanarfourier.py @@ -23,13 +23,14 @@ class CurvePlanarFourier(sopp.CurvePlanarFourier, Curve): where :math:`\theta` is the counterclockwise rotation about a unit axis :math:`(\hat{x},\hat{y},\hat{z})`. - - The quaternion is normalized for calculations to prevent scaling. The dofs - themselves are not normalized. This results in a redundancy in the - optimization, where several different sets of dofs may correspond to the - same normalized quaternion. Normalizing the dofs directly would create a - dependence between the quaternion dofs, which may cause issues during - optimization. + + A quaternion is used for rotation rather than other methods for rotation to + prevent gimbal locking during optimization. The quaternion is normalized for + calculations to prevent scaling. The dofs themselves are not normalized. This + results in a redundancy in the optimization, where several different sets of + dofs may correspond to the same normalized quaternion. Normalizing the dofs + directly would create a dependence between the quaternion dofs, which may cause + issues during optimization. The dofs are stored in the order diff --git a/src/simsoptpp/curveplanarfourier.cpp b/src/simsoptpp/curveplanarfourier.cpp index ceda2e9aa..a3db9e2bf 100644 --- a/src/simsoptpp/curveplanarfourier.cpp +++ b/src/simsoptpp/curveplanarfourier.cpp @@ -1,22 +1,25 @@ #include "curveplanarfourier.h" - template -void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { - int numquadpoints = quadpoints.size(); - data *= 0; - - /* Converts q dofs to unit quaternion */ - Array q_norm = xt::zeros({4}); +double CurvePlanarFourier::inv_magnitude() { double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; if(s != 0) { - for (int i = 0; i < 4; ++i) - q_norm[i] = q[i] / std::sqrt(s); + double sqrt_inv_s = 1 / std::sqrt(s); + return sqrt_inv_s; } else { - q_norm[0] = 1; + return 1; } +} + +template +void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { + int numquadpoints = quadpoints.size(); + data *= 0; + + Array q_norm = q * inv_magnitude(); + for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; @@ -24,9 +27,6 @@ void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { data(k, 0) += rc[i] * cos(i*phi) * cos(phi); data(k, 1) += rc[i] * cos(i*phi) * sin(phi); } - } - for (int k = 0; k < numquadpoints; ++k) { - double phi = 2 * M_PI * quadpoints[k]; for (int i = 1; i < order+1; ++i) { data(k, 0) += rs[i-1] * sin(i*phi) * cos(phi); data(k, 1) += rs[i-1] * sin(i*phi) * sin(phi); @@ -40,6 +40,7 @@ void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { j = data(m, 1); k = data(m, 2); + /* Performs quaternion based rotation, see https://www.cis.upenn.edu/~cis5150/ws-book-Ib.pdf page 575, 576 for details regarding this rotation*/ data(m, 0) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k) + center[0]; data(m, 1) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k) + center[1]; data(m, 2) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k) + center[2]; @@ -50,16 +51,8 @@ template void CurvePlanarFourier::gammadash_impl(Array& data) { data *= 0; - /* Converts q dofs to unit quaternion */ - Array q_norm = xt::zeros({4}); - double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; - if(s != 0) { - for (int i = 0; i < 4; ++i) - q_norm[i] = q[i] / std::sqrt(s); - } - else { - q_norm[0] = 1; - } + double inv_sqrt_s = inv_magnitude(); + Array q_norm = q * inv_sqrt_s; for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; @@ -67,26 +60,26 @@ void CurvePlanarFourier::gammadash_impl(Array& data) { data(k, 0) += rc[i] * ( -(i) * sin(i*phi) * cos(phi) - cos(i*phi) * sin(phi)); data(k, 1) += rc[i] * ( -(i) * sin(i*phi) * sin(phi) + cos(i*phi) * cos(phi)); } - } - for (int k = 0; k < numquadpoints; ++k) { - double phi = 2 * M_PI * quadpoints[k]; for (int i = 1; i < order+1; ++i) { data(k, 0) += rs[i-1] * ( (i) * cos(i*phi) * cos(phi) - sin(i*phi) * sin(phi)); data(k, 1) += rs[i-1] * ( (i) * cos(i*phi) * sin(phi) + sin(i*phi) * cos(phi)); } } + data *= (2*M_PI); for (int m = 0; m < numquadpoints; ++m) { - Array i = xt::zeros({1}); - i[0] = data(m, 0); - Array j = xt::zeros({1}); - j[0] = data(m, 1); - Array k = xt::zeros({1}); - k[0] = data(m, 2); - - data(m, 0) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); - data(m, 1) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); - data(m, 2) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); + double i; + double j; + double k; + i = data(m, 0); + j = data(m, 1); + k = data(m, 2); + + + /* Performs quaternion based rotation, see https://www.cis.upenn.edu/~cis5150/ws-book-Ib.pdf page 575, 576 for details regarding this rotation*/ + data(m, 0) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); + data(m, 1) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k); + data(m, 2) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k); } } @@ -95,45 +88,33 @@ template void CurvePlanarFourier::gammadashdash_impl(Array& data) { data *= 0; - /* Converts q dofs to unit quaternion */ - Array q_norm = xt::zeros({4}); - double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; - if(s != 0) { - for (int i = 0; i < 4; ++i) - q_norm[i] = q[i] / std::sqrt(s); - } - else { - q_norm[0] = 1; - } + Array q_norm = q * inv_magnitude(); for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; for (int i = 0; i < order+1; ++i) { - data(k, 0) += rc[i] * (+2*(i)*sin(i*phi)*sin(phi)-(pow(i, 2)+1)*cos(i*phi)*cos(phi)); - data(k, 1) += rc[i] * (-2*(i)*sin(i*phi)*cos(phi)-(pow(i, 2)+1)*cos(i*phi)*sin(phi)); + data(k, 0) += rc[i] * (+2*(i)*sin(i*phi)*sin(phi)-(i*i+1)*cos(i*phi)*cos(phi)); + data(k, 1) += rc[i] * (-2*(i)*sin(i*phi)*cos(phi)-(i*i+1)*cos(i*phi)*sin(phi)); } - data(k, 2) = 0; - } - for (int k = 0; k < numquadpoints; ++k) { - double phi = 2 * M_PI * quadpoints[k]; for (int i = 1; i < order+1; ++i) { - data(k, 0) += rs[i-1] * (-(pow(i,2)+1)*sin(i*phi)*cos(phi) - 2*(i)*cos(i*phi)*sin(phi)); - data(k, 1) += rs[i-1] * (-(pow(i,2)+1)*sin(i*phi)*sin(phi) + 2*(i)*cos(i*phi)*cos(phi)); + data(k, 0) += rs[i-1] * (-(i*i+1)*sin(i*phi)*cos(phi) - 2*(i)*cos(i*phi)*sin(phi)); + data(k, 1) += rs[i-1] * (-(i*i+1)*sin(i*phi)*sin(phi) + 2*(i)*cos(i*phi)*cos(phi)); } - data(k, 2) = 0; } data *= 2*M_PI*2*M_PI; for (int m = 0; m < numquadpoints; ++m) { - Array i = xt::zeros({1}); - i[0] = data(m, 0); - Array j = xt::zeros({1}); - j[0] = data(m, 1); - Array k = xt::zeros({1}); - k[0] = data(m, 2); + double i; + double j; + double k; + i = data(m, 0); + j = data(m, 1); + k = data(m, 2); + - data(m, 0) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); - data(m, 1) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); - data(m, 2) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); + /* Performs quaternion based rotation*/ + data(m, 0) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); + data(m, 1) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k); + data(m, 2) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k); } } @@ -142,55 +123,45 @@ template void CurvePlanarFourier::gammadashdashdash_impl(Array& data) { data *= 0; - /* Converts q dofs to unit quaternion */ - Array q_norm = xt::zeros({4}); - double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; - if(s != 0) { - for (int i = 0; i < 4; ++i) - q_norm[i] = q[i] / std::sqrt(s); - } - else { - q_norm[0] = 1; - } + Array q_norm = q * inv_magnitude(); for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; for (int i = 0; i < order+1; ++i) { data(k, 0) += rc[i]*( - +(3*pow(i, 2) + 1)*cos(i*phi)*sin(phi) - +(pow(i, 2) + 3)*(i)*sin(i*phi)*cos(phi) + +(3*i*i + 1)*cos(i*phi)*sin(phi) + +(i*i + 3)*(i)*sin(i*phi)*cos(phi) ); data(k, 1) += rc[i]*( - +(pow(i, 2) + 3)*(i)*sin(i*phi)*sin(phi) - -(3*pow(i, 2) + 1)*cos(i*phi)*cos(phi) + +(i*i + 3)*(i)*sin(i*phi)*sin(phi) + -(3*i*i + 1)*cos(i*phi)*cos(phi) ); } - } - for (int k = 0; k < numquadpoints; ++k) { - double phi = 2 * M_PI * quadpoints[k]; for (int i = 1; i < order+1; ++i) { data(k, 0) += rs[i-1]*( - -(pow(i,2)+3) * (i) * cos(i*phi)*cos(phi) - +(3*pow(i,2)+1) * sin(i*phi)*sin(phi) + -(i*i+3) * (i) * cos(i*phi)*cos(phi) + +(3*i*i+1) * sin(i*phi)*sin(phi) ); data(k, 1) += rs[i-1]*( - -(pow(i,2)+3)*(i)*cos(i*phi)*sin(phi) - -(3*pow(i,2)+1)*sin(i*phi)*cos(phi) + -(i*i+3)*(i)*cos(i*phi)*sin(phi) + -(3*i*i+1)*sin(i*phi)*cos(phi) ); } } data *= 2*M_PI*2*M_PI*2*M_PI; for (int m = 0; m < numquadpoints; ++m) { - Array i = xt::zeros({1}); - i[0] = data(m, 0); - Array j = xt::zeros({1}); - j[0] = data(m, 1); - Array k = xt::zeros({1}); - k[0] = data(m, 2); + double i; + double j; + double k; + i = data(m, 0); + j = data(m, 1); + k = data(m, 2); + - data(m, 0) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); - data(m, 1) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); - data(m, 2) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); + /* Performs quaternion based rotation*/ + data(m, 0) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); + data(m, 1) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k); + data(m, 2) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k); } } @@ -199,335 +170,327 @@ template void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { data *= 0; - /* Converts q dofs to unit quaternion */ - Array q_norm = xt::zeros({4}); - double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; - if(s != 0) { - for (int i = 0; i < 4; ++i) - q_norm[i] = q[i] / std::sqrt(s); - } - else { - q_norm[0] = 1; - } + Array q_norm = q * inv_magnitude(); for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; int counter = 0; - Array i = xt::zeros({1}); - Array j = xt::zeros({1}); - Array k = xt::zeros({1}); + double i; + double j; + double k; for (int n = 0; n < order+1; ++n) { - i[0] = cos(n*phi) * cos(phi); - j[0] = cos(n*phi) * sin(phi); - k[0] = 0; + i = cos(n*phi) * cos(phi); + j = cos(n*phi) * sin(phi); + k = 0; - data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); - data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); - data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); + data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k); counter++; } for (int n = 1; n < order+1; ++n) { - i[0] = sin(n*phi) * cos(phi); - j[0] = sin(n*phi) * sin(phi); - k[0] = 0; + i = sin(n*phi) * cos(phi); + j = sin(n*phi) * sin(phi); + k = 0; - data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); - data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); - data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); + data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k); counter++; } - i[0] = 0; - j[0] = 0; - k[0] = 0; + i = 0; + j = 0; + k = 0; for (int n = 0; n < order+1; ++n) { - i[0] += rc[n] * cos(n*phi) * cos(phi); - j[0] += rc[n] * cos(n*phi) * sin(phi); + i += rc[n] * cos(n*phi) * cos(phi); + j += rc[n] * cos(n*phi) * sin(phi); } for (int n = 1; n < order+1; ++n) { - i[0] += rs[n-1] * sin(n*phi) * cos(phi); - j[0] += rs[n-1] * sin(n*phi) * sin(phi); + i += rs[n-1] * sin(n*phi) * cos(phi); + j += rs[n-1] * sin(n*phi) * sin(phi); } + double inv_sqrt_s = inv_magnitude(); - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; @@ -546,341 +509,333 @@ template void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { data *= 0; - /* Converts q dofs to unit quaternion */ - Array q_norm = xt::zeros({4}); - double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; - if(s != 0) { - for (int i = 0; i < 4; ++i) - q_norm[i] = q[i] / std::sqrt(s); - } - else { - q_norm[0] = 1; - } + Array q_norm = q * inv_magnitude(); for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; int counter = 0; - Array i = xt::zeros({1}); - Array j = xt::zeros({1}); - Array k = xt::zeros({1}); + double i; + double j; + double k; for (int n = 0; n < order+1; ++n) { - i[0] = ( -(n) * sin(n*phi) * cos(phi) - cos(n*phi) * sin(phi)); - j[0] = ( -(n) * sin(n*phi) * sin(phi) + cos(n*phi) * cos(phi)); - k[0] = 0; + i = ( -(n) * sin(n*phi) * cos(phi) - cos(n*phi) * sin(phi)); + j = ( -(n) * sin(n*phi) * sin(phi) + cos(n*phi) * cos(phi)); + k = 0; - i[0] *= (2*M_PI); - j[0] *= (2*M_PI); + i *= (2*M_PI); + j *= (2*M_PI); - data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); - data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); - data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); + data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k); counter++; } for (int n = 1; n < order+1; ++n) { - i[0] = ( (n) * cos(n*phi) * cos(phi) - sin(n*phi) * sin(phi)); - j[0] = ( (n) * cos(n*phi) * sin(phi) + sin(n*phi) * cos(phi)); - k[0] = 0; + i = ( (n) * cos(n*phi) * cos(phi) - sin(n*phi) * sin(phi)); + j = ( (n) * cos(n*phi) * sin(phi) + sin(n*phi) * cos(phi)); + k = 0; - i[0] *= (2*M_PI); - j[0] *= (2*M_PI); + i *= (2*M_PI); + j *= (2*M_PI); - data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); - data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); - data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); + data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k); counter++; } - i[0] = 0; - j[0] = 0; - k[0] = 0; + i = 0; + j = 0; + k = 0; for (int n = 0; n < order+1; ++n) { - i[0] += rc[n] * ( -(n) * sin(n*phi) * cos(phi) - cos(n*phi) * sin(phi)) * 2 * M_PI; - j[0] += rc[n] * ( -(n) * sin(n*phi) * sin(phi) + cos(n*phi) * cos(phi)) * 2 * M_PI; + i += rc[n] * ( -(n) * sin(n*phi) * cos(phi) - cos(n*phi) * sin(phi)) * 2 * M_PI; + j += rc[n] * ( -(n) * sin(n*phi) * sin(phi) + cos(n*phi) * cos(phi)) * 2 * M_PI; } for (int n = 1; n < order+1; ++n) { - i[0] += rs[n-1] * ( (n) * cos(n*phi) * cos(phi) - sin(n*phi) * sin(phi)) * 2 * M_PI; - j[0] += rs[n-1] * ( (n) * cos(n*phi) * sin(phi) + sin(n*phi) * cos(phi)) * 2 * M_PI; + i += rs[n-1] * ( (n) * cos(n*phi) * cos(phi) - sin(n*phi) * sin(phi)) * 2 * M_PI; + j += rs[n-1] * ( (n) * cos(n*phi) * sin(phi) + sin(n*phi) * cos(phi)) * 2 * M_PI; } - - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + double inv_sqrt_s = inv_magnitude(); + + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; for (int i = 0; i < 2; ++i) { @@ -898,344 +853,336 @@ template void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { data *= 0; - /* Converts q dofs to unit quaternion */ - Array q_norm = xt::zeros({4}); - double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; - if(s != 0) { - for (int i = 0; i < 4; ++i) - q_norm[i] = q[i] / std::sqrt(s); - } - else { - q_norm[0] = 1; - } + Array q_norm = q * inv_magnitude(); for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; int counter = 0; - Array i = xt::zeros({1}); - Array j = xt::zeros({1}); - Array k = xt::zeros({1}); + double i; + double j; + double k; for (int n = 0; n < order+1; ++n) { - i[0] = (+2*(n)*sin(n*phi)*sin(phi)-(pow(n, 2)+1)*cos(n*phi)*cos(phi)); - j[0] = (-2*(n)*sin(n*phi)*cos(phi)-(pow(n, 2)+1)*cos(n*phi)*sin(phi)); - k[0] = 0; + i = (+2*(n)*sin(n*phi)*sin(phi)-(n*n+1)*cos(n*phi)*cos(phi)); + j = (-2*(n)*sin(n*phi)*cos(phi)-(n*n+1)*cos(n*phi)*sin(phi)); + k = 0; - i[0] *= 2*M_PI*2*M_PI; - j[0] *= 2*M_PI*2*M_PI; - k[0] *= 2*M_PI*2*M_PI; + i *= 2*M_PI*2*M_PI; + j *= 2*M_PI*2*M_PI; + k *= 2*M_PI*2*M_PI; - data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); - data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); - data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); + data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k); counter++; } for (int n = 1; n < order+1; ++n) { - i[0] = (-(pow(n,2)+1)*sin(n*phi)*cos(phi) - 2*(n)*cos(n*phi)*sin(phi)); - j[0] = (-(pow(n,2)+1)*sin(n*phi)*sin(phi) + 2*(n)*cos(n*phi)*cos(phi)); - k[0] = 0; + i = (-(n*n+1)*sin(n*phi)*cos(phi) - 2*(n)*cos(n*phi)*sin(phi)); + j = (-(n*n+1)*sin(n*phi)*sin(phi) + 2*(n)*cos(n*phi)*cos(phi)); + k = 0; - i[0] *= 2*M_PI*2*M_PI; - j[0] *= 2*M_PI*2*M_PI; - k[0] *= 2*M_PI*2*M_PI; + i *= 2*M_PI*2*M_PI; + j *= 2*M_PI*2*M_PI; + k *= 2*M_PI*2*M_PI; - data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); - data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); - data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); + data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k); counter++; } - i[0] = 0; - j[0] = 0; - k[0] = 0; + i = 0; + j = 0; + k = 0; for (int n = 0; n < order+1; ++n) { - i[0] += rc[n] * (+2*(n)*sin(n*phi)*sin(phi)-(pow(n, 2)+1)*cos(n*phi)*cos(phi)); - j[0] += rc[n] * (-2*(n)*sin(n*phi)*cos(phi)-(pow(n, 2)+1)*cos(n*phi)*sin(phi)); + i += rc[n] * (+2*(n)*sin(n*phi)*sin(phi)-(n*n+1)*cos(n*phi)*cos(phi)); + j += rc[n] * (-2*(n)*sin(n*phi)*cos(phi)-(n*n+1)*cos(n*phi)*sin(phi)); } for (int n = 1; n < order+1; ++n) { - i[0] += rs[n-1] * (-(pow(n,2)+1)*sin(n*phi)*cos(phi) - 2*(n)*cos(n*phi)*sin(phi)); - j[0] += rs[n-1] * (-(pow(n,2)+1)*sin(n*phi)*sin(phi) + 2*(n)*cos(n*phi)*cos(phi)); + i += rs[n-1] * (-(n*n+1)*sin(n*phi)*cos(phi) - 2*(n)*cos(n*phi)*sin(phi)); + j += rs[n-1] * (-(n*n+1)*sin(n*phi)*sin(phi) + 2*(n)*cos(n*phi)*cos(phi)); } - i[0] *= 2*M_PI*2*M_PI; - j[0] *= 2*M_PI*2*M_PI; - k[0] *= 2*M_PI*2*M_PI; + i *= 2*M_PI*2*M_PI; + j *= 2*M_PI*2*M_PI; + k *= 2*M_PI*2*M_PI; + double inv_sqrt_s = inv_magnitude(); - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; for (int i = 0; i < 3; ++i) { @@ -1252,368 +1199,360 @@ template void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { data *= 0; - /* Converts q dofs to unit quaternion */ - Array q_norm = xt::zeros({4}); - double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; - if(s != 0) { - for (int i = 0; i < 4; ++i) - q_norm[i] = q[i] / std::sqrt(s); - } - else { - q_norm[0] = 1; - } + Array q_norm = q * inv_magnitude(); for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; int counter = 0; - Array i = xt::zeros({1}); - Array j = xt::zeros({1}); - Array k = xt::zeros({1}); + double i; + double j; + double k; for (int n = 0; n < order+1; ++n) { - i[0] = ( - +(3*pow(n, 2) + 1)*cos(n*phi)*sin(phi) - +(pow(n, 2) + 3)*(n)*sin(n*phi)*cos(phi) + i = ( + +(3*n*n + 1)*cos(n*phi)*sin(phi) + +(n*n + 3)*(n)*sin(n*phi)*cos(phi) ); - j[0] = ( - +(pow(n, 2) + 3)*(n)*sin(n*phi)*sin(phi) - -(3*pow(n, 2) + 1)*cos(n*phi)*cos(phi) + j = ( + +(n*n + 3)*(n)*sin(n*phi)*sin(phi) + -(3*n*n + 1)*cos(n*phi)*cos(phi) ); - k[0] = 0; + k = 0; - i[0] *= 2*M_PI*2*M_PI*2*M_PI; - j[0] *= 2*M_PI*2*M_PI*2*M_PI; - k[0] *= 2*M_PI*2*M_PI*2*M_PI; + i *= 2*M_PI*2*M_PI*2*M_PI; + j *= 2*M_PI*2*M_PI*2*M_PI; + k *= 2*M_PI*2*M_PI*2*M_PI; - data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); - data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); - data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); + data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k); counter++; } for (int n = 1; n < order+1; ++n) { - i[0] = ( - -(pow(n,2)+3) * (n) * cos(n*phi)*cos(phi) - +(3*pow(n,2)+1) * sin(n*phi)*sin(phi) + i = ( + -(n*n+3) * (n) * cos(n*phi)*cos(phi) + +(3*n*n+1) * sin(n*phi)*sin(phi) ); - j[0] = ( - -(pow(n,2)+3)*(n)*cos(n*phi)*sin(phi) - -(3*pow(n,2)+1)*sin(n*phi)*cos(phi) + j = ( + -(n*n+3)*(n)*cos(n*phi)*sin(phi) + -(3*n*n+1)*sin(n*phi)*cos(phi) ); - k[0] = 0; + k = 0; - i[0] *= 2*M_PI*2*M_PI*2*M_PI; - j[0] *= 2*M_PI*2*M_PI*2*M_PI; - k[0] *= 2*M_PI*2*M_PI*2*M_PI; + i *= 2*M_PI*2*M_PI*2*M_PI; + j *= 2*M_PI*2*M_PI*2*M_PI; + k *= 2*M_PI*2*M_PI*2*M_PI; - data(m, 0, counter) = (i[0] - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i[0] + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j[0] + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k[0]); - data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i[0] + j[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j[0] + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k[0]); - data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i[0] + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j[0] + k[0] - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k[0]); + data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); + data(m, 1, counter) = (2 * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * i + j - 2 * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * j + 2 * (q_norm[2] * q_norm[3] - q_norm[1] * q_norm[0]) * k); + data(m, 2, counter) = (2 * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * i + 2 * (q_norm[2] * q_norm[3] + q_norm[1] * q_norm[0]) * j + k - 2 * (q_norm[1] * q_norm[1] + q_norm[2] * q_norm[2]) * k); counter++; } - i[0] = 0; - j[0] = 0; - k[0] = 0; + i = 0; + j = 0; + k = 0; for (int n = 0; n < order+1; ++n) { - i[0] += rc[n]*( - +(3*pow(n, 2) + 1)*cos(n*phi)*sin(phi) - +(pow(n, 2) + 3)*(n)*sin(n*phi)*cos(phi) + i += rc[n]*( + +(3*n*n + 1)*cos(n*phi)*sin(phi) + +(n*n + 3)*(n)*sin(n*phi)*cos(phi) ); - j[0] += rc[n]*( - +(pow(n, 2) + 3)*(n)*sin(n*phi)*sin(phi) - -(3*pow(n, 2) + 1)*cos(n*phi)*cos(phi) + j += rc[n]*( + +(n*n + 3)*(n)*sin(n*phi)*sin(phi) + -(3*n*n + 1)*cos(n*phi)*cos(phi) ); } for (int n = 1; n < order+1; ++n) { - i[0] += rs[n-1]*( - -(pow(n,2)+3) * (n) * cos(n*phi)*cos(phi) - +(3*pow(n,2)+1) * sin(n*phi)*sin(phi) + i += rs[n-1]*( + -(n*n+3) * (n) * cos(n*phi)*cos(phi) + +(3*n*n+1) * sin(n*phi)*sin(phi) ); - j[0] += rs[n-1]*( - -(pow(n,2)+3)*(n)*cos(n*phi)*sin(phi) - -(3*pow(n,2)+1)*sin(n*phi)*cos(phi) + j += rs[n-1]*( + -(n*n+3)*(n)*cos(n*phi)*sin(phi) + -(3*n*n+1)*sin(n*phi)*cos(phi) ); } - i[0] *= 2*M_PI*2*M_PI*2*M_PI; - j[0] *= 2*M_PI*2*M_PI*2*M_PI; - k[0] *= 2*M_PI*2*M_PI*2*M_PI; + i *= 2*M_PI*2*M_PI*2*M_PI; + j *= 2*M_PI*2*M_PI*2*M_PI; + k *= 2*M_PI*2*M_PI*2*M_PI; + double inv_sqrt_s = inv_magnitude(); - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[0] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[0] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (inv_sqrt_s - q[0] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[0] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (1 / std::sqrt(s) - q[1] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[1] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (inv_sqrt_s - q[1] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[1] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[2] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (- q[3] * q[2] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (inv_sqrt_s - q[2] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (- q[3] * q[2] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; - data(m, 0, counter) = (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] - - 2 * j[0] * q_norm[3]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[0] + - 2 * j * q_norm[3]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - + (4 * i[0] * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[2]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + + (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[2]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (- 4 * i[0] * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[1]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) + (- 4 * i * (q_norm[0] * q_norm[0] + q_norm[1] * q_norm[1]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[1]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + - (- 4 * i[0] * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] - - 2 * j[0] * q_norm[0]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 1, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] - + 2 * i[0] * q_norm[3] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[2] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] - - 4 * j[0] * q_norm[1]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] - + 2 * i[0] * q_norm[1] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] - + 2 * i[0] * q_norm[0] - + 4 * j[0] * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] - - 4 * j[0] * q_norm[3]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); - - - data(m, 2, counter) = (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] - - 2 * i[0] * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] - + 2 * j[0] * q_norm[1]) - * (- q[0] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] - + 2 * i[0] * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] - + 2 * j[0] * q_norm[0]) - * (- q[1] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (- 2 * i[0] * q_norm[0] - - 4 * i[0] * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] - + 2 * j[0] * q_norm[3]) - * (- q[2] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))) - + - (2 * i[0] * q_norm[1] - + 4 * i[0] * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] - - 4 * j[0] * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] - + 2 * j[0] * q_norm[2]) - * (1 / std::sqrt(s) - q[3] * q[3] / (std::sqrt(s) * std::sqrt(s) * std::sqrt(s))); + (- 4 * i * (q_norm[1] * q_norm[1] + q_norm[0] * q_norm[0]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[2] - q_norm[0] * q_norm[3]) * q_norm[3] + - 2 * j * q_norm[0]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 1, counter) = (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[0] + + 2 * i * q_norm[3] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[0]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[2] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[1] + - 4 * j * q_norm[1]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[2] + + 2 * i * q_norm[1] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[2]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[2] + q_norm[3] * q_norm[0]) * q_norm[3] + + 2 * i * q_norm[0] + + 4 * j * (q_norm[1] * q_norm[1] + q_norm[3] * q_norm[3]) * q_norm[3] + - 4 * j * q_norm[3]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); + + + data(m, 2, counter) = (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[0] + - 2 * i * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[0] + + 2 * j * q_norm[1]) + * (- q[0] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 4 * i * (q_norm[1] * q_norm[3] - q_norm[2] * q_norm[0]) * q_norm[1] + + 2 * i * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[1] + + 2 * j * q_norm[0]) + * (- q[1] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (- 2 * i * q_norm[0] + - 4 * i * (q_norm[1] * q_norm[3] - q_norm[0] * q_norm[2]) * q_norm[2] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[2] + + 2 * j * q_norm[3]) + * (- q[2] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s) + + + (2 * i * q_norm[1] + + 4 * i * (q_norm[2] * q_norm[0] - q_norm[1] * q_norm[3]) * q_norm[3] + - 4 * j * (q_norm[1] * q_norm[0] + q_norm[2] * q_norm[3]) * q_norm[3] + + 2 * j * q_norm[2]) + * (inv_sqrt_s - q[3] * q[3] * inv_sqrt_s * inv_sqrt_s * inv_sqrt_s); counter++; for (int i = 0; i < 3; ++i) { diff --git a/src/simsoptpp/curveplanarfourier.h b/src/simsoptpp/curveplanarfourier.h index 4b8b4baee..f365ba88e 100644 --- a/src/simsoptpp/curveplanarfourier.h +++ b/src/simsoptpp/curveplanarfourier.h @@ -101,6 +101,8 @@ class CurvePlanarFourier : public Curve { } + double inv_magnitude(); + void gamma_impl(Array& data, Array& quadpoints) override; void gammadash_impl(Array& data) override; void gammadashdash_impl(Array& data) override; diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 59c480c48..275b6464b 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -509,6 +509,5 @@ def test_load_curves_from_makegrid_file(self): os.remove("coils.file_to_load") - if __name__ == "__main__": unittest.main() diff --git a/tests/geo/test_equally_spaced_planar_coils.py b/tests/geo/test_equally_spaced_planar_coils.py new file mode 100644 index 000000000..4470430fd --- /dev/null +++ b/tests/geo/test_equally_spaced_planar_coils.py @@ -0,0 +1,26 @@ +import unittest +from simsopt.geo.curve import create_equally_spaced_curves, create_equally_spaced_planar_curves +from simsopt.field import coils_via_symmetries, BiotSavart, Current + +class Testing(unittest.TestCase): + def test_equally_spaced_planar_coils(self): + ncoils = 4 + nfp = 4 + stellsym = False + + curves = create_equally_spaced_curves(ncoils, nfp, False) + currents = [Current(1e5) for i in range(ncoils)] + + curves_planar = create_equally_spaced_planar_curves(ncoils, nfp, False) + currents_planar = [Current(1e5) for i in range(ncoils)] + + coils = coils_via_symmetries(curves, currents, nfp, stellsym) + coils_planar = coils_via_symmetries(curves_planar, currents_planar, nfp, stellsym) + bs = BiotSavart(coils) + bs_planar = BiotSavart(coils_planar) + err = bs.AbsB()[0][0] - bs_planar.AbsB()[0][0] + print(err) + assert(err < 3e-10) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From 30bbfc60419007182b8504d8fe39ac4e35616248 Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Wed, 1 Nov 2023 21:12:49 -0400 Subject: [PATCH 11/21] removed input.NewConfiguration --- tests/test_files/input.NewConfiguration | 113 ------------------------ 1 file changed, 113 deletions(-) delete mode 100644 tests/test_files/input.NewConfiguration diff --git a/tests/test_files/input.NewConfiguration b/tests/test_files/input.NewConfiguration deleted file mode 100644 index 9adf5fa4e..000000000 --- a/tests/test_files/input.NewConfiguration +++ /dev/null @@ -1,113 +0,0 @@ -&INDATA -!----- Runtime Parameters ----- - DELT = 9.00E-01 - NITER = 10000 - NSTEP = 200 - TCON0 = 2.00E+00 - -! NS_ARRAY = 16 50 -! NITER_ARRAY = 600 3000 -! FTOL_ARRAY = 1.0E-16 1.0E-13 - -! NS_ARRAY = 12 25 50 -! NITER_ARRAY = 600 1000 6000 -! FTOL_ARRAY = 1.0E-17 1.0e-17 1.0e-15 - -! NS_ARRAY = 12 25 50 75 -! NITER_ARRAY = 600 1000 2500 10000 -! FTOL_ARRAY = 1.0E-17 1.0e-17 1.0e-17 1.0e-17 - - NS_ARRAY = 12 25 50 75 100 150 201 - NITER_ARRAY = 1200 2000 3000 4000 5000 6000 20000 - FTOL_ARRAY = 1.0E-17 1.0e-17 1.0e-17 1.0e-17 1.0e-17 1.0e-17 2.0e-17 - - PRECON_TYPE = 'none' - PREC2D_THRESHOLD = 1.000000E-19 -!----- Grid Parameters ----- - LASYM = F - NFP = 0004 - MPOL = 0008 - NTOR = 0008 - PHIEDGE = 0.0381790210242581 -!----- Free Boundary Parameters ----- - LFREEB = F - NVACSKIP = 6 -!----- Pressure Parameters ----- - GAMMA = 0.000000000000E+000 - BLOAT = 1.000000000000E+000 - SPRES_PED = 1.000000000000E+000 - PRES_SCALE = 1.000000000000E+000 - PMASS_TYPE = 'power_series' - AM = 000000000E+00 -!----- Current/Iota Parameters ----- - CURTOR = 0 - NCURR = 1 - PIOTA_TYPE = 'power_series' - PCURR_TYPE = 'power_series' -!----- Axis Parameters ----- - RAXIS_CC = 0 - ZAXIS_CS = 0 -!----- Boundary Parameters ----- -! n comes before m! -RBC( 0, 0) = 1.000000000000000e+00, ZBS( 0, 0) = -0.000000000000000e+00 -RBC( 1, 0) = 1.798197877372061e-01, ZBS( 1, 0) = 1.526874285925055e-01 -RBC( 2, 0) = 1.734951154350431e-02, ZBS( 2, 0) = 1.866334230413251e-02 -RBC( 3, 0) = 2.577160162049330e-03, ZBS( 3, 0) = 1.199711292212324e-03 -RBC( 4, 0) = -1.637889983682740e-04, ZBS( 4, 0) = 6.984345011786886e-05 -RBC( 5, 0) = -2.425305167830765e-05, ZBS( 5, 0) = -2.548557148257138e-05 -RBC( -5, 1) = -8.577683632032374e-05, ZBS( -5, 1) = 2.045490523320995e-05 -RBC( -4, 1) = -3.374047917343044e-04, ZBS( -4, 1) = 5.046849551418733e-04 -RBC( -3, 1) = -3.641359983759378e-03, ZBS( -3, 1) = 3.782490654681902e-03 -RBC( -2, 1) = -2.444833020873945e-02, ZBS( -2, 1) = 2.427925370183856e-02 -RBC( -1, 1) = -8.731762429558673e-02, ZBS( -1, 1) = 4.517210283176742e-02 -RBC( 0, 1) = 1.380390474734288e-01, ZBS( 0, 1) = 1.310968006001034e-01 -RBC( 1, 1) = 2.903189084133577e-02, ZBS( 1, 1) = 3.270191607891355e-02 -RBC( 2, 1) = 6.875247108489111e-03, ZBS( 2, 1) = 6.803576261710397e-03 -RBC( 3, 1) = 8.150566273801188e-04, ZBS( 3, 1) = 8.594345731469456e-04 -RBC( 4, 1) = -2.843729541521199e-05, ZBS( 4, 1) = -1.177273734326507e-05 -RBC( 5, 1) = 1.828959533446362e-05, ZBS( 5, 1) = -1.615216261142120e-05 -RBC( -5, 2) = 2.187727631099286e-05, ZBS( -5, 2) = -7.400469361173993e-05 -RBC( -4, 2) = 8.393516055641350e-04, ZBS( -4, 2) = -4.483876523047104e-04 -RBC( -3, 2) = 1.971788481361341e-03, ZBS( -3, 2) = -3.174905588243931e-03 -RBC( -2, 2) = 5.269805664655518e-03, ZBS( -2, 2) = -7.113162328175970e-03 -RBC( -1, 2) = 2.116933661799145e-02, ZBS( -1, 2) = 1.865602467381490e-02 -RBC( 0, 2) = 1.536055908756419e-02, ZBS( 0, 2) = 9.451140140723166e-03 -RBC( 1, 2) = -1.177074525788361e-03, ZBS( 1, 2) = -4.394443738790604e-04 -RBC( 2, 2) = 1.300915708157302e-03, ZBS( 2, 2) = 1.022384351225018e-03 -RBC( 3, 2) = 2.747377558866586e-05, ZBS( 3, 2) = -6.300323824473890e-05 -RBC( 4, 2) = 9.334314906640049e-05, ZBS( 4, 2) = 6.552426964270398e-05 -RBC( 5, 2) = -5.617421098748800e-06, ZBS( 5, 2) = -1.848848555889170e-07 -RBC( -5, 3) = 2.874225777670480e-06, ZBS( -5, 3) = 7.868289246153724e-05 -RBC( -4, 3) = -1.903878083029936e-04, ZBS( -4, 3) = 3.682504964925082e-05 -RBC( -3, 3) = 2.220407427826208e-05, ZBS( -3, 3) = 6.281678187469348e-04 -RBC( -2, 3) = -1.082472074236150e-03, ZBS( -2, 3) = 6.445833193595944e-04 -RBC( -1, 3) = 6.435380216410359e-05, ZBS( -1, 3) = 1.141350665160774e-03 -RBC( 0, 3) = 1.069417168790915e-04, ZBS( 0, 3) = 3.802855234303916e-04 -RBC( 1, 3) = 4.983980241995697e-04, ZBS( 1, 3) = 6.843953564643375e-04 -RBC( 2, 3) = 3.325266953783200e-04, ZBS( 2, 3) = 2.395037991595740e-04 -RBC( 3, 3) = -8.380550535631315e-05, ZBS( 3, 3) = -2.858606506850391e-06 -RBC( 4, 3) = 8.168748496456451e-05, ZBS( 4, 3) = 3.828660987048127e-05 -RBC( 5, 3) = -1.172958658426462e-05, ZBS( 5, 3) = -2.567553564985603e-07 -RBC( -5, 4) = 1.930663967799810e-05, ZBS( -5, 4) = 5.848712999415494e-06 -RBC( -4, 4) = 5.914443815425555e-05, ZBS( -4, 4) = -9.777520270947895e-05 -RBC( -3, 4) = -1.535671893320628e-04, ZBS( -3, 4) = -1.968457634323347e-04 -RBC( -2, 4) = 9.254995677768834e-05, ZBS( -2, 4) = -1.254944494739196e-04 -RBC( -1, 4) = 2.217517688289458e-04, ZBS( -1, 4) = 7.133325449383868e-05 -RBC( 0, 4) = 4.623699812020439e-04, ZBS( 0, 4) = 3.336146039802283e-04 -RBC( 1, 4) = -4.834681321758439e-05, ZBS( 1, 4) = -1.984613542379469e-05 -RBC( 2, 4) = 1.449578757996227e-04, ZBS( 2, 4) = 3.445613069241063e-05 -RBC( 3, 4) = -5.390410338650556e-05, ZBS( 3, 4) = -6.043337987396479e-05 -RBC( 4, 4) = -2.755169485866935e-05, ZBS( 4, 4) = -3.234200905245086e-05 -RBC( 5, 4) = -1.031528435324214e-05, ZBS( 5, 4) = -8.346877197760745e-06 -RBC( -5, 5) = -8.230328283192286e-06, ZBS( -5, 5) = -4.962452471737940e-07 -RBC( -4, 5) = -4.283219579566894e-05, ZBS( -4, 5) = 2.554677526708830e-05 -RBC( -3, 5) = 7.171674894766820e-06, ZBS( -3, 5) = 4.411924318063437e-05 -RBC( -2, 5) = 1.686400668654943e-05, ZBS( -2, 5) = -5.849246530755695e-06 -RBC( -1, 5) = -3.106338530700742e-06, ZBS( -1, 5) = 1.479053323007641e-06 -RBC( 0, 5) = -3.106894329327918e-05, ZBS( 0, 5) = -4.555573189096034e-05 -RBC( 1, 5) = -2.117004285123679e-05, ZBS( 1, 5) = 4.954122546236333e-06 -RBC( 2, 5) = 1.404444565956858e-06, ZBS( 2, 5) = 2.921397801630777e-06 -RBC( 3, 5) = -1.491037166951584e-05, ZBS( 3, 5) = -1.337158933881559e-05 -RBC( 4, 5) = -1.062017757240239e-05, ZBS( 4, 5) = -1.038497225885287e-05 -RBC( 5, 5) = -3.055942324592806e-06, ZBS( 5, 5) = -2.630290187244904e-06 -/ From b5fc112ff2e7ab2283f9c406ea4c8fdd36f90408 Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Wed, 1 Nov 2023 21:18:03 -0400 Subject: [PATCH 12/21] ran autopep --- src/simsopt/geo/curveplanarfourier.py | 2 +- tests/geo/test_curve.py | 1 + tests/geo/test_equally_spaced_planar_coils.py | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/simsopt/geo/curveplanarfourier.py b/src/simsopt/geo/curveplanarfourier.py index 264e85a86..0f3bbd60c 100644 --- a/src/simsopt/geo/curveplanarfourier.py +++ b/src/simsopt/geo/curveplanarfourier.py @@ -23,7 +23,7 @@ class CurvePlanarFourier(sopp.CurvePlanarFourier, Curve): where :math:`\theta` is the counterclockwise rotation about a unit axis :math:`(\hat{x},\hat{y},\hat{z})`. - + A quaternion is used for rotation rather than other methods for rotation to prevent gimbal locking during optimization. The quaternion is normalized for calculations to prevent scaling. The dofs themselves are not normalized. This diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 275b6464b..59c480c48 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -509,5 +509,6 @@ def test_load_curves_from_makegrid_file(self): os.remove("coils.file_to_load") + if __name__ == "__main__": unittest.main() diff --git a/tests/geo/test_equally_spaced_planar_coils.py b/tests/geo/test_equally_spaced_planar_coils.py index 4470430fd..4dc4fa722 100644 --- a/tests/geo/test_equally_spaced_planar_coils.py +++ b/tests/geo/test_equally_spaced_planar_coils.py @@ -2,6 +2,7 @@ from simsopt.geo.curve import create_equally_spaced_curves, create_equally_spaced_planar_curves from simsopt.field import coils_via_symmetries, BiotSavart, Current + class Testing(unittest.TestCase): def test_equally_spaced_planar_coils(self): ncoils = 4 @@ -20,7 +21,8 @@ def test_equally_spaced_planar_coils(self): bs_planar = BiotSavart(coils_planar) err = bs.AbsB()[0][0] - bs_planar.AbsB()[0][0] print(err) - assert(err < 3e-10) + assert (err < 3e-10) + if __name__ == "__main__": unittest.main() \ No newline at end of file From ebf55f5c7d668e336309d804bfb0d3f70d888e91 Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Wed, 1 Nov 2023 21:57:24 -0400 Subject: [PATCH 13/21] Linting fixes --- .../2_Intermediate/stage_two_optimization_planar_coils.py | 4 ++-- src/simsopt/geo/curveplanarfourier.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/2_Intermediate/stage_two_optimization_planar_coils.py b/examples/2_Intermediate/stage_two_optimization_planar_coils.py index d32ca4da8..956525085 100755 --- a/examples/2_Intermediate/stage_two_optimization_planar_coils.py +++ b/examples/2_Intermediate/stage_two_optimization_planar_coils.py @@ -180,7 +180,7 @@ def fun(dofs): ################################################################################ """) res = minimize(fun, dofs, jac=True, method='L-BFGS-B', options={'maxiter': MAXITER, 'maxcor': 300}, tol=1e-15) -curves_to_vtk(curves, OUT_DIR + f"curves_opt_short") +curves_to_vtk(curves, OUT_DIR + "curves_opt_short") pointData = {"B_N": np.sum(bs.B().reshape((nphi, ntheta, 3)) * s.unitnormal(), axis=2)[:, :, None]} s.to_vtk(OUT_DIR + "surf_opt_short", extra_data=pointData) @@ -191,7 +191,7 @@ def fun(dofs): dofs = res.x LENGTH_WEIGHT *= 0.1 res = minimize(fun, dofs, jac=True, method='L-BFGS-B', options={'maxiter': MAXITER, 'maxcor': 300}, tol=1e-15) -curves_to_vtk(curves, OUT_DIR + f"curves_opt_long") +curves_to_vtk(curves, OUT_DIR + "curves_opt_long") pointData = {"B_N": np.sum(bs.B().reshape((nphi, ntheta, 3)) * s.unitnormal(), axis=2)[:, :, None]} s.to_vtk(OUT_DIR + "surf_opt_long", extra_data=pointData) diff --git a/src/simsopt/geo/curveplanarfourier.py b/src/simsopt/geo/curveplanarfourier.py index 0f3bbd60c..99b3ec8fe 100644 --- a/src/simsopt/geo/curveplanarfourier.py +++ b/src/simsopt/geo/curveplanarfourier.py @@ -1,7 +1,6 @@ import numpy as np import simsoptpp as sopp -from .._core.json import GSONDecoder from .curve import Curve __all__ = ['CurvePlanarFourier'] From d76c397c56da1de5526626d73efd0df0366e703b Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Wed, 1 Nov 2023 23:03:09 -0400 Subject: [PATCH 14/21] added round() to linkingnumber --- src/simsopt/geo/curveobjectives.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simsopt/geo/curveobjectives.py b/src/simsopt/geo/curveobjectives.py index baf41d598..bb81ec318 100644 --- a/src/simsopt/geo/curveobjectives.py +++ b/src/simsopt/geo/curveobjectives.py @@ -520,7 +520,7 @@ def J(self): integrals = sopp.linkNumber(R1, R2, dR1, dR2) * dS * dT linkNum[i-1][j-1] = 1/(4*np.pi) * (integrals) linkNumSum = sum(sum(abs(linkNum))) - return linkNumSum + return round(linkNumSum) @derivative_dec def dJ(self): From ec3581920dbd3a1dec8d5ad07b09c4a6b101364b Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Wed, 1 Nov 2023 23:04:09 -0400 Subject: [PATCH 15/21] removed penalty from linking number in example --- examples/2_Intermediate/stage_two_optimization_planar_coils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/2_Intermediate/stage_two_optimization_planar_coils.py b/examples/2_Intermediate/stage_two_optimization_planar_coils.py index 956525085..8c9d62b94 100755 --- a/examples/2_Intermediate/stage_two_optimization_planar_coils.py +++ b/examples/2_Intermediate/stage_two_optimization_planar_coils.py @@ -129,7 +129,7 @@ + CS_WEIGHT * Jcsdist \ + CURVATURE_WEIGHT * sum(Jcs) \ + MSC_WEIGHT * sum(QuadraticPenalty(J, MSC_THRESHOLD) for J in Jmscs) \ - + QuadraticPenalty(linkNum, 0.1) + + linkNum # We don't have a general interface in SIMSOPT for optimisation problems that # are not in least-squares form, so we write a little wrapper function that we From e740cbf8deef15839766c88888603f9f58669f69 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Tue, 14 Nov 2023 07:32:55 -0500 Subject: [PATCH 16/21] Testing create_equally_spaced_planar_curves at multiple points; moved test --- src/simsoptpp/curveplanarfourier.h | 11 +++--- tests/field/test_coil.py | 34 +++++++++++++++++-- tests/geo/test_equally_spaced_planar_coils.py | 28 --------------- 3 files changed, 39 insertions(+), 34 deletions(-) delete mode 100644 tests/geo/test_equally_spaced_planar_coils.py diff --git a/src/simsoptpp/curveplanarfourier.h b/src/simsoptpp/curveplanarfourier.h index f365ba88e..b3a686c0d 100644 --- a/src/simsoptpp/curveplanarfourier.h +++ b/src/simsoptpp/curveplanarfourier.h @@ -5,16 +5,19 @@ template class CurvePlanarFourier : public Curve { /* - CurvePlanarFourier is a curve that is represented using the following Fourier series: + CurvePlanarFourier is a curve that is restricted to lie in a plane. In + the plane, the curve is represented using a Fourier series in plane polar coordinates: r(phi) = \sum_{n=0}^{order} x_{c,n}cos(n*nfp*phi) + \sum_{n=1}^order x_{s,n}sin(n*nfp*phi) - with rotation about an axis and angle determined by a set of quarternions + The plane is rotated using a quarternion + q = [q_0, q_1, q_2, q_3] = [cos(\theta/2), x * sin(\theta/2), y * sin(\theta/2), z * sin(\theta/2)] - Quaternions are normalized to prevent scaling the curves, but remain unnormalized as dofs to prevent optimization error. + The dofs for the quaternion need not generally have unit norm. The + quaternion is normalized before being applied to the curve to prevent scaling the curve. - A center vector is used to specify the location of the center of the curve: + A translation vector is used to specify the location of the center of the curve: c = [c_x, c_y, c_z] diff --git a/tests/field/test_coil.py b/tests/field/test_coil.py index 0b1125b34..47dee47fa 100644 --- a/tests/field/test_coil.py +++ b/tests/field/test_coil.py @@ -7,8 +7,8 @@ from simsopt.geo.curvexyzfourier import CurveXYZFourier, JaxCurveXYZFourier from simsopt.geo.curverzfourier import CurveRZFourier from simsopt.geo.curvehelical import CurveHelical -from simsopt.geo.curve import RotatedCurve -from simsopt.field.coil import Coil, Current, ScaledCurrent, CurrentSum +from simsopt.geo.curve import RotatedCurve, create_equally_spaced_curves, create_equally_spaced_planar_curves +from simsopt.field.coil import Coil, Current, ScaledCurrent, CurrentSum, coils_via_symmetries from simsopt.field.coil import coils_to_makegrid, coils_to_focus, load_coils_from_makegrid_file from simsopt.field.biotsavart import BiotSavart from simsopt._core.json import GSONEncoder, GSONDecoder, SIMSON @@ -187,6 +187,36 @@ def test_load_coils_from_makegrid_file(self): np.testing.assert_allclose(B, loaded_B) np.testing.assert_allclose(gamma, loaded_gamma) + def test_equally_spaced_planar_curves(self): + ncoils = 4 + nfp = 4 + stellsym = False + R0 = 2.3 + R1 = 0.9 + + curves = create_equally_spaced_curves(ncoils, nfp, stellsym, R0=R0, R1=R1) + currents = [Current(1e5) for i in range(ncoils)] + + curves_planar = create_equally_spaced_planar_curves(ncoils, nfp, stellsym, R0=R0, R1=R1) + currents_planar = [Current(1e5) for i in range(ncoils)] + + coils = coils_via_symmetries(curves, currents, nfp, stellsym) + coils_planar = coils_via_symmetries(curves_planar, currents_planar, nfp, stellsym) + bs = BiotSavart(coils) + bs_planar = BiotSavart(coils_planar) + + x1d = np.linspace(R0, R0 + 0.3, 4) + y1d = np.linspace(0, 0.2, 3) + z1d = np.linspace(-0.2, 0.4, 5) + x, y, z = np.meshgrid(x1d, y1d, z1d) + points = np.ascontiguousarray(np.array([x.ravel(), y.ravel(), z.ravel()]).T) + + bs.set_points(points) + bs_planar.set_points(points) + + np.testing.assert_allclose(bs.B(), bs_planar.B(), atol=1e-16) + + if __name__ == "__main__": unittest.main() diff --git a/tests/geo/test_equally_spaced_planar_coils.py b/tests/geo/test_equally_spaced_planar_coils.py deleted file mode 100644 index 4dc4fa722..000000000 --- a/tests/geo/test_equally_spaced_planar_coils.py +++ /dev/null @@ -1,28 +0,0 @@ -import unittest -from simsopt.geo.curve import create_equally_spaced_curves, create_equally_spaced_planar_curves -from simsopt.field import coils_via_symmetries, BiotSavart, Current - - -class Testing(unittest.TestCase): - def test_equally_spaced_planar_coils(self): - ncoils = 4 - nfp = 4 - stellsym = False - - curves = create_equally_spaced_curves(ncoils, nfp, False) - currents = [Current(1e5) for i in range(ncoils)] - - curves_planar = create_equally_spaced_planar_curves(ncoils, nfp, False) - currents_planar = [Current(1e5) for i in range(ncoils)] - - coils = coils_via_symmetries(curves, currents, nfp, stellsym) - coils_planar = coils_via_symmetries(curves_planar, currents_planar, nfp, stellsym) - bs = BiotSavart(coils) - bs_planar = BiotSavart(coils_planar) - err = bs.AbsB()[0][0] - bs_planar.AbsB()[0][0] - print(err) - assert (err < 3e-10) - - -if __name__ == "__main__": - unittest.main() \ No newline at end of file From aab93ed0acdaf42d435abb249c1d7658df2dbc2e Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Tue, 14 Nov 2023 08:03:01 -0500 Subject: [PATCH 17/21] CurvePlanarFourier: Reduce number of trig evaluations --- src/simsoptpp/curveplanarfourier.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/simsoptpp/curveplanarfourier.cpp b/src/simsoptpp/curveplanarfourier.cpp index a3db9e2bf..6001edff5 100644 --- a/src/simsoptpp/curveplanarfourier.cpp +++ b/src/simsoptpp/curveplanarfourier.cpp @@ -4,10 +4,8 @@ template double CurvePlanarFourier::inv_magnitude() { double s = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; if(s != 0) { - double sqrt_inv_s = 1 / std::sqrt(s); - return sqrt_inv_s; - } - else { + return 1 / std::sqrt(s); + } else { return 1; } @@ -15,6 +13,7 @@ double CurvePlanarFourier::inv_magnitude() { template void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { + double sinphi, cosphi, siniphi, cosiphi; int numquadpoints = quadpoints.size(); data *= 0; @@ -23,13 +22,15 @@ void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; - for (int i = 0; i < order+1; ++i) { - data(k, 0) += rc[i] * cos(i*phi) * cos(phi); - data(k, 1) += rc[i] * cos(i*phi) * sin(phi); - } + sinphi = sin(phi); + cosphi = cos(phi); + data(k, 0) = rc[0] * cosphi; + data(k, 1) = rc[0] * sinphi; for (int i = 1; i < order+1; ++i) { - data(k, 0) += rs[i-1] * sin(i*phi) * cos(phi); - data(k, 1) += rs[i-1] * sin(i*phi) * sin(phi); + siniphi = sin(i * phi); + cosiphi = cos(i * phi); + data(k, 0) += (rc[i] * cosiphi + rs[i-1] * siniphi) * cosphi; + data(k, 1) += (rc[i] * cosiphi + rs[i-1] * siniphi) * sinphi; } } for (int m = 0; m < numquadpoints; ++m) { From bb88259e2f19adb3a968c94129f5821a06d97d84 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Tue, 14 Nov 2023 09:05:40 -0500 Subject: [PATCH 18/21] CurvePlanarFourier tidying up --- src/simsopt/geo/curveplanarfourier.py | 25 ++++++++++----- src/simsoptpp/curveplanarfourier.cpp | 46 +++++++++------------------ src/simsoptpp/curveplanarfourier.h | 13 ++++---- 3 files changed, 39 insertions(+), 45 deletions(-) diff --git a/src/simsopt/geo/curveplanarfourier.py b/src/simsopt/geo/curveplanarfourier.py index 99b3ec8fe..4880d05d6 100644 --- a/src/simsopt/geo/curveplanarfourier.py +++ b/src/simsopt/geo/curveplanarfourier.py @@ -8,24 +8,33 @@ class CurvePlanarFourier(sopp.CurvePlanarFourier, Curve): r""" - ``CurvePlanarFourier`` is a curve that is represented by a polar coordinate - Fourier serires, a rotation quaternion, and a center point following the - form: + ``CurvePlanarFourier`` is a curve that is restricted to lie in a plane. The + shape of the curve within the plane is represented by a Fourier series in + polar coordinates. The resulting planar curve is then rotated in three + dimensions using a quaternion, and finally a translation is applied. The + Fourier series in polar coordinates is .. math:: - r(\phi) &= \sum_{m=0}^{\text{order}} r_{c,m}\cos(m \phi) + \sum_{m=1}^{\text{order}} r_{s,m}\sin(m \phi) + r(\phi) = \sum_{m=0}^{\text{order}} r_{c,m}\cos(m \phi) + \sum_{m=1}^{\text{order}} r_{s,m}\sin(m \phi). + + The rotation quaternion is + + .. math:: \bf{q} &= [q_0,q_i,q_j,q_k] &= [\cos(\theta / 2), \hat{x}\sin(\theta / 2), \hat{y}\sin(\theta / 2), \hat{z}\sin(\theta / 2)] - where :math:`\theta` is the counterclockwise rotation about a unit axis - :math:`(\hat{x},\hat{y},\hat{z})`. + where :math:`\theta` is the counterclockwise rotation angle about a unit axis + :math:`(\hat{x},\hat{y},\hat{z})`. Details of the quaternion rotation can be + found for example in pages 575-576 of + https://www.cis.upenn.edu/~cis5150/ws-book-Ib.pdf. + A quaternion is used for rotation rather than other methods for rotation to - prevent gimbal locking during optimization. The quaternion is normalized for - calculations to prevent scaling. The dofs themselves are not normalized. This + prevent gimbal locking during optimization. The quaternion is normalized + before being applied to prevent scaling of the curve. The dofs themselves are not normalized. This results in a redundancy in the optimization, where several different sets of dofs may correspond to the same normalized quaternion. Normalizing the dofs directly would create a dependence between the quaternion dofs, which may cause diff --git a/src/simsoptpp/curveplanarfourier.cpp b/src/simsoptpp/curveplanarfourier.cpp index 6001edff5..2d5a3cc55 100644 --- a/src/simsoptpp/curveplanarfourier.cpp +++ b/src/simsoptpp/curveplanarfourier.cpp @@ -34,12 +34,9 @@ void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { } } for (int m = 0; m < numquadpoints; ++m) { - double i; - double j; - double k; - i = data(m, 0); - j = data(m, 1); - k = data(m, 2); + double i = data(m, 0); + double j = data(m, 1); + double k = data(m, 2); /* Performs quaternion based rotation, see https://www.cis.upenn.edu/~cis5150/ws-book-Ib.pdf page 575, 576 for details regarding this rotation*/ data(m, 0) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k) + center[0]; @@ -69,13 +66,9 @@ void CurvePlanarFourier::gammadash_impl(Array& data) { data *= (2*M_PI); for (int m = 0; m < numquadpoints; ++m) { - double i; - double j; - double k; - i = data(m, 0); - j = data(m, 1); - k = data(m, 2); - + double i = data(m, 0); + double j = data(m, 1); + double k = data(m, 2); /* Performs quaternion based rotation, see https://www.cis.upenn.edu/~cis5150/ws-book-Ib.pdf page 575, 576 for details regarding this rotation*/ data(m, 0) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); @@ -104,13 +97,9 @@ void CurvePlanarFourier::gammadashdash_impl(Array& data) { } data *= 2*M_PI*2*M_PI; for (int m = 0; m < numquadpoints; ++m) { - double i; - double j; - double k; - i = data(m, 0); - j = data(m, 1); - k = data(m, 2); - + double i = data(m, 0); + double j = data(m, 1); + double k = data(m, 2); /* Performs quaternion based rotation*/ data(m, 0) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); @@ -151,13 +140,9 @@ void CurvePlanarFourier::gammadashdashdash_impl(Array& data) { } data *= 2*M_PI*2*M_PI*2*M_PI; for (int m = 0; m < numquadpoints; ++m) { - double i; - double j; - double k; - i = data(m, 0); - j = data(m, 1); - k = data(m, 2); - + double i = data(m, 0); + double j = data(m, 1); + double k = data(m, 2); /* Performs quaternion based rotation*/ data(m, 0) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); @@ -495,12 +480,11 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { counter++; + data(m, 0, counter) = 0; + data(m, 1, counter) = 0; + data(m, 2, counter) = 0; for (int i = 0; i < 3; ++i) { - data(m, 0, counter) = 0; - data(m, 1, counter) = 0; - data(m, 2, counter) = 0; data(m, i, counter) = 1; - counter++; } } diff --git a/src/simsoptpp/curveplanarfourier.h b/src/simsoptpp/curveplanarfourier.h index b3a686c0d..7575ff673 100644 --- a/src/simsoptpp/curveplanarfourier.h +++ b/src/simsoptpp/curveplanarfourier.h @@ -11,10 +11,13 @@ class CurvePlanarFourier : public Curve { r(phi) = \sum_{n=0}^{order} x_{c,n}cos(n*nfp*phi) + \sum_{n=1}^order x_{s,n}sin(n*nfp*phi) The plane is rotated using a quarternion - + q = [q_0, q_1, q_2, q_3] = [cos(\theta/2), x * sin(\theta/2), y * sin(\theta/2), z * sin(\theta/2)] - The dofs for the quaternion need not generally have unit norm. The + Details of the quaternion rotation can be found for example in pages + 575-576 of https://www.cis.upenn.edu/~cis5150/ws-book-Ib.pdf. + + The simsopt dofs for the quaternion need not generally have unit norm. The quaternion is normalized before being applied to the curve to prevent scaling the curve. A translation vector is used to specify the location of the center of the curve: @@ -103,9 +106,6 @@ class CurvePlanarFourier : public Curve { return check_the_persistent_cache("dgammadashdashdash_by_dcoeff", {numquadpoints, 3, num_dofs()}, [this](Array& A) { return dgammadashdashdash_by_dcoeff_impl(A);}); } - - double inv_magnitude(); - void gamma_impl(Array& data, Array& quadpoints) override; void gammadash_impl(Array& data) override; void gammadashdash_impl(Array& data) override; @@ -115,6 +115,7 @@ class CurvePlanarFourier : public Curve { void dgammadashdash_by_dcoeff_impl(Array& data) override; void dgammadashdashdash_by_dcoeff_impl(Array& data) override; - +private: + double inv_magnitude(); }; From 1c439a42d64c648023b105c998b562b39daa073e Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Tue, 14 Nov 2023 09:17:15 -0500 Subject: [PATCH 19/21] Undo bug I introduced in the previous commit --- src/simsoptpp/curveplanarfourier.cpp | 6 +++--- src/simsoptpp/curveplanarfourier.h | 6 +++--- src/simsoptpp/python_curves.cpp | 1 - 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/simsoptpp/curveplanarfourier.cpp b/src/simsoptpp/curveplanarfourier.cpp index 2d5a3cc55..9c282b3e0 100644 --- a/src/simsoptpp/curveplanarfourier.cpp +++ b/src/simsoptpp/curveplanarfourier.cpp @@ -480,10 +480,10 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { counter++; - data(m, 0, counter) = 0; - data(m, 1, counter) = 0; - data(m, 2, counter) = 0; for (int i = 0; i < 3; ++i) { + data(m, 0, counter) = 0; + data(m, 1, counter) = 0; + data(m, 2, counter) = 0; data(m, i, counter) = 1; counter++; } diff --git a/src/simsoptpp/curveplanarfourier.h b/src/simsoptpp/curveplanarfourier.h index 7575ff673..901bde313 100644 --- a/src/simsoptpp/curveplanarfourier.h +++ b/src/simsoptpp/curveplanarfourier.h @@ -5,8 +5,8 @@ template class CurvePlanarFourier : public Curve { /* - CurvePlanarFourier is a curve that is restricted to lie in a plane. In - the plane, the curve is represented using a Fourier series in plane polar coordinates: + CurvePlanarFourier is a curve that is restricted to lie in a plane. In + the plane, the curve is represented using a Fourier series in plane polar coordinates: r(phi) = \sum_{n=0}^{order} x_{c,n}cos(n*nfp*phi) + \sum_{n=1}^order x_{s,n}sin(n*nfp*phi) @@ -24,7 +24,7 @@ class CurvePlanarFourier : public Curve { c = [c_x, c_y, c_z] - The dofs are stored in the order + The dofs are stored in the order [r_{c,0},...,r_{c,order},r_{s,1},...,r_{s,order}, q_0, q_1, q_2, q_3, c_x, c_y, c_z] diff --git a/src/simsoptpp/python_curves.cpp b/src/simsoptpp/python_curves.cpp index ada7a2225..90760ee4b 100644 --- a/src/simsoptpp/python_curves.cpp +++ b/src/simsoptpp/python_curves.cpp @@ -135,7 +135,6 @@ void init_curves(py::module_ &m) { register_common_curve_methods(pycurverzfourier); auto pycurveplanarfourier = py::class_, PyCurvePlanarFourierTrampoline, PyCurve>(m, "CurvePlanarFourier") - //.def(py::init()) .def(py::init, int, int, bool>()) .def_readwrite("rc", &PyCurvePlanarFourier::rc) .def_readwrite("rs", &PyCurvePlanarFourier::rs) From 6678a9c6452ae4f83b73c01f26dec40960a846e5 Mon Sep 17 00:00:00 2001 From: Alex Wiedman Date: Fri, 24 Nov 2023 13:21:43 -0500 Subject: [PATCH 20/21] removed extraneous transcendental functions --- src/simsoptpp/curveplanarfourier.cpp | 192 ++++++++++++++++++--------- 1 file changed, 132 insertions(+), 60 deletions(-) diff --git a/src/simsoptpp/curveplanarfourier.cpp b/src/simsoptpp/curveplanarfourier.cpp index a3db9e2bf..e5e7fcdc3 100644 --- a/src/simsoptpp/curveplanarfourier.cpp +++ b/src/simsoptpp/curveplanarfourier.cpp @@ -23,13 +23,19 @@ void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; + double cosphi = cos(phi); + double sinphi = sin(phi); + double cosiphi = 0; + double siniphi = 0; for (int i = 0; i < order+1; ++i) { - data(k, 0) += rc[i] * cos(i*phi) * cos(phi); - data(k, 1) += rc[i] * cos(i*phi) * sin(phi); + cosiphi = cos(i*phi); + data(k, 0) += rc[i] * cosiphi * cosphi; + data(k, 1) += rc[i] * cosiphi * sinphi; } for (int i = 1; i < order+1; ++i) { - data(k, 0) += rs[i-1] * sin(i*phi) * cos(phi); - data(k, 1) += rs[i-1] * sin(i*phi) * sin(phi); + siniphi = sin(i*phi); + data(k, 0) += rs[i-1] * siniphi * cosphi; + data(k, 1) += rs[i-1] * siniphi * sinphi; } } for (int m = 0; m < numquadpoints; ++m) { @@ -56,13 +62,21 @@ void CurvePlanarFourier::gammadash_impl(Array& data) { for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; + double cosphi = cos(phi); + double sinphi = sin(phi); + double cosiphi = 0; + double siniphi = 0; for (int i = 0; i < order+1; ++i) { - data(k, 0) += rc[i] * ( -(i) * sin(i*phi) * cos(phi) - cos(i*phi) * sin(phi)); - data(k, 1) += rc[i] * ( -(i) * sin(i*phi) * sin(phi) + cos(i*phi) * cos(phi)); + cosiphi = cos(i*phi); + siniphi = sin(i*phi); + data(k, 0) += rc[i] * ( -(i) * siniphi * cosphi - cosiphi * sinphi); + data(k, 1) += rc[i] * ( -(i) * siniphi * sinphi + cosiphi * cosphi); } for (int i = 1; i < order+1; ++i) { - data(k, 0) += rs[i-1] * ( (i) * cos(i*phi) * cos(phi) - sin(i*phi) * sin(phi)); - data(k, 1) += rs[i-1] * ( (i) * cos(i*phi) * sin(phi) + sin(i*phi) * cos(phi)); + cosiphi = cos(i*phi); + siniphi = sin(i*phi); + data(k, 0) += rs[i-1] * ( (i) * cosiphi * cosphi - siniphi * sinphi); + data(k, 1) += rs[i-1] * ( (i) * cosiphi * sinphi + siniphi * cosphi); } } @@ -92,13 +106,21 @@ void CurvePlanarFourier::gammadashdash_impl(Array& data) { for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; + double cosphi = cos(phi); + double sinphi = sin(phi); + double cosiphi = 0; + double siniphi = 0; for (int i = 0; i < order+1; ++i) { - data(k, 0) += rc[i] * (+2*(i)*sin(i*phi)*sin(phi)-(i*i+1)*cos(i*phi)*cos(phi)); - data(k, 1) += rc[i] * (-2*(i)*sin(i*phi)*cos(phi)-(i*i+1)*cos(i*phi)*sin(phi)); + cosiphi = cos(i*phi); + siniphi = sin(i*phi); + data(k, 0) += rc[i] * (+2*(i)*siniphi*sinphi-(i*i+1)*cosiphi*cosphi); + data(k, 1) += rc[i] * (-2*(i)*siniphi*cosphi-(i*i+1)*cosiphi*sinphi); } for (int i = 1; i < order+1; ++i) { - data(k, 0) += rs[i-1] * (-(i*i+1)*sin(i*phi)*cos(phi) - 2*(i)*cos(i*phi)*sin(phi)); - data(k, 1) += rs[i-1] * (-(i*i+1)*sin(i*phi)*sin(phi) + 2*(i)*cos(i*phi)*cos(phi)); + cosiphi = cos(i*phi); + siniphi = sin(i*phi); + data(k, 0) += rs[i-1] * (-(i*i+1)*siniphi*cosphi - 2*(i)*cosiphi*sinphi); + data(k, 1) += rs[i-1] * (-(i*i+1)*siniphi*sinphi + 2*(i)*cosiphi*cosphi); } } data *= 2*M_PI*2*M_PI; @@ -127,24 +149,33 @@ void CurvePlanarFourier::gammadashdashdash_impl(Array& data) { for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; + double cosphi = cos(phi); + double sinphi = sin(phi); + double cosiphi = 0; + double siniphi = 0; + for (int i = 0; i < order+1; ++i) { + cosiphi = cos(i*phi); + siniphi = sin(i*phi); data(k, 0) += rc[i]*( - +(3*i*i + 1)*cos(i*phi)*sin(phi) - +(i*i + 3)*(i)*sin(i*phi)*cos(phi) + +(3*i*i + 1)*cosiphi*sinphi + +(i*i + 3)*(i)*siniphi*cosphi ); data(k, 1) += rc[i]*( - +(i*i + 3)*(i)*sin(i*phi)*sin(phi) - -(3*i*i + 1)*cos(i*phi)*cos(phi) + +(i*i + 3)*(i)*siniphi*sinphi + -(3*i*i + 1)*cosiphi*cosphi ); } for (int i = 1; i < order+1; ++i) { + cosiphi = cos(i*phi); + siniphi = sin(i*phi); data(k, 0) += rs[i-1]*( - -(i*i+3) * (i) * cos(i*phi)*cos(phi) - +(3*i*i+1) * sin(i*phi)*sin(phi) + -(i*i+3) * (i) * cosiphi*cosphi + +(3*i*i+1) * siniphi*sinphi ); data(k, 1) += rs[i-1]*( - -(i*i+3)*(i)*cos(i*phi)*sin(phi) - -(3*i*i+1)*sin(i*phi)*cos(phi) + -(i*i+3)*(i)*cosiphi*sinphi + -(3*i*i+1)*siniphi*cosphi ); } } @@ -179,9 +210,14 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { double j; double k; + double cosphi = cos(phi); + double sinphi = sin(phi); + double cosnphi = 0; + double sinnphi = 0; + for (int n = 0; n < order+1; ++n) { - i = cos(n*phi) * cos(phi); - j = cos(n*phi) * sin(phi); + i = cos(n*phi) * cosphi; + j = cos(n*phi) * sinphi; k = 0; data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); @@ -192,8 +228,8 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { } for (int n = 1; n < order+1; ++n) { - i = sin(n*phi) * cos(phi); - j = sin(n*phi) * sin(phi); + i = sin(n*phi) * cosphi; + j = sin(n*phi) * sinphi; k = 0; data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); @@ -208,12 +244,12 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { k = 0; for (int n = 0; n < order+1; ++n) { - i += rc[n] * cos(n*phi) * cos(phi); - j += rc[n] * cos(n*phi) * sin(phi); + i += rc[n] * cos(n*phi) * cosphi; + j += rc[n] * cos(n*phi) * sinphi; } for (int n = 1; n < order+1; ++n) { - i += rs[n-1] * sin(n*phi) * cos(phi); - j += rs[n-1] * sin(n*phi) * sin(phi); + i += rs[n-1] * sin(n*phi) * cosphi; + j += rs[n-1] * sin(n*phi) * sinphi; } double inv_sqrt_s = inv_magnitude(); @@ -513,13 +549,19 @@ void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; + double cosphi = cos(phi); + double sinphi = sin(phi); + double cosnphi = 0; + double sinnphi = 0; int counter = 0; double i; double j; double k; for (int n = 0; n < order+1; ++n) { - i = ( -(n) * sin(n*phi) * cos(phi) - cos(n*phi) * sin(phi)); - j = ( -(n) * sin(n*phi) * sin(phi) + cos(n*phi) * cos(phi)); + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); + i = ( -(n) * sinnphi * cosphi - cosnphi * sinphi); + j = ( -(n) * sinnphi * sinphi + cosnphi * cosphi); k = 0; i *= (2*M_PI); @@ -534,8 +576,10 @@ void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { } for (int n = 1; n < order+1; ++n) { - i = ( (n) * cos(n*phi) * cos(phi) - sin(n*phi) * sin(phi)); - j = ( (n) * cos(n*phi) * sin(phi) + sin(n*phi) * cos(phi)); + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); + i = ( (n) * cosnphi * cosphi - sinnphi * sinphi); + j = ( (n) * cosnphi * sinphi + sinnphi * cosphi); k = 0; i *= (2*M_PI); @@ -553,12 +597,16 @@ void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { j = 0; k = 0; for (int n = 0; n < order+1; ++n) { - i += rc[n] * ( -(n) * sin(n*phi) * cos(phi) - cos(n*phi) * sin(phi)) * 2 * M_PI; - j += rc[n] * ( -(n) * sin(n*phi) * sin(phi) + cos(n*phi) * cos(phi)) * 2 * M_PI; + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); + i += rc[n] * ( -(n) * sinnphi * cosphi - cosnphi * sinphi) * 2 * M_PI; + j += rc[n] * ( -(n) * sinnphi * sinphi + cosnphi * cosphi) * 2 * M_PI; } for (int n = 1; n < order+1; ++n) { - i += rs[n-1] * ( (n) * cos(n*phi) * cos(phi) - sin(n*phi) * sin(phi)) * 2 * M_PI; - j += rs[n-1] * ( (n) * cos(n*phi) * sin(phi) + sin(n*phi) * cos(phi)) * 2 * M_PI; + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); + i += rs[n-1] * ( (n) * cosnphi * cosphi - sinnphi * sinphi) * 2 * M_PI; + j += rs[n-1] * ( (n) * cosnphi * sinphi + sinnphi * cosphi) * 2 * M_PI; } double inv_sqrt_s = inv_magnitude(); @@ -857,13 +905,19 @@ void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; + double cosphi = cos(phi); + double sinphi = sin(phi); + double cosnphi = 0; + double sinnphi = 0; int counter = 0; double i; double j; double k; for (int n = 0; n < order+1; ++n) { - i = (+2*(n)*sin(n*phi)*sin(phi)-(n*n+1)*cos(n*phi)*cos(phi)); - j = (-2*(n)*sin(n*phi)*cos(phi)-(n*n+1)*cos(n*phi)*sin(phi)); + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); + i = (+2*(n)*sinnphi*sinphi-(n*n+1)*cosnphi*cosphi); + j = (-2*(n)*sinnphi*cosphi-(n*n+1)*cosnphi*sinphi); k = 0; i *= 2*M_PI*2*M_PI; @@ -878,8 +932,10 @@ void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { } for (int n = 1; n < order+1; ++n) { - i = (-(n*n+1)*sin(n*phi)*cos(phi) - 2*(n)*cos(n*phi)*sin(phi)); - j = (-(n*n+1)*sin(n*phi)*sin(phi) + 2*(n)*cos(n*phi)*cos(phi)); + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); + i = (-(n*n+1)*sinnphi*cosphi - 2*(n)*cosnphi*sinphi); + j = (-(n*n+1)*sinnphi*sinphi + 2*(n)*cosnphi*cosphi); k = 0; i *= 2*M_PI*2*M_PI; @@ -897,12 +953,16 @@ void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { j = 0; k = 0; for (int n = 0; n < order+1; ++n) { - i += rc[n] * (+2*(n)*sin(n*phi)*sin(phi)-(n*n+1)*cos(n*phi)*cos(phi)); - j += rc[n] * (-2*(n)*sin(n*phi)*cos(phi)-(n*n+1)*cos(n*phi)*sin(phi)); + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); + i += rc[n] * (+2*(n)*sinnphi*sinphi-(n*n+1)*cosnphi*cosphi); + j += rc[n] * (-2*(n)*sinnphi*cosphi-(n*n+1)*cosnphi*sinphi); } for (int n = 1; n < order+1; ++n) { - i += rs[n-1] * (-(n*n+1)*sin(n*phi)*cos(phi) - 2*(n)*cos(n*phi)*sin(phi)); - j += rs[n-1] * (-(n*n+1)*sin(n*phi)*sin(phi) + 2*(n)*cos(n*phi)*cos(phi)); + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); + i += rs[n-1] * (-(n*n+1)*sinnphi*cosphi - 2*(n)*cosnphi*sinphi); + j += rs[n-1] * (-(n*n+1)*sinnphi*sinphi + 2*(n)*cosnphi*cosphi); } i *= 2*M_PI*2*M_PI; j *= 2*M_PI*2*M_PI; @@ -1203,18 +1263,24 @@ void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; + double cosphi = cos(phi); + double sinphi = sin(phi); + double cosnphi = 0; + double sinnphi = 0; int counter = 0; double i; double j; double k; for (int n = 0; n < order+1; ++n) { + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); i = ( - +(3*n*n + 1)*cos(n*phi)*sin(phi) - +(n*n + 3)*(n)*sin(n*phi)*cos(phi) + +(3*n*n + 1)*cosnphi*sinphi + +(n*n + 3)*(n)*sinnphi*cosphi ); j = ( - +(n*n + 3)*(n)*sin(n*phi)*sin(phi) - -(3*n*n + 1)*cos(n*phi)*cos(phi) + +(n*n + 3)*(n)*sinnphi*sinphi + -(3*n*n + 1)*cosnphi*cosphi ); k = 0; @@ -1230,13 +1296,15 @@ void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { } for (int n = 1; n < order+1; ++n) { + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); i = ( - -(n*n+3) * (n) * cos(n*phi)*cos(phi) - +(3*n*n+1) * sin(n*phi)*sin(phi) + -(n*n+3) * (n) * cosnphi*cosphi + +(3*n*n+1) * sinnphi*sinphi ); j = ( - -(n*n+3)*(n)*cos(n*phi)*sin(phi) - -(3*n*n+1)*sin(n*phi)*cos(phi) + -(n*n+3)*(n)*cosnphi*sinphi + -(3*n*n+1)*sinnphi*cosphi ); k = 0; @@ -1255,23 +1323,27 @@ void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { j = 0; k = 0; for (int n = 0; n < order+1; ++n) { + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); i += rc[n]*( - +(3*n*n + 1)*cos(n*phi)*sin(phi) - +(n*n + 3)*(n)*sin(n*phi)*cos(phi) + +(3*n*n + 1)*cosnphi*sinphi + +(n*n + 3)*(n)*sinnphi*cosphi ); j += rc[n]*( - +(n*n + 3)*(n)*sin(n*phi)*sin(phi) - -(3*n*n + 1)*cos(n*phi)*cos(phi) + +(n*n + 3)*(n)*sinnphi*sinphi + -(3*n*n + 1)*cosnphi*cosphi ); } for (int n = 1; n < order+1; ++n) { + cosnphi = cos(n*phi); + sinnphi = sin(n*phi); i += rs[n-1]*( - -(n*n+3) * (n) * cos(n*phi)*cos(phi) - +(3*n*n+1) * sin(n*phi)*sin(phi) + -(n*n+3) * (n) * cosnphi*cosphi + +(3*n*n+1) * sinnphi*sinphi ); j += rs[n-1]*( - -(n*n+3)*(n)*cos(n*phi)*sin(phi) - -(3*n*n+1)*sin(n*phi)*cos(phi) + -(n*n+3)*(n)*cosnphi*sinphi + -(3*n*n+1)*sinnphi*cosphi ); } i *= 2*M_PI*2*M_PI*2*M_PI; From 60cb677420b9b2ac2456e0eb11522921f31ce6ff Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Mon, 27 Nov 2023 10:05:25 -0500 Subject: [PATCH 21/21] curveplanarfourier.cpp: Reduced number of calls to trig functions --- src/simsoptpp/curveplanarfourier.cpp | 157 +++++++++++---------------- 1 file changed, 64 insertions(+), 93 deletions(-) diff --git a/src/simsoptpp/curveplanarfourier.cpp b/src/simsoptpp/curveplanarfourier.cpp index fc778247b..9e11bc3e8 100644 --- a/src/simsoptpp/curveplanarfourier.cpp +++ b/src/simsoptpp/curveplanarfourier.cpp @@ -24,17 +24,13 @@ void CurvePlanarFourier::gamma_impl(Array& data, Array& quadpoints) { double phi = 2 * M_PI * quadpoints[k]; double cosphi = cos(phi); double sinphi = sin(phi); - double cosiphi = 0; - double siniphi = 0; - for (int i = 0; i < order+1; ++i) { - cosiphi = cos(i*phi); - data(k, 0) += rc[i] * cosiphi * cosphi; - data(k, 1) += rc[i] * cosiphi * sinphi; - } + data(k, 0) = rc[0] * cosphi; + data(k, 1) = rc[0] * sinphi; for (int i = 1; i < order+1; ++i) { + cosiphi = cos(i*phi); siniphi = sin(i*phi); - data(k, 0) += rs[i-1] * siniphi * cosphi; - data(k, 1) += rs[i-1] * siniphi * sinphi; + data(k, 0) += (rc[i] * cosiphi + rs[i-1] * siniphi) * cosphi; + data(k, 1) += (rc[i] * cosiphi + rs[i-1] * siniphi) * sinphi; } } for (int m = 0; m < numquadpoints; ++m) { @@ -56,23 +52,20 @@ void CurvePlanarFourier::gammadash_impl(Array& data) { double inv_sqrt_s = inv_magnitude(); Array q_norm = q * inv_sqrt_s; + double cosiphi, siniphi; for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; double cosphi = cos(phi); double sinphi = sin(phi); - double cosiphi = 0; - double siniphi = 0; - for (int i = 0; i < order+1; ++i) { - cosiphi = cos(i*phi); - siniphi = sin(i*phi); - data(k, 0) += rc[i] * ( -(i) * siniphi * cosphi - cosiphi * sinphi); - data(k, 1) += rc[i] * ( -(i) * siniphi * sinphi + cosiphi * cosphi); - } + data(k, 0) = rc[0] * (-sinphi); + data(k, 1) = rc[0] * (cosphi); for (int i = 1; i < order+1; ++i) { cosiphi = cos(i*phi); siniphi = sin(i*phi); - data(k, 0) += rs[i-1] * ( (i) * cosiphi * cosphi - siniphi * sinphi); - data(k, 1) += rs[i-1] * ( (i) * cosiphi * sinphi + siniphi * cosphi); + data(k, 0) += rc[i] * ( -(i) * siniphi * cosphi - cosiphi * sinphi) + + rs[i-1] * ( (i) * cosiphi * cosphi - siniphi * sinphi); + data(k, 1) += rc[i] * ( -(i) * siniphi * sinphi + cosiphi * cosphi) + + rs[i-1] * ( (i) * cosiphi * sinphi + siniphi * cosphi); } } @@ -96,23 +89,20 @@ void CurvePlanarFourier::gammadashdash_impl(Array& data) { Array q_norm = q * inv_magnitude(); + double cosiphi, siniphi; for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; double cosphi = cos(phi); double sinphi = sin(phi); - double cosiphi = 0; - double siniphi = 0; - for (int i = 0; i < order+1; ++i) { - cosiphi = cos(i*phi); - siniphi = sin(i*phi); - data(k, 0) += rc[i] * (+2*(i)*siniphi*sinphi-(i*i+1)*cosiphi*cosphi); - data(k, 1) += rc[i] * (-2*(i)*siniphi*cosphi-(i*i+1)*cosiphi*sinphi); - } + data(k, 0) = rc[0] * (-cosphi); + data(k, 1) = rc[0] * (-sinphi); for (int i = 1; i < order+1; ++i) { cosiphi = cos(i*phi); siniphi = sin(i*phi); - data(k, 0) += rs[i-1] * (-(i*i+1)*siniphi*cosphi - 2*(i)*cosiphi*sinphi); - data(k, 1) += rs[i-1] * (-(i*i+1)*siniphi*sinphi + 2*(i)*cosiphi*cosphi); + data(k, 0) += rc[i] * (+2*(i)*siniphi*sinphi-(i*i+1)*cosiphi*cosphi) + + rs[i-1] * (-(i*i+1)*siniphi*cosphi - 2*(i)*cosiphi*sinphi); + data(k, 1) += rc[i] * (-2*(i)*siniphi*cosphi-(i*i+1)*cosiphi*sinphi) + + rs[i-1] * (-(i*i+1)*siniphi*sinphi + 2*(i)*cosiphi*cosphi); } } data *= 2*M_PI*2*M_PI; @@ -135,33 +125,28 @@ void CurvePlanarFourier::gammadashdashdash_impl(Array& data) { Array q_norm = q * inv_magnitude(); + double cosiphi, siniphi; for (int k = 0; k < numquadpoints; ++k) { double phi = 2 * M_PI * quadpoints[k]; double cosphi = cos(phi); double sinphi = sin(phi); - double cosiphi = 0; - double siniphi = 0; - for (int i = 0; i < order+1; ++i) { + data(k, 0) = rc[0]*(+sinphi); + data(k, 1) = rc[0]*(-cosphi); + for (int i = 1; i < order+1; ++i) { cosiphi = cos(i*phi); siniphi = sin(i*phi); data(k, 0) += rc[i]*( +(3*i*i + 1)*cosiphi*sinphi +(i*i + 3)*(i)*siniphi*cosphi + ) + rs[i-1]*( + -(i*i+3) * (i) * cosiphi*cosphi + +(3*i*i+1) * siniphi*sinphi ); data(k, 1) += rc[i]*( +(i*i + 3)*(i)*siniphi*sinphi -(3*i*i + 1)*cosiphi*cosphi - ); - } - for (int i = 1; i < order+1; ++i) { - cosiphi = cos(i*phi); - siniphi = sin(i*phi); - data(k, 0) += rs[i-1]*( - -(i*i+3) * (i) * cosiphi*cosphi - +(3*i*i+1) * siniphi*sinphi - ); - data(k, 1) += rs[i-1]*( + ) + rs[i-1]*( -(i*i+3)*(i)*cosiphi*sinphi -(3*i*i+1)*siniphi*cosphi ); @@ -187,6 +172,7 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { Array q_norm = q * inv_magnitude(); + double cosnphi, sinnphi; for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; int counter = 0; @@ -200,8 +186,9 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { double sinnphi = 0; for (int n = 0; n < order+1; ++n) { - i = cos(n*phi) * cosphi; - j = cos(n*phi) * sinphi; + cosnphi = cos(n * phi); + i = cosnphi * cosphi; + j = cosnphi * sinphi; k = 0; data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); @@ -212,8 +199,9 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { } for (int n = 1; n < order+1; ++n) { - i = sin(n*phi) * cosphi; - j = sin(n*phi) * sinphi; + sinnphi = sin(n * phi); + i = sinnphi * cosphi; + j = sinnphi * sinphi; k = 0; data(m, 0, counter) = (i - 2 * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * i + 2 * (q_norm[1] * q_norm[2] - q_norm[3] * q_norm[0]) * j + 2 * (q_norm[1] * q_norm[3] + q_norm[2] * q_norm[0]) * k); @@ -223,17 +211,15 @@ void CurvePlanarFourier::dgamma_by_dcoeff_impl(Array& data) { counter++; } - i = 0; - j = 0; + i = rc[0] * cosphi; + j = rc[0] * sinphi; k = 0; - for (int n = 0; n < order+1; ++n) { - i += rc[n] * cos(n*phi) * cosphi; - j += rc[n] * cos(n*phi) * sinphi; - } for (int n = 1; n < order+1; ++n) { - i += rs[n-1] * sin(n*phi) * cosphi; - j += rs[n-1] * sin(n*phi) * sinphi; + cosnphi = cos(n * phi); + sinnphi = sin(n * phi); + i += (rc[n] * cosnphi + rs[n-1] * sinnphi) * cosphi; + j += (rc[n] * cosnphi + rs[n-1] * sinnphi) * sinphi; } double inv_sqrt_s = inv_magnitude(); @@ -530,12 +516,11 @@ void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { Array q_norm = q * inv_magnitude(); + double cosnphi, sinnphi; for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; double cosphi = cos(phi); double sinphi = sin(phi); - double cosnphi = 0; - double sinnphi = 0; int counter = 0; double i; double j; @@ -576,21 +561,19 @@ void CurvePlanarFourier::dgammadash_by_dcoeff_impl(Array& data) { } - i = 0; - j = 0; + i = rc[0] * (-sinphi); + j = rc[0] * (cosphi); k = 0; - for (int n = 0; n < order+1; ++n) { - cosnphi = cos(n*phi); - sinnphi = sin(n*phi); - i += rc[n] * ( -(n) * sinnphi * cosphi - cosnphi * sinphi) * 2 * M_PI; - j += rc[n] * ( -(n) * sinnphi * sinphi + cosnphi * cosphi) * 2 * M_PI; - } for (int n = 1; n < order+1; ++n) { cosnphi = cos(n*phi); sinnphi = sin(n*phi); - i += rs[n-1] * ( (n) * cosnphi * cosphi - sinnphi * sinphi) * 2 * M_PI; - j += rs[n-1] * ( (n) * cosnphi * sinphi + sinnphi * cosphi) * 2 * M_PI; + i += rc[n] * ( -(n) * sinnphi * cosphi - cosnphi * sinphi) + + rs[n-1] * ( (n) * cosnphi * cosphi - sinnphi * sinphi); + j += rc[n] * ( -(n) * sinnphi * sinphi + cosnphi * cosphi) + + rs[n-1] * ( (n) * cosnphi * sinphi + sinnphi * cosphi); } + i *= (2*M_PI); + j *= (2*M_PI); double inv_sqrt_s = inv_magnitude(); data(m, 0, counter) = (4 * i * (q_norm[2] * q_norm[2] + q_norm[3] * q_norm[3]) * q_norm[0] @@ -886,12 +869,11 @@ void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { Array q_norm = q * inv_magnitude(); + double cosnphi, sinnphi; for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; double cosphi = cos(phi); double sinphi = sin(phi); - double cosnphi = 0; - double sinnphi = 0; int counter = 0; double i; double j; @@ -932,20 +914,16 @@ void CurvePlanarFourier::dgammadashdash_by_dcoeff_impl(Array& data) { counter++; } - i = 0; - j = 0; + i = rc[0] * (-cosphi); + j = rc[0] * (-sinphi); k = 0; - for (int n = 0; n < order+1; ++n) { - cosnphi = cos(n*phi); - sinnphi = sin(n*phi); - i += rc[n] * (+2*(n)*sinnphi*sinphi-(n*n+1)*cosnphi*cosphi); - j += rc[n] * (-2*(n)*sinnphi*cosphi-(n*n+1)*cosnphi*sinphi); - } for (int n = 1; n < order+1; ++n) { cosnphi = cos(n*phi); sinnphi = sin(n*phi); - i += rs[n-1] * (-(n*n+1)*sinnphi*cosphi - 2*(n)*cosnphi*sinphi); - j += rs[n-1] * (-(n*n+1)*sinnphi*sinphi + 2*(n)*cosnphi*cosphi); + i += rc[n] * (+2*(n)*sinnphi*sinphi-(n*n+1)*cosnphi*cosphi) + + rs[n-1] * (-(n*n+1)*sinnphi*cosphi - 2*(n)*cosnphi*sinphi); + j += rc[n] * (-2*(n)*sinnphi*cosphi-(n*n+1)*cosnphi*sinphi) + + rs[n-1] * (-(n*n+1)*sinnphi*sinphi + 2*(n)*cosnphi*cosphi); } i *= 2*M_PI*2*M_PI; j *= 2*M_PI*2*M_PI; @@ -1244,12 +1222,11 @@ void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { Array q_norm = q * inv_magnitude(); + double cosnphi, sinnphi; for (int m = 0; m < numquadpoints; ++m) { double phi = 2 * M_PI * quadpoints[m]; double cosphi = cos(phi); double sinphi = sin(phi); - double cosnphi = 0; - double sinnphi = 0; int counter = 0; double i; double j; @@ -1302,29 +1279,23 @@ void CurvePlanarFourier::dgammadashdashdash_by_dcoeff_impl(Array& data) { counter++; } - i = 0; - j = 0; + i = rc[0]*(sinphi); + j = rc[0]*(-cosphi); k = 0; - for (int n = 0; n < order+1; ++n) { + for (int n = 1; n < order+1; ++n) { cosnphi = cos(n*phi); sinnphi = sin(n*phi); i += rc[n]*( +(3*n*n + 1)*cosnphi*sinphi +(n*n + 3)*(n)*sinnphi*cosphi + ) + rs[n-1]*( + -(n*n+3) * (n) * cosnphi*cosphi + +(3*n*n+1) * sinnphi*sinphi ); j += rc[n]*( +(n*n + 3)*(n)*sinnphi*sinphi -(3*n*n + 1)*cosnphi*cosphi - ); - } - for (int n = 1; n < order+1; ++n) { - cosnphi = cos(n*phi); - sinnphi = sin(n*phi); - i += rs[n-1]*( - -(n*n+3) * (n) * cosnphi*cosphi - +(3*n*n+1) * sinnphi*sinphi - ); - j += rs[n-1]*( + ) + rs[n-1]*( -(n*n+3)*(n)*cosnphi*sinphi -(3*n*n+1)*sinnphi*cosphi );