An example from Polygon Mesh Processing page 74
The original equation:
I❤️LA implementation:
`E_LSCM` = ∑_T A_T‖M_T v_T - [0 -1
1 0] M_T u_T‖²
where
v_T ∈ ℝ^3
u_T ∈ ℝ^3
M_T ∈ ℝ^(2×3)
A_T ∈ ℝ
I❤️LA compiled to C++/Eigen:
/*
`E_LSCM` = ∑_T A_T‖M_T v_T - [0 -1
1 0] M_T u_T‖²
where
v_T ∈ ℝ^3
u_T ∈ ℝ^3
M_T ∈ ℝ^(2×3)
A_T ∈ ℝ
*/
#include <Eigen/Core>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <iostream>
#include <set>
struct pmp_74ResultType {
double E_LSCM;
pmp_74ResultType(const double & E_LSCM)
: E_LSCM(E_LSCM)
{}
};
pmp_74ResultType pmp_74(
const std::vector<Eigen::Matrix<double, 3, 1>> & v,
const std::vector<Eigen::Matrix<double, 3, 1>> & u,
const std::vector<Eigen::Matrix<double, 2, 3>> & M,
const std::vector<double> & A)
{
const long dim_0 = A.size();
assert( v.size() == dim_0 );
assert( u.size() == dim_0 );
assert( M.size() == dim_0 );
double sum_0 = 0;
for(int T=1; T<=M.size(); T++){
Eigen::Matrix<double, 2, 2> E_LSCM_0;
E_LSCM_0 << 0, -1,
1, 0;
sum_0 += A.at(T-1) * pow((M.at(T-1) * v.at(T-1) - E_LSCM_0 * M.at(T-1) * u.at(T-1)).lpNorm<2>(), 2);
}
double E_LSCM = sum_0;
return pmp_74ResultType(E_LSCM);
}
void generateRandomData(std::vector<Eigen::Matrix<double, 3, 1>> & v,
std::vector<Eigen::Matrix<double, 3, 1>> & u,
std::vector<Eigen::Matrix<double, 2, 3>> & M,
std::vector<double> & A)
{
const int dim_0 = rand()%10;
v.resize(dim_0);
for(int i=0; i<dim_0; i++){
v[i] = Eigen::VectorXd::Random(3);
}
u.resize(dim_0);
for(int i=0; i<dim_0; i++){
u[i] = Eigen::VectorXd::Random(3);
}
M.resize(dim_0);
for(int i=0; i<dim_0; i++){
M[i] = Eigen::MatrixXd::Random(2, 3);
}
A.resize(dim_0);
for(int i=0; i<dim_0; i++){
A[i] = rand() % 10;
}
}
int main(int argc, char *argv[])
{
srand((int)time(NULL));
std::vector<Eigen::Matrix<double, 3, 1>> v;
std::vector<Eigen::Matrix<double, 3, 1>> u;
std::vector<Eigen::Matrix<double, 2, 3>> M;
std::vector<double> A;
generateRandomData(v, u, M, A);
pmp_74ResultType func_value = pmp_74(v, u, M, A);
std::cout<<"return value:\n"<<func_value.E_LSCM<<std::endl;
return 0;
}
I❤️LA compiled to Python/NumPy/SciPy:
"""
`E_LSCM` = ∑_T A_T‖M_T v_T - [0 -1
1 0] M_T u_T‖²
where
v_T ∈ ℝ^3
u_T ∈ ℝ^3
M_T ∈ ℝ^(2×3)
A_T ∈ ℝ
"""
import numpy as np
import scipy
import scipy.linalg
from scipy import sparse
from scipy.integrate import quad
from scipy.optimize import minimize
class pmp_74ResultType:
def __init__( self, E_LSCM):
self.E_LSCM = E_LSCM
def pmp_74(v, u, M, A):
v = np.asarray(v, dtype=np.float64)
u = np.asarray(u, dtype=np.float64)
M = np.asarray(M, dtype=np.float64)
A = np.asarray(A, dtype=np.float64)
dim_0 = A.shape[0]
assert v.shape == (dim_0, 3, )
assert u.shape == (dim_0, 3, )
assert M.shape == (dim_0, 2, 3)
assert A.shape == (dim_0,)
sum_0 = 0
for T in range(1, len(M)+1):
E_LSCM_0 = np.zeros((2, 2))
E_LSCM_0[0] = [0, -1]
E_LSCM_0[1] = [1, 0]
sum_0 += A[T-1] * np.power(np.linalg.norm(M[T-1] @ v[T-1] - E_LSCM_0 @ M[T-1] @ u[T-1], 2), 2)
E_LSCM = sum_0
return pmp_74ResultType(E_LSCM)
def generateRandomData():
dim_0 = np.random.randint(10)
v = np.random.randn(dim_0, 3, )
u = np.random.randn(dim_0, 3, )
M = np.random.randn(dim_0, 2, 3)
A = np.random.randn(dim_0)
return v, u, M, A
if __name__ == '__main__':
v, u, M, A = generateRandomData()
print("v:", v)
print("u:", u)
print("M:", M)
print("A:", A)
func_value = pmp_74(v, u, M, A)
print("return value: ", func_value.E_LSCM)
I❤️LA compiled to MATLAB:
function output = pmp_74(v, u, M, A)
% output = pmp_74(v, u, M, A)
%
% `E_LSCM` = ∑_T A_T‖M_T v_T - [0 -1
% 1 0] M_T u_T‖²
% where
%
% v_T ∈ ℝ^3
% u_T ∈ ℝ^3
% M_T ∈ ℝ^(2×3)
% A_T ∈ ℝ
if nargin==0
warning('generating random input data');
[v, u, M, A] = generateRandomData();
end
function [v, u, M, A] = generateRandomData()
dim_0 = randi(10);
v = randn(dim_0,3);
u = randn(dim_0,3);
M = randn(dim_0,2,3);
A = randn(dim_0,1);
end
A = reshape(A,[],1);
dim_0 = size(A, 1);
assert( isequal(size(v), [dim_0, 3]) );
assert( isequal(size(u), [dim_0, 3]) );
assert( isequal(size(M), [dim_0, 2, 3]) );
assert( size(A,1) == dim_0 );
sum_0 = 0;
for T = 1:size(M, 1)
E_LSCM_0 = zeros(2, 2);
E_LSCM_0(1,:) = [0, -1];
E_LSCM_0(2,:) = [1, 0];
sum_0 = sum_0 + A(T) * norm(squeeze(M(T,:,:)) * v(T,:)' - E_LSCM_0 * squeeze(M(T,:,:)) * u(T,:)', 2).^2;
end
E_LSCM = sum_0;
output.E_LSCM = E_LSCM;
end
I❤️LA compiled to LaTeX:
\documentclass[12pt]{article}
\usepackage{mathdots}
\usepackage[bb=boondox]{mathalfa}
\usepackage{mathtools}
\usepackage{amssymb}
\usepackage{libertine}
\DeclareMathOperator*{\argmax}{arg\,max}
\DeclareMathOperator*{\argmin}{arg\,min}
\usepackage[paperheight=8in,paperwidth=4in,margin=.3in,heightrounded]{geometry}
\let\originalleft\left
\let\originalright\right
\renewcommand{\left}{\mathopen{}\mathclose\bgroup\originalleft}
\renewcommand{\right}{\aftergroup\egroup\originalright}
\begin{document}
\begin{center}
\resizebox{\textwidth}{!}
{
\begin{minipage}[c]{\textwidth}
\begin{align*}
\textit{E\_LSCM} & = \sum_\mathit{T} \mathit{A}_{ \mathit{T} }\left\|\mathit{M}_{ \mathit{T} }\mathit{v}_{ \mathit{T} } - \begin{bmatrix}
0 & -1\\
1 & 0\\
\end{bmatrix}\mathit{M}_{ \mathit{T} }\mathit{u}_{ \mathit{T} }\right\|_2^{2} \\
\intertext{where}
\mathit{v}_{\mathit{T}} & \in \mathbb{R}^{ 3} \\
\mathit{u}_{\mathit{T}} & \in \mathbb{R}^{ 3} \\
\mathit{M}_{\mathit{T}} & \in \mathbb{R}^{ 2 \times 3 } \\
\mathit{A}_{\mathit{T}} & \in \mathbb{R} \\
\\
\end{align*}
\end{minipage}
}
\end{center}
\end{document}
I❤️LA LaTeX output: