一些错误观念的澄清,比如数学意义上的
点积
和叉积
并不对应matlab程序中的.*
(按位相乘)和*
(矩阵乘法)内积的物理意义
- 一种向量到标量的映射
- 两向量的夹角的计算
- 两向量是否正交的判断
- 两向量的相似性(similarity)的度量
叉积的意义
如何使用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.youkuaiyun.com/jiangjunshow