Eigen-约简,访问和广播

约简化,访客和广播

  • 一、约简化
    • 1. 标准计算
    • 2. 布尔约减
  • 二、访问
  • 三、部分约简
    • 1. 将部分约减与其他业务相结合
  • 四、广播
    • 1. 将广播与其他业务相结合

一、约简化

在Eigen中,约简化是一个接受矩阵或数组并返回单个标量值的函数。最常用的约简方法之一是.sum(),它返回给定矩阵或数组中所有系数的和。

#include <iostream>
#include <Eigen/Dense>using namespace std;
int main()
{Eigen::Matrix2d mat;mat << 1, 2,3, 4;cout << "Here is mat.sum():       " << mat.sum()       << endl;cout << "Here is mat.prod():      " << mat.prod()      << endl;cout << "Here is mat.mean():      " << mat.mean()      << endl;cout << "Here is mat.minCoeff():  " << mat.minCoeff()  << endl;cout << "Here is mat.maxCoeff():  " << mat.maxCoeff()  << endl;cout << "Here is mat.trace():     " << mat.trace()     << endl;
}//输出
Here is mat.sum():       10
Here is mat.prod():      24
Here is mat.mean():      2.5
Here is mat.minCoeff():  1
Here is mat.maxCoeff():  4
Here is mat.trace():     5

由函数 trace() 返回的矩阵的轨迹是对角线系数的和,可以等效地计算为 a.diagonal().sum()。

1. 标准计算

向量的(欧几里得也就是 ℓ2 )平方范数可以得到 squaredNorm()。它等于向量与自身的点积,也等价于它的系数绝对值的平方和。

Eigen还提供了 norm() 方法,该方法返回 squaredNorm() 的平方根。

这些运算也可以作用于矩阵;在这种情况下,n × p 矩阵被视为大小为 (n * p) 的向量,因此例如 norm() 方法返回 “Frobenius” 或“Hilbert-Schmidt” 范数。我们不讨论矩阵 ℓ2 范数因为它有不同的含义。

如果需要其他与系数相关的 ℓp 规范,请使用 lpNorm<p>() 方法。模板参数p可以取特殊值无穷大,如果你想要的是 ℓ 范数,它是系数绝对值的最大值。

下面的示例演示了这些方法。

#include <Eigen/Dense>
#include <iostream>int main()
{Eigen::VectorXf v(2);Eigen::MatrixXf m(2,2), n(2,2);v << -1,2;m << 1,-2,-3,4;std::cout << "v.squaredNorm() = " << v.squaredNorm() << std::endl;std::cout << "v.norm() = " << v.norm() << std::endl;std::cout << "v.lpNorm<1>() = " << v.lpNorm<1>() << std::endl;std::cout << "v.lpNorm<Infinity>() = " << v.lpNorm<Eigen::Infinity>() << std::endl;std::cout << std::endl;std::cout << "m.squaredNorm() = " << m.squaredNorm() << std::endl;std::cout << "m.norm() = " << m.norm() << std::endl;std::cout << "m.lpNorm<1>() = " << m.lpNorm<1>() << std::endl;std::cout << "m.lpNorm<Infinity>() = " << m.lpNorm<Eigen::Infinity>() << std::endl;
}// 输出
v.squaredNorm() = 5
v.norm() = 2.23607
v.lpNorm<1>() = 3
v.lpNorm<Infinity>() = 2m.squaredNorm() = 30
m.norm() = 5.47723
m.lpNorm<1>() = 10
m.lpNorm<Infinity>() = 4

算子范数:1 范数和 ∞ 范数矩阵算子范数可以很容易地计算如下:

#include <Eigen/Dense>
#include <iostream>int main()
{Eigen::MatrixXf m(2,2);m << 1,-2,-3,4;std::cout << "1-norm(m)     = " << m.cwiseAbs().colwise().sum().maxCoeff()<< " == "             << m.colwise().lpNorm<1>().maxCoeff() << std::endl;std::cout << "infty-norm(m) = " << m.cwiseAbs().rowwise().sum().maxCoeff()<< " == "             << m.rowwise().lpNorm<1>().maxCoeff() << std::endl;
}// 输出
1-norm(m)     = 6 == 6
infty-norm(m) = 7 == 7

