当前位置: 首页 > 编程日记 > 正文

行列式介绍及Eigen/OpenCV/C++的三种实现

行列式,记作det(A),是一个将方阵A映射到实数的函数。行列式等于矩阵特征值的乘积。行列式的绝对值可以用来衡量矩阵参与矩阵乘法后空间扩大或者缩小了多少。如果行列式是0,那么空间至少沿着某一维完全收缩了,使其失去了所有的体积。如果行列式是1,那么这个转换保持空间体积不变。

行列式(Determinant)是数学中的一个函数,将一个n*n的矩阵A映射到一个标量,记作det(A)或|A|。行列式可以看作是有向面积或体积的概念在一般的欧几里得空间中的推广。或者说,在n维欧几里得空间中,行列式描述的是一个线性变换对”体积”所造成的影响。

对于简单的2阶和3阶的矩阵,行列式的表达式相对简单,而且恰好是每条主对角线(左上至右下)元素乘积之和减去每条副对角线(右上至左下)元素乘积之和。

一个n阶方块矩阵A的行列式可直观地定义如下,来自于维基百科:


按照拉普拉斯公式进行递推计算:

对一个n阶的行列式M,去掉M的第i行第j列后形成的n-1阶的行列式叫做M关于元素mij的余因式(又称余子式),记作Mij

M关于元素mij的代数余子式记作Cij:Cij=(-1)(i+j)*Mij

一个n阶的行列式M可以写成一行(或一列)的元素与对应的代数余子式的乘积之和,叫做行列式按一行(或一列)的展开,如:

det(A)=a11C11+a21C21+…+an1Cn1 或  det(A)=a11C11+a12C12+…+a1nC1n

这个公式又称拉普拉斯公式,把n维矩阵的行列式计算变成了n个n-1维的行列式的计算。另一方面,拉普拉斯公式可以作为行列式的一种归纳定义。

行列式性质:

(1)、单位矩阵的行列式为1,若矩阵的某几行线性相关,则它的行列式为零。

(2)、一个矩阵的行列式等于它的转置矩阵的行列式。

(3)、在行列式中,一行(列)元素全为0,则此行列式的值为0。

(4)、在行列式中,某一行(列)有公因子k,则可以提出k。

(5)、在行列式中,某一行(列)的每个元素是两数之和,则此行列式可拆分为两个相加的行列式。

(6)、行列式中的两行(列)互换,改变行列式正负符号。

(7)、在行列式中,有两行(列)对应成比例或相同,则此行列式的值为0。

(8)、将一行(列)的k倍加进另一行(列)里,行列式的值不变。注:一行(列)的k倍加上另一行(列),行列式的值改变。

(9)、将行列式的行列互换,行列式的值不变,其中行列互换相当于转置。这个性质可以简单地记作:D=|aij|=|aji|=DT

(10)、行列式的乘法定理:方块矩阵的乘积的行列式等于行列式的乘积:det(AB) = det(A)det(B)

(11)、若A是可逆矩阵,det(A-1)=(det(A))-1

(12)、若两个矩阵相似,那么它们的行列式相同。

(13)、行列式是所有特征值(按代数重数计)的乘积。

行列式的计算:(1)、按照定义公式;(2)、按照拉普拉斯公式进行递归计算;(3)、利用高斯消去法;(4)、LU分解法。

以下测试代码是采用Eigen实现的行列式计算:

int test_mat_determinant()
{std::vector<float> vec{ 1, 0, 2, -1, 3, 0, 0, 5, 2, 1, 4, -3, 1, 0, 5, 0 };Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> map(vec.data(), 4, 4);double det = map.determinant();fprintf(stderr, "det: %f\n", det);return 0;
}
执行结果如下:

以下是分别采用OpenCV和C++实现的行列式计算:

