点乘和叉乘及其物理意义(C++STL实现)

                       
  1. 一些错误观念的澄清,比如数学意义上的点积叉积并不对应matlab程序中的.*(按位相乘)和*(矩阵乘法)

  2. 内积的物理意义

    • 一种向量到标量的映射
    • 两向量的夹角的计算
    • 两向量是否正交的判断
    • 两向量的相似性(similarity)的度量
  3. 叉积的意义

  4. 如何使用C++语言(STL容器,运算符重载):

    • 表示向量
    • 计算内积
    • 计算叉积
    • 计算模长
    • 计算两向量的夹角
    • 计算点到直线的距离

prerequisites

内积(inner product)

又叫点乘,点积(dot product),数量积,顾名思义得到的是一个标量(scalar)。

  • 代数定义

向量x=[x1,x2,,xn]x=[x 1 ,x 2 ,,x n ]

C++ STL实现

  • 向量的定义:
typedef vector<double> Vec;
   
   
  • 1
  • 矩阵减法
Vec operator-(const Vec& x, const Vec& y){    assert(x.size() == y.size());                        // #include <cassert>    Vec tmp;    for(size_t i = 0; i < x.size(); ++i)        tmp.push_back(x[i] - y[i]);    return tmp;         // 返回局部变量的拷贝}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 内积和叉积的定义

为了形式的简单,我们在C++中以*表示内积,以^表示叉积,分别对二者进行运算符重载:

double operator*(const Vec& x, const Vec& y){    assert(x.size() == y.size());       // #include <cassert>    double sum = 0.;    for (size_t i = 0; i < x.size(); ++i)        sum += x[i]*y[i];    return sum;}// 三维的情况Vec operator^(const Vec& x, const Vec& y){    assert(x.size() == y.size() && x.size() == 3);    return Vec{x[1]*y[2]-x[2]*y[1],                 x[2]*y[0]-x[0]*y[2],                x[0]*y[1]-x[1]*y[0]};            // uniform initialization, C++11新特性}// 二维就姑且返回其模长吧double twoDCrossProd(const Vec& x, const Vec& y){    return x[0]*y[1]-x[1]*y[0];}
   
   
  • 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
  • 模长或者范数的计算
double norm(const Vec& x){    double val = 0.;    for(auto elem: x)        val += elem*elem;    return sqrt(val);                       // #include <cmath>}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 向量夹角的计算
#define PI 3.14159265358979323846// 弧长向弧度的转换double toDegree(double val){    return val*180/PI;}double angle(const Vec& x, const Vec& y){    return toDegree(acos(x*y/norm(x)/norm(y)));            // x*y, 计算二者的内积}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 点到直线的距离
// x0, x1, x2 分别表示三角形的三个顶点的坐标// 这里计算的是点x0到x1和x2构成的直线的距离double distance(const Vec& x0, const Vec& x1, const Vec& x2){    return twoDCrossProd(x1-x0, x2-x0)/norm(x1-x2);}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

客户端程序:

int main(int, char**){    Vec x{1, 0, 0}, y{0, 1, 0};    Vec z = x^y;        // 计算叉乘    copy(z.begin(), z.end(), ostream_iterator<double>(cout, " "));    cout << endl;        // 0 0 1    Vec alpha{1, 0}, beta{1, 1};    cout << angle(alpha, beta) << endl;            // 45    Vec x0{0, 0}, x1{1, 0}, x2{0, 1};       cout << distance(x0, x1, x2) << endl;            // 1/sqrt(2)    return 0;}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

猜你喜欢

转载自blog.csdn.net/qq_43679627/article/details/87726715