有关这些表达式语法的更多解释,请参见下文。

2. 布尔约减

下面的约简操作是对布尔值进行的:

  • 如果给定矩阵或数组中的所有系数都为真,则 all() 返回真。
  • 如果给定矩阵或数组中至少有一个系数为真,则 any() 返回真。
  • count() 返回给定矩阵或数组中求值为true的系数数。

这些操作符通常与 Array 提供的系数比较和相等操作符一起使用。例如,array > 0 是与 array 大小相同的 array,在 array 对应系数为正的位置为 true。因此,(array > 0).all() 测试数组的所有系数是否都为正。这可以从下面的例子中看到:

#include <Eigen/Dense>
#include <iostream>int main()
{Eigen::ArrayXXf a(2,2);a << 1,2,3,4;std::cout << "(a > 0).all()   = " << (a > 0).all() << std::endl;std::cout << "(a > 0).any()   = " << (a > 0).any() << std::endl;std::cout << "(a > 0).count() = " << (a > 0).count() << std::endl;std::cout << std::endl;std::cout << "(a > 2).all()   = " << (a > 2).all() << std::endl;std::cout << "(a > 2).any()   = " << (a > 2).any() << std::endl;std::cout << "(a > 2).count() = " << (a > 2).count() << std::endl;
}//输出
(a > 0).all()   = 1
(a > 0).any()   = 1
(a > 0).count() = 4(a > 2).all()   = 0
(a > 2).any()   = 1
(a > 2).count() = 2

二、访问

当想要获得矩阵或数组中系数的位置时,也就是获取矩阵中的特殊元素的时候。访问器很有用。最简单的例子是 maxCoeff(&x,&y) 和 minCoeff(&x,&y),它们可用于查找矩阵或数组中最大或最小系数的位置。

传递给访问者的参数是指向存储行和列位置的变量的指针。这些变量的类型应该是Index,如下所示:

#include <iostream>
#include <Eigen/Dense>int main()
{Eigen::MatrixXf m(2,2);m << 1, 2,3, 4;//get location of maximumEigen::Index maxRow, maxCol;float max = m.maxCoeff(&maxRow, &maxCol);//get location of minimumEigen::Index minRow, minCol;float min = m.minCoeff(&minRow, &minCol);std::cout << "Max: " << max <<  ", at: " <<maxRow << "," << maxCol << std::endl;std:: cout << "Min: " << min << ", at: " <<minRow << "," << minCol << std::endl;
}//输出
Max: 4, at: 1,1
Min: 1, at: 0,0

这两个函数还返回最小或最大系数的值。

三、部分约简

部分约简是可以在矩阵或数组上按列或按行操作的约简,对每列或每行应用约简操作,并返回具有相应值的列或行向量。使用 colwise() 或 rowwise() 应用部分缩减。

一个简单的例子是获取给定矩阵中每列元素的最大值,并将结果存储在行向量中:

#include <iostream>
#include <Eigen/Dense>using namespace std;
int main()
{Eigen::MatrixXf mat(2,4);mat << 1, 2, 6, 9,3, 1, 7, 2;std::cout << "Column's maximum: " << std::endl<< mat.colwise().maxCoeff() << std::endl;
}//输出
Column's maximum: 
3 2 7 9

同样的操作可以按行执行:

#include <iostream>
#include <Eigen/Dense>using namespace std;
int main()
{Eigen::MatrixXf mat(2,4);mat << 1, 2, 6, 9,3, 1, 7, 2;std::cout << "Row's maximum: " << std::endl<< mat.rowwise().maxCoeff() << std::endl;
}//输出
Row's maximum: 
9
7

注意,列操作返回一个行向量,而行操作返回一个列向量。

1. 将部分约减与其他业务相结合

也可以使用部分还原的结果进行进一步处理。这里是另一个例子,它找到一个列,其元素的和在一个矩阵中是最大的。使用按列部分约减,可以将其编码为:

#include <iostream>
#include <Eigen/Dense>int main()
{Eigen::MatrixXf mat(2,4);mat << 1, 2, 6, 9,3, 1, 7, 2;Eigen::Index   maxIndex;float maxNorm = mat.colwise().sum().maxCoeff(&maxIndex);std::cout << "Maximum sum at position " << maxIndex << std::endl;std::cout << "The corresponding vector is: " << std::endl;std::cout << mat.col( maxIndex ) << std::endl;std::cout << "And its sum is is: " << maxNorm << std::endl;
}//输出
Maximum sum at position 2
The corresponding vector is: 
6
7
And its sum is is: 13

前面的示例通过colwise()访问器对每个列应用sum()约简,获得一个大小为1x4的新矩阵。

因此,如果

m = [13216792]
然后

m.colwise().sum()=[431311]
最后应用maxCoeff()约简来获得找到最大和的列索引,在本例中是列索引2(第三列)。

四、广播

广播背后的概念类似于部分约简,不同之处在于广播构建了一个表达式,其中矢量(列或行)通过在一个方向上复制来解释为矩阵。

一个简单的例子是向矩阵中的每一列添加一个特定的列向量。

这可以通过以下方式实现:

#include <iostream>
#include <Eigen/Dense>using namespace std;
int main()
{Eigen::MatrixXf mat(2,4);Eigen::VectorXf v(2);mat << 1, 2, 6, 9,3, 1, 7, 2;v << 0,1;//add v to each column of mmat.colwise() += v;std::cout << "Broadcasting result: " << std::endl;std::cout << mat << std::endl;
}//输出
Broadcasting result: 
1 2 6 9
4 2 8 3

我们可以用两种等价的方式来解释指令mat.colwise() += v。它把向量v加到矩阵的每一列。或者,它可以被解释为将向量v重复四次以形成一个4乘2的矩阵,然后将其添加到mat中:

[13216792] +[01010101] =[14226893]。

操作符-=、+和-也可以按列和按行使用。在数组上,我们还可以使用操作符*=、/=、*和/来执行按列或按行计算的系数乘法和除法。这些运算符在矩阵上是不可用的,因为不清楚它们会做什么。如果要将矩阵mat的第0列与v(0)相乘,第1列与v(1)相乘,以此类推,则使用mat = mat * v. asdiagonal()。

重要的是要指出,要按列或按行添加的向量必须是vector类型,而不能是Matrix。如果不满足这个条件,则会得到编译时错误。这也意味着广播操作只能在使用矩阵操作时应用于Vector类型的对象。这同样适用于Array类,其中等价于VectorXf的是ArrayXf。与往常一样,不应该在同一个表达式中混合使用数组和矩阵。

要按行执行相同的操作,我们可以这样做:

#include <iostream>
#include <Eigen/Dense>using namespace std;
int main()
{Eigen::MatrixXf mat(2,4);Eigen::VectorXf v(4);mat << 1, 2, 6, 9,3, 1, 7, 2;v << 0,1,2,3;//add v to each row of mmat.rowwise() += v.transpose();std::cout << "Broadcasting result: " << std::endl;std::cout << mat << std::endl;
}//输出
Broadcasting result: 1  3  8 123  2  9  5

1. 将广播与其他业务相结合

广播还可以与其他操作相结合,例如矩阵或数组操作、缩减和部分缩减。

现在已经介绍了广播、约简和部分约简,我们可以深入到一个更高级的例子中,在矩阵m的列中找到向量v的最近邻居。欧几里德距离将在这个例子中使用,通过名为squaredNorm()的部分约简计算欧几里德距离的平方:

#include <iostream>
#include <Eigen/Dense>int main()
{Eigen::MatrixXf m(2,4);Eigen::VectorXf v(2);m << 1, 23, 6, 9,3, 11, 7, 2;v << 2,3;Eigen::Index index;// find nearest neighbour(m.colwise() - v).colwise().squaredNorm().minCoeff(&index);std::cout << "Nearest neighbour is column " << index << ":" << std::endl;std::cout << m.col(index) << std::endl;
}//输出
Nearest neighbour is column 0:
1
3

完成这项工作的线是

(m.colwise() - v).colwise().squaredNorm().minCoeff(&index);

具体解析如下:

  • m.colwise() - v是一个广播操作,从m的每一列中减去v。这个操作的结果是一个新的矩阵,其大小与矩阵m相同:

M.colwise () - v=[−10218447−1]

  • (m.colwise() - v).colwise(). squarednorm()是一个部分约简,按列计算平方范数。这个操作的结果是一个行向量,其中每个系数是m和v中每列之间的欧几里德距离的平方:
    在这里插入图片描述

  • 最后,使用minCoeff(&index)来获得m中最接近v的欧氏距离列的索引。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/718287.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

心法利器[108] | 微调与RAG的优缺点分析

心法利器 本栏目主要和大家一起讨论近期自己学习的心得和体会。具体介绍&#xff1a;仓颉专项&#xff1a;飞机大炮我都会&#xff0c;利器心法我还有。 2023年新的文章合集已经发布&#xff0c;获取方式看这里&#xff1a;又添十万字-CS的陋室2023年文章合集来袭&#xff0c;更…

修复通达OA 百度ueditor 文件上传漏动

前些日子&#xff0c;服务器阿里云监控报警&#xff0c;有文件木马文件&#xff0c;因为非常忙&#xff0c;就没及时处理&#xff0c;直接删除了木马文件了事。 谁知&#xff0c;这几天对方又上传了木马文件。好家伙&#xff0c;今天不花点时间修复下&#xff0c;你都传上瘾了…

PHP【swoole】

前言 Swoole官方文档&#xff1a;Swoole 文档 Swoole 使 PHP 开发人员可以编写高性能高并发的 TCP、UDP、Unix Socket、HTTP、 WebSocket 等服务&#xff0c;让 PHP 不再局限于 Web 领域。Swoole4 协程的成熟将 PHP 带入了前所未有的时期&#xff0c; 为性能的提升提供了独一无…

Dynamo初学尝试梳理

学习Dynamo有一段时间了&#xff0c;最近整理了下自己的笔记&#xff0c;分享一些给初学者&#xff0c;做个备忘吧&#xff01;&#xff08;PS&#xff1a;很多资料网上都能搜到&#xff0c;我仅仅是收集整理下笔记&#xff0c;分享给大家&#xff09; 今天先简单介绍下Dynamo…

展厅设计中多媒体的常用技术

1、互动投影 可以大大提高展厅和观众之间的互动体验&#xff0c;使观众不仅可以享受观看&#xff0c;还可以在轻松娱乐的氛围中娱乐的氛围中享受每个展览的背景故事和内涵&#xff0c;使整个参观过程非常轻松愉快。 2、幻影成像 可以全面展示企业产品的生产过程&#xff0c;让观…

STM32 (4) GPIO(1)

1.芯片的引脚分布 2.普通IO引脚的命名规则 3.IO复用 IO引脚身兼数职的现象叫做IO复用&#xff0c;可以使芯片拥有更多的功能&#xff0c;例如&#xff1a; PA9和PA10既可以用于GPIO的引脚&#xff0c;也可以用于串口或定时器的引脚 通用&#xff1a;CPU直接控制IO引脚的输入输…

【OpenGL编程手册-04】详细解释着色器

着色器 目录 一、说明二、着色器语言GLSL2.1 典型的着色器代码2.2 数据类型2.2.1 向量 2.3 输入与输出2.3.1 顶点着色器2.3.2 片段着色器 2.4 Uniform2.5 函数后缀含义2 .6 更多属性&#xff01; 三、我们自己的着色器类四、从文件读取五、 编译着色器练习 一、说明 在Hello T…

shopee、美客多、敦煌、国际站卖家如何掌握测评补单的核心要素

对于卖家而言&#xff0c;测评补单是一种经济高效的推广策略&#xff0c;它对于提升商品流量、优化转化率、增强关键词质量分以及加强链接权重都起到了积极的推动作用。然而&#xff0c;要实现自养号测评&#xff0c;需满足以下条件&#xff1a; 首要之务&#xff0c;建立一个稳…

jenkins插件下载失败bug

如果遇到安装jenkins插件经常失败并报以下类似错误&#xff0c;很可能是因为jenkins国外官方插件地址下载速度非常慢&#xff0c;我们可以修改为国内插件地址。 java.io.IOException: Failed to load: SCM API Plugin (scm-api 676.v886669a_199a_a_) - Jenkins (2.361.4) or h…