#include "funset.hpp"
#include <math.h>
#include <iostream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>static double determinant_opencv(const std::vector<float>& vec)
{int length = std::sqrt(vec.size());cv::Mat mat(length, length, CV_32FC1, const_cast<float*>(vec.data()));// In OpenCV, for small matrices(rows=cols<=3),the direct method is used.// For larger matrices the function uses LU factorization with partial pivoting.return cv::determinant(mat);
}template<typename _Tp>
static _Tp det(const std::vector<std::vector<_Tp>>& mat, int N)
{if (mat.size() != N) {fprintf(stderr, "mat must be square matrix\n");return -1;}for (int i = 0; i < mat.size(); ++i) {if (mat[i].size() != N) {fprintf(stderr, "mat must be square matrix\n");return -1;}}_Tp ret{ 0 };if (N == 1) return mat[0][0];if (N == 2) {return (mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]);} else {// first colfor (int i = 0; i < N; ++i) {std::vector<std::vector<_Tp>> m(N - 1);std::vector<int> m_rows;for (int t = 0; t < N; ++t) {if (i != t) m_rows.push_back(t);}for (int x = 0; x < N - 1; ++x) {m[x].resize(N - 1);for (int y = 0; y < N - 1; ++y) {m[x][y] = mat[m_rows[x]][y + 1];}}int sign = (int)pow(-1, 1 + i + 1);ret += mat[i][0] * sign * det<_Tp>(m, N-1);}}return ret;
}int test_determinant()
{std::vector<float> vec{ 1, 0, 2, -1, 3, 0, 0, 5, 2, 1, 4, -3, 1, 0, 5, 0};const int N{ 4 };if (vec.size() != (int)pow(N, 2)) {fprintf(stderr, "vec must be N^2\n");return -1;}double det1 = determinant_opencv(vec);std::vector<std::vector<float>> arr(N);for (int i = 0; i < N; ++i) {arr[i].resize(N);for (int j = 0; j < N; ++j) {arr[i][j] = vec[i * N + j];}}double det2 = det<float>(arr, N);fprintf(stderr, "det1: %f, det2: %f\n", det1, det2);return 0;
}
执行结果如下:


经测试,使用C++实现的行列式的计算与调用OpenCV和Eigen接口实现的结果是一致的。

GitHub

https://github.com/fengbingchun/NN_Test

https://github.com/fengbingchun/Eigen_Test

相关文章:

基于Go的语义解析开源库FMR,“屠榜”模型外的NLP利器

&#xff08;由AI科技大本营付费下载自视觉中国&#xff09;作者 | 刘占亮 一览群智技术副总裁编辑 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;如何合理地表示语言的内在意义&#xff1f;这是自然语言处理业界中长久以来悬而未决的一个命题。在…

【高级数据类型2】- 10. 接口

2019独角兽企业重金招聘Python工程师标准>>> Go语言-接口 在Go语言中&#xff0c;一个接口类型总是代表着某一种类型&#xff08;即所有实现它的类型&#xff09;的行为。一个接口类型的声明通常会包含关键字type、类型名称、关键字interface以及由花括号包裹的若干…

Linux软件包命令

2019独角兽企业重金招聘Python工程师标准>>> dpkg命令&#xff1a; dpkg -i **/**.deb 安装软件 dpkg -x **.deb 解开.deb文件 dpkg -r /-p 删除并清配置 更详细的 用dpkg --help 查询 如下&#xff1a; dpkg -i|--install <.deb 文件的文件名> ... | -R|--re…

Caffe中计算图像均值的实现(cifar10)

在深度学习中&#xff0c;在进行test时经常会减去train数据集的图像均值&#xff0c;这样做的好处是&#xff1a;属于数据预处理中的数据归一化&#xff0c;降低数据间相似性&#xff0c;可以将数值调整到一个合理的范围。以下code是用于计算cifar10中训练集的图像均值&#xf…

阿里云弹性公网IP(EIP)的使用限制

阿里云弹性公网IP&#xff08;EIP&#xff09;是一种可以独立购买和持有的公网IP地址资源&#xff0c;弹性公网IP具有独立购买持有、弹性绑定和配置灵活等优势&#xff0c;但实际使用中弹性公网IP也是有很多限制的&#xff0c;阿里云惠网分享弹性公网IP&#xff08;EIP&#xf…

400名微软员工主动曝光薪资:28万元到228万元不等!

作者 | Dave Gershgorn译者 | 弯月&#xff0c;编辑 | 郭芮来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;【导读】近日&#xff0c;近400名微软员工分享了他们的薪酬&#xff08;从4万美元到32万美元不等&#xff0c;约为28万人民币到228万人民币&#xff09;&am…

Extjs:添加查看全部按钮

