点乘和叉乘及其物理意义(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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值