详细分析Java类调用Service接口失效的注意事项(附Demo)

目录 前言1. 问题所示2. 原理分析3. 解决方法 前言 试错了一小时&#xff0c;发现接口返回null&#xff01;&#xff01; 最后梳理其知识点并总结其原理 1. 问题所示 接口类如下&#xff1a; public interface IInfoService extends BaseService<Info> {错误方式一&a…

【Zookeeper】ZooKeeper的一些重要功能和作用

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 结语 我的其他博客 前言 随着分布式系统的普及和应用场景的不断增加&#xff0c;构建可靠、高效的分布式系统变得愈发重要。然…

C 嵌入式系统设计模式 19:保护调用模式

本书的原著为&#xff1a;《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》&#xff0c;讲解的是嵌入式系统设计模式&#xff0c;是一本不可多得的好书。 本系列描述我对书中内容的理解。本文章描述嵌入式并发和资源管理模式之五…

Cesium 3D Tiles 简介

3D Tiles 是大规模异构 3D 地理空间数据集&#xff08;例如点云、建筑物和摄影测量&#xff09;的开放标准。3D Tiles 基于 glTF 和其他 3D 数据类型构建&#xff0c;是一种可类似二维瓦片模式的流式传输的优化格式&#xff0c;旨在适应当今不断增长的 3D 地理空间数据集的渲染…

【数据分享】1979~2020年MSWEP降水数据集

各位同学们好&#xff0c;今天和大伙儿分享的是1979~2020年MSWEP降水数据集。如果大家有下载处理数据等方面的问题&#xff0c;您可以私信或者评论。 Beck, H. E., E. F. Wood, M. Pan, C. K. Fisher, D. G. Miralles, A. I. J. M. van Dijk, T. R. McVicar, and R. F. Adler, …

深度学习 精选笔记(7)前向传播、反向传播和计算图

学习参考&#xff1a; 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增)&#xff0c;以达到集多方教程的精华于一文的目的。 ③非常推荐上面&#xff08;学习参考&#x…

U盘无法读取?轻松掌握正确解决方法!

“为什么我的u盘插入电脑后会显示无法读取呢&#xff1f;想查看一些比较重要的文件&#xff0c;但就是无法读取U盘&#xff0c;想问问大家&#xff0c;我应该怎么操作呢&#xff1f;” U盘作为一种便捷的数据存储设备&#xff0c;广泛应用于我们的日常生活和工作中。然而&#…

独立游戏《星尘异变》UE5 C++程序开发日志2——创建并编写一个C++类

在本篇日志中&#xff0c;我们将要用一个C类来实现一个游戏内的物品&#xff0c;同时介绍UCLASS、USTRUCT、UPROPERTY的使用 一、创建一个C类 我们在UE5的"内容侧滑菜单"中&#xff0c;在右侧空白中右键选择"新建C类"&#xff0c;然后可以选择一个想要的…

Spring AOP(Aspect-Oriented Programming,面向切面编程)介绍

Spring AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面编程&#xff09;是Spring框架的一个重要模块&#xff0c;它提供了一种强大的方式来帮助开发者实现横切关注点&#xff08;cross-cutting concerns&#xff09;的模块化。横切关注点是指那些影响多个模块…

Linux设备模型(十一) - platform设备

一&#xff0c;platform device概述 在Linux2.6以后的设备驱动模型中&#xff0c;需关心总线、设备和驱动这3个实体&#xff0c;总线将设备和驱动绑定。在系统每注册一个设备的时候&#xff0c; 会寻找与之匹配的驱动&#xff1b;相反的&#xff0c;在系统每注册一个设备的时…

可让照片人物“开口说话”阿里图生视频模型EMO,高启强普法

3 月 1 日消息&#xff0c;阿里巴巴研究团队近日发布了一款名为“EMO&#xff08;Emote Portrait Alive&#xff09;”的 AI 框架&#xff0c;该框架号称可以用于“对口型”&#xff0c;只需要输入人物照片及音频&#xff0c;模型就能够让照片中的人物开口说出相关音频&#xf…