/images/avatar.png

Abstract Algebra

抽象代数 1.1 群 满足四个性质: 封闭性:对于任意的$a,b\in G$,都有$a\circ b\in G$。 结合律:对于任意的$a,b,c\in G$,都有$(a\circ b)\circ c=a\circ(b\circ c)$。 幺元:存在一个元素$e\in G$,使得对于任意的$a\in G$,都有$e\circ a=a\circ e=a$。 逆元:对于任意的$a\in G$,都存在一个元素$b\in G$,使得$a\circ b=b\circ a=e$。 可以看到群并没有要求交换律。如果群内任意元素均满足$a\circ b=b\circ a$,则称该群为阿贝尔群。 半群: 满足封闭性和结合律,但不满足幺元和逆元。 1.2 群的同构和同态 同构: 若群$G$和$H$之间存在一个双射$\varphi:G\to H$,使得$f(a)=A$和$f(b)=B$,则有$f(a\circ b)=f(a)\ast f(b)$。 例:群$G(\mathbb{Z}/4\mathbb{Z},+)$和群$H(\left\{1,i,-1,-i\right\},\times)$同构。 同态: 给定两个群$(G,\circ)$和$(H,\ast)$,如果存在一个映射$\varphi:G\to H$,使得对于任意的$a,b\in G$,都有$\varphi(a\circ b)=\varphi(a)\ast\varphi(b)$,那么称$\varphi$是一个群的同态。因此可以说,同构是满足双射的同态 例1:$f(x)=x^2$是一个从实数到非负实数的同态。 例2:C3循环群和S3交换群同态,C3循环群和C6循环群同态 1.3 常见群 常见矩阵群: 一般线性群$GL(n)$:其单位元为单位矩阵,逆元为一个矩阵的逆矩阵。 特殊正交群$SO(n)$: 特殊欧式群$SE(n)$: 特殊射影群$SP(n)$ 循环群: 交换群 对称群:n个对象所有的重新排列组成对称群$S_n$,可参考(https://zhuanlan.zhihu.com/p/402197369) 环 2.1 环的定义 如果一个非空集合$R$上定义了两个二元运算$+$和$\times$,分别称为加法和乘法,满足: (1)$(R,+)$是阿贝尔群 (2)$(R,\times)$是半群 (3)乘法对于加法满足左分配律、右分配律,则称$R$ 关于运算$\times$,$+$构成一个环(ring),记为$(R,+,\times)$ 域

Lie Group

李群 李群指具有群结构的光滑微分流形,在物理上描述的是连续的对称性 例: 对于模为1的复数集合,其可以表示为$e^{i\theta}$,显然该集合对于乘法封闭,满足群的四个基本要求,所以说其具有群结构。 相对应的这个集合可以在复平面上绘制成一个圆,此时,圆上的任意一点,都可以用赋予其的值$\theta$表示其坐标,其等价于一个一维流形,且其上的乘法运算是光滑的,因此这个集合是一个李群 李代数:李群上的切空间。描述了李群的局部性质李代数由一个集合$V$,一个数域$F$ 和一个二元运算 $[,]$ 组成。如果它们满足以下几条性质,称 (V; F; [, ]) 为一个李代数,记作 g。 封闭性: $\forall \mathbf{X}, \mathbf{Y} \in V,[\mathbf{X}, \mathbf{Y}] \in V$ 双线性: $\forall \mathbf{X}, \mathbf{Y}, \mathbf{Z} \in V, a, b \in F$ ,有$[a \mathbf{X}+b \mathbf{Y}, \mathbf{Z}]=a[\mathbf{X}, \mathbf{Z}]+[\mathbf{Y}, \mathbf{Z}],[\mathbf{Z}, a \mathbf{X}+b \mathbf{Y}]=a[\mathbf{Z}, \mathbf{X}]+b[\mathbf{Z}, \mathbf{Y}]$ 自反性: $\forall \mathbf{X} \in V,[\mathbf{X}, \mathbf{X}]=\mathbf{0}$ 雅可比等价: $\forall \mathbf{X}, \mathbf{Y}, \mathbf{Z} \in V,[\mathbf{X},[\mathbf{Y}, \mathbf{Z}]]+[\mathbf{Z},[\mathbf{X}, \mathbf{Y}]]+[\mathbf{Y},[\mathbf{Z}, \mathbf{X}]]=\mathbf{0}$ 其中的二元运算称为李括号,他表示了两个元素之间的差异,在$R^3$空间中上定义的叉积就是一种李括号,此时$g=(R^3,R,\times)$构成了李代数 指数映射:将切空间上的切向量映射到流形上点的动作 对数映射:将流形上的点映射到切空间的切向量上 O(2) SO(2) SU(2) 对于单位四元数$a+bi+cj+dk$ 其左乘矩阵形式等价于$\left[\begin{array}{ccc}a & -b & -c & -d \\ b & a & -d & c \\ c & d & a & -b \\ d & -c & -b & -a\end{array}\right]$,右乘矩阵等价为$\left[\begin{array}{ccc}a & -b & -c & -d \\ b & a & d & -c \\ c & -d & a & b \\ d & c & -b & a\end{array}\right]$,以右乘矩阵为例,其每个子矩阵代表了一个复数,如果将其改写为复数矩阵,形式为$\left[\begin{array}{ccc}a+bi & -c+di\\ c + di & a-bi\end{array}\right]$此时,该矩阵为酉矩阵。且对于单位四元数,该矩阵的特征值为1。

distance computation

Distance Computation CPU上的离散模型距离计算库 FCL 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <fcl/fcl.h> typedef fcl::BVHModel<fcl::OBBRSS<REAL>> FCLModel; std::vector<fcl::Vector3<REAL>> fclVerticesA, fclVerticesB; std::vector<fcl::Triangle> fclTrianglesA, fclTrianglesB; std::shared_ptr<FCLModel> geomA = std::make_shared<FCLModel>(); std::shared_ptr<FCLModel> geomB = std::make_shared<FCLModel>(); FCLModel* FCLModelA, *FCLModelB; fcl::CollisionObject<REAL>* objA = new fcl::CollisionObject<REAL>(geomA, transformA); fcl::CollisionObject<REAL>* objB = new fcl::CollisionObject<REAL>(geomB, transformB); fcl::DistanceRequest<REAL> request; request.enable_nearest_points = true; fcl::DistanceResult<REAL> result; fcl::distance(objA, objB, request, result); PQP 1 2 3 4 5 6 7 8 #include "PQP.

Heat Method for Geodesic

基于热的测地线距离以及向量平行传输 heat method $\phi(x,y) = \lim _{t \rightarrow 0} \sqrt{-4t \log {k_t}(x,y)} $ 当热核函数存在误差的时候,直接使用Varadhan公式会有非常显著的误差。 Alg 在曲面上给定一点x上施加一个热源,并对其进行扩散获得温度场 1.$\frac{d}{dt}u = \Delta u$ 取u为顶点坐标的函数,代入热传导方程并离散化后有$\frac{u^{k+1} - u^k}{h} = Lu^k$,隐式迭代下为$(I-tL)u^{k+1} = u^k$。此时,$u_0$代表 可以使用Cholesky分解或者Krylov子空间分解,在论文中,t的选取一般取平均边长的平方 2.$X = -\frac{\nabla u}{|\nabla u|}$ 对温度场的梯度进行归一化后得到距离场扩散的向量场X 3.求解$\Delta u = \nabla \cdot X$ 对于已知向量场X,如果希望寻找一个势场u使得u可以表示X,则可以构造迪利克雷能量 $E(u)=\int_{M}|\nabla u-X|^{2} d A$。 而最小化迪利克雷能量等价于求解泊松方程$\Delta u = \nabla \cdot X$ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 /* Constructor * Input: The surface mesh <inputMesh> and geometry <inputGeo>.

FEM

fem概览 流程 1.获得微分方程 2.定义边界或者约束条件 3.将微分形式的控制方程转换为其等效积分 4.对计算单元刚度矩阵 5.单元刚度矩阵的组装 6.矩阵求解 等效变换 控制方程(微分形式)-> 等效积分 -> 等效积分的弱形式 变分形式推导 加权余量 给定微分方程 $$A(u) = 0$$ $$B(u) = 0$$ 能量泛函推导: $$A(u) = L(u) + f$$ $$\int_{\Omega}(L(u) + f)\delta u \ d\Omega = 0$$ $$ \begin{equation*} \begin{split} \int_{\Omega}L(u)\delta u \ d\Omega & = \int_{\Omega}\frac{1}{2}L(u)\delta u \ d\Omega + \int_{\Omega}\frac{1}{2}L(u)\delta u \ d\Omega \\ & = \int_{\Omega}\frac{1}{2}L(u)\delta u \ d\Omega + \int_{\Omega}\frac{1}{2}L(\delta u)u \ d\Omega \\ & = \delta\int_{\Omega}\frac{1}{2}L(u)u \ d\Omega \end{split} \end{equation*} $$ 其中A和B都是算子符号,$A(u)$为控制方程,$B(u)$为边界条件

mesh ccd

mesh ccd 基本概念 false positives a collision is reported when there is no collision false negatives a collision is not reported when there is a collision Multivariate CCD Formulation $$\begin{align*} &F_{\mathrm{vf}}(t, u, v)=p(t)-\left((1-u-v) v_1(t)+u v_2(t)+v v_3(t)\right)\\ &F_{\mathrm{vf}}: \Omega_{\mathrm{vf}}=[0,1] \times\{u, v \geqslant 0 \mid u+v \leqslant 1\} \rightarrow \mathbb{R}^3\\ &F_{\mathrm{ee}}(t, u, v)=\left((1-u) p_1(t)+u p_2(t)\right)-\left((1-v) p_3(t)+v p_4(t)\right)\\ &F_{\mathrm{ee}}: \Omega_{\mathrm{ee}}=[0,1] \times[0,1]^2 \rightarrow \mathbb{R}^3 \end{align*}$$ Univariate CCD Formulation Normal Cone test 给定连续曲面S以及其边界C,若其不自交,则必须通过surface normal test和contour test

Reduction

Reduction 概念 可以将Reduce操作视为计算$x = x_0\oplus x_1\oplus x_2\oplus …\oplus x_n$,$\oplus $作为算子可以表示为乘法,加法,最小值等运算 简易版Reduce 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 //一个基础的Reduce操作,源自NVDIA的教程 __global__ void reduce0(int* g_idata, int* g_odata) { extern __shared__ int sdata[]; unsigned int tid = threadIdx.x; unsigned int i = blockIdx.x*blockDim.x + threadIdx.x; sdata[tid] = g_idata[i]; __syncthreads(); for(unsigned int s=1; s < blockDim.x; s *= 2) { // 此处有warp divergent,并非所有thread都可以进入这个分支中,会造成硬件资源的浪费 // 其次取模操作需要消耗大量计算时间 if(tid % (2*s) == 0) { sdata[tid] += sdata[tid + s]; } __syncthreads(); } if(tid == 0) { g_odata[blockIdx.