var grid new Ext.grid.GridPanel({renderTo:tsllb,title:产品成本列表,selModel:csm,height:350,columns:[csm,{header: "编码", dataIndex: "bm", sortable: true,hidden:true},{header: "产品", dataIndex: "cp", sortable: true},…

练手扎实基本功必备:非结构文本特征提取方法

作者 | Dipanjan (DJ) Sarkar编译 | ronghuaiyang来源 | AI公园&#xff08;ID:AI_Paradise&#xff09;【导读】本文介绍了一些传统但是被验证是非常有用的&#xff0c;现在都还在用的策略&#xff0c;用来对非结构化的文本数据提取特征。介绍在本文中&#xff0c;我们将研究如…

范数介绍及C++/OpenCV/Eigen的三种实现

有时我们需要衡量一个向量的大小。在机器学习中&#xff0c;我们经常使用被称为范数(norm)的函数衡量向量大小。形式上&#xff0c;Lp范数定义如下&#xff1a;范数(包括Lp范数)是将向量映射到非负值的函数。直观上来说&#xff0c;向量x的范数衡量从原点到点x的距离。更严格地…

js添加网页水印和three.js场景中加水印

我们在日常网页开发的时候&#xff0c;可能想给自己的网页或者canvas里面添加水印&#xff0c;增添个人标记&#xff0c;我这里分为普通静态html页面和threejs中3d场景里面添加水印功能。一 静态html页面添加水印你只需要在你的页面添加一个图片遮罩&#xff0c;通过绝对定位和…

JAVA学习笔记(6)

关于多线程的优先级&#xff0c;这个程序里面&#xff0c;现在计算机比较好&#xff0c;int存储不下了&#xff0c;我跑了好几次都是负分&#xff0c;特把int改成long。但是之后跑出来的结果&#xff0c;两个数字都差不多&#xff0c;不知道是什么问题&#xff1f;等待答案中。…

C++/C++11中std::deque的使用

std::deque是双端队列&#xff0c;可以高效的在头尾两端插入和删除元素&#xff0c;在std::deque两端插入和删除并不会使其它元素的指针或引用失效。在接口上和std::vector相似。与sdk::vector相反&#xff0c;std::deque中的元素并非连续存储&#xff1a;典型的实现是使用一个…

贾扬清:我对人工智能方向的一点浅见

阿里妹导读&#xff1a;作为 AI 大神&#xff0c;贾扬清让人印象深刻的可能是他写的AI框架Caffe &#xff0c;那已经是六年前的事了。经过多年的沉淀&#xff0c;成为“阿里新人”的他&#xff0c;对人工智能又有何看法&#xff1f;最近&#xff0c;贾扬清在阿里内部分享了他的…

吴甘沙:天外飞“厕”、红绿灯消失,未来无人驾驶将被重新定义

整理 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;2019 年9 月 5 日至 7 日&#xff0c;由新一代人工智能产业技术创新战略联盟&#xff08;AITISA&#xff09;指导&#xff0c;鹏城实验室、北京智源人工智能研究院支持&#xff0c;专业中文 IT 技术社区 CS…

Linux内核--网络栈实现分析(二)--数据包的传递过程--转

转载地址http://blog.csdn.net/yming0221/article/details/7492423 作者&#xff1a;闫明 本文分析基于Linux Kernel 1.2.13 注&#xff1a;标题中的”&#xff08;上&#xff09;“&#xff0c;”&#xff08;下&#xff09;“表示分析过程基于数据包的传递方向&#xff1a;”…

C++/C++11中std::stack的使用

栈stack 是一个容器适配器(container adaptor)类型&#xff0c;被特别设计用来运行于LIFO(Last-in First-out&#xff0c;后进先出)场景&#xff0c;在该场景中&#xff0c;只能从容器末尾添加和删除元素&#xff0c;其定义在stack头文件中。stack默认基于std::deque实现&#…

团队前四次作业——个人总结

团队前四次作业——个人总结 描述 团队名称待就业六人组相关团队第四次作业答辩——反思与总结做了哪些事&#xff1f;工作量、完成度 作业负责工作量完成度团队队员展示创意合照后期1h95%项目选题报告编写创新和收益部分2h85%项目原型设计原型设计6h95%需求规格说明书功能需求…

吴甘沙:天外飞“厕”、红绿灯消失,未来无人驾驶将被重新定义 | AI ProCon 2019

2019 年9 月 5 日至 7 日&#xff0c;由新一代人工智能产业技术创新战略联盟&#xff08;AITISA&#xff09;指导&#xff0c;鹏城实验室、北京智源人工智能研究院支持&#xff0c;专业中文 IT 技术社区 CSDN 主办的 2019 中国 AI 开发者大会&#xff08;AI ProCon 2019&#x…

MySQL基础day03_数据的导入、导出-MySQL 5.6

MySQL基础day03_数据的导入、导出-MySQL 5.6注&#xff1a;把数据按照一定格式存放到文件里才能进行数据的导入。1&#xff0c;数据导入的条件把文件里的内容保存到数据的表里&#xff1b;把数据按照一定格式存放文件里&#xff1b;注&#xff1a;默认情况下&#xff0c;只有管…

“含光”剑出,谁与争锋?阿里重磅发布首颗AI芯片含光800

作者 | 夕颜、胡巍巍 编辑 | 唐小引 出品 | AI 科技大本营&#xff08;ID:rgznai100&#xff09; 9 月末的杭州气温适宜&#xff0c;宜出游&#xff0c;宜在湖边餐厅浅酌一杯清茶消闲。但在钱塘江水支流河畔的云栖小镇&#xff0c;却完全一副与闲适氛围不相称的热闹景象。 …

c++面试题中经常被面试官面试的小问题总结(一)(本篇偏向基础知识)

原文作者&#xff1a;aircraft 原文链接&#xff1a;https://www.cnblogs.com/DOMLX/p/10711810.html 1.类中的函数定义后加了一个const代表什么&#xff1f; 代表它将具备以下三个性质&#xff1a;1.const对象只能调用const成员函数。2.const对象的值不能被修改&#xff0c;在…

矩阵特征分解介绍及雅克比(Jacobi)方法实现特征值和特征向量的求解(C++/OpenCV/Eigen)

对角矩阵(diagonal matrix)&#xff1a;只在主对角线上含有非零元素&#xff0c;其它位置都是零&#xff0c;对角线上的元素可以为0或其它值。形式上&#xff0c;矩阵D是对角矩阵&#xff0c;当且仅当对于所有的i≠j, Di,j 0. 单位矩阵就是对角矩阵&#xff0c;对角元素全部是1…

Entity Framework CodeFirst数据迁移

原文:Entity Framework CodeFirst数据迁移前言 紧接着前面一篇博文Entity Framework CodeFirst尝试。 我们知道无论是“Database First”还是“Model First”当模型发生改变了都可以通过Visual Studio设计视图进行更新&#xff0c;那么对于Code First如何更新已有的模型呢&…

限时早鸟票 | 2019 中国大数据技术大会(BDTC)超豪华盛宴抢先看!

2019 年12月5-7 日&#xff0c;由中国计算机学会主办&#xff0c;CCF 大数据专家委员会承办&#xff0c;CSDN、中科天玑数据科技股份有限公司协办的 2019 中国大数据技术大会&#xff0c;将于北京长城饭店隆重举行。届时&#xff0c;超过百位技术专家及行业领袖将齐聚于此&…

Google AI 系统 DeepMind无法通过 高中数学

Google 旗下 DeepMind 团队让 AI 系统接受一项高中程度的数学测试&#xff0c;结果在 40 道题目中只答对了 14 题&#xff0c;甚至连「1111111」也算错了。说来难以置信&#xff0c;Google AI 系统能打败人类世界棋王&#xff0c;却无法通过高中程度的数学考试。上周&#xff0…

C++11中std::tuple的使用

std::tuple是类似pair的模板。每个pair的成员类型都不相同&#xff0c;但每个pair都恰好有两个成员。不同std::tuple类型的成员类型也不相同&#xff0c;但一个std::tuple可以有任意数量的成员。每个确定的std::tuple类型的成员数目是固定的&#xff0c;但一个std::tuple类型的…

PHP Countable接口

实现该接口可以使用count()方法来获取集合的总数转载于:https://www.cnblogs.com/xiaodo0/p/3611307.html

矩阵奇异值分解简介及C++/OpenCV/Eigen的三种实现

奇异值分解(singular value decomposition, SVD)&#xff1a;将矩阵分解为奇异向量(singular vector)和奇异值(singular value)。通过奇异值分解&#xff0c;我们会得到一些与特征分解相同类型的信息。然而&#xff0c;奇异值分解有更广泛的应用。每个实数矩阵都有一个奇异值分…

经典!工业界深度推荐系统与CTR预估必读的论文汇总

&#xff08;图片付费下载自视觉中国&#xff09;来源 | 深度传送门&#xff08;ID: gh_5faae7b50fc5&#xff09;导读&#xff1a;本文是“深度推荐系统”专栏的第十一篇文章&#xff0c;这个系列将介绍在深度学习的强力驱动下&#xff0c;给推荐系统工业界所带来的最前沿的变…

docker上传自己的镜像

https://blog.csdn.net/boonya/article/details/74906927 需要注意的就是命名规范 docker push 注册用户名/镜像名 tag命令修改为规范的镜像&#xff1a; docker tag boonya/tomcat-allow-remote boonyadocker/tomcat-allow-remote转载于:https://www.cnblogs.com/MC-Curry/p/1…