问题标签 [expression-templates]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - C ++中的模板构造函数参数基类型检查
我正在尝试使用表达式模板在 C++ 中编写一些简单的数学库。
我怎样才能让一个构造器来检查类型。我需要 3 个构造函数。
- 两者都是 MatExpression
- 第一个是 MatExpression,第二个是标量
- 第一个是标量,第二个是 MatExpression
我知道我需要使用 type_traits,但我不明白如何使用它们。
c++ - C++ 有限差分微分 - 设计
让A
:
为简单起见,请考虑以下功能:
我们想区分foo()
它的论点。因此,一阶灵敏度d foo/d a
是一个std::vector<double>
大小等于a.size()
。同样的道理也适用d foo/d b
。
一个简单的实现如下:
这很好用,但是我们有基本相同的代码 forcomputeDfDa()
和 for computeDfDb()
。
是否有任何设计模式允许拥有一个独特的(可能是模板化的)函数来自动理解要碰撞的输入?
请注意a
和b
在输入中的位置不是可交换的。
如果 的复杂性和输入的数量foo()
更大,那么简单的解决方案将生成大量无用的代码,因为我们必须为 . 的每个输入编写一个computeDfDx()
函数。x
foo()
c++ - 如何在 Fastor 或 Xtensor 中编写快速的 c++ 惰性评估代码?
我是 C++ 的新手,听说eigen、blaze、Fastor和Xtensor 等具有惰性求值和 simd 的库对于矢量化操作来说很快。
我通过以下函数测量了一些进行基本数值运算的时间:
(快速)
(Xtensor)
编译标志:
(快速)
(Xtensor)
编译器:Apple LLVM version 10.0.0 (clang-1000.11.45.5)
处理器:2.6 GHz Intel Core i5
为了比较,我还测量了用 python 编写的函数,它优化了numba.vectorize
结果(以 usec 为单位)表明
我做错什么了吗?Fastor 和 Xtensor 怎么会慢 50 倍。
如何通过使用auto
关键字来使用表达式模板和惰性求值?
谢谢你的帮助!
@Jérôme Richard 感谢您的帮助!
有趣的是,Fastor 和 Xtensor 无法忽略冗余的 for 循环。无论如何,我对每个数字运算进行了更公平的比较。
SIMD 的因子 2 也很有意义。
(快速)
(Xtensor)
(努巴)
结果显示
像这样的格式135/135
表示结果。without/with
-ffast-math
事实证明
- Fastor/Xtensor 在 , , 中的表现非常糟糕
exp
,sin
这cos
令人惊讶。 +=
Fastor/Xtensor 在,*=
,中的缩放比 Numba 差/=
。
这是 Fastor/Xtensor 的本质吗?
我将表达式修改为
它给了
发生了什么?
- 为什么 Fastor/Xtensor 无法
100*exp(u)
通过惰性评估将 for 循环表达为天真的? - 为什么随着张量大小的增加 Fastor/Xtensor 变得更快?
c++ - 如何从基本数据类型的操作中构造表达式模板?
我正在尝试从数学运算构建表达式模板,以便正确排序未排序的运算(例如 opertor+)。
原因是运算符co_await
withoperator+
似乎没有排序(导致生成器/生成任务的结果不正确)。请参阅此处C++20 协程,await_resume、return_value 和 yield_value 的意外重新排序。
如果我可以在原始数据类型上使用表达式模板,我可以使用表达式模板手动排序执行。这主要是一个练习,以确定它是否可能(而不是它是否是一个好主意)来确定是否存在解决该问题的可能解决方法。
如果不可能为原始类型重载全局运算符,那么是否有人知道如何将表达式模板注入现有的基于运算符的数学代码中。
正在进行的研究
运算符需要至少 1 个类类型才能重载:
所以,我不能为基本数据类型做这件事。因此,它将这个问题的重点转变为其他将基本数据类型表达式转换为表达式模板的方法。
根据彼得的以下评论。由于 的参数operator+(a,b)
是未排序的,这种方法将不起作用:(
c++ - 使用对临时对象的引用的表达式模板可以重复使用吗?
我正在尝试围绕表达式模板进行思考。在wikipedia article 中,给出了一个示例,其中表达式模板VecSum
存储对其两个操作数的const 引用。AVec
是一个表达式模板,它包含一个std::vector<double>
. 我将首先提出我的问题,然后对下面的示例进行完整的概述。
我可以重用使用 const 对临时对象的引用的表达式吗?如果没有,我将如何实现轻量级、可重复使用的表达式模板?
对于三个Vec
, a
,b
和c
表达式a+b+c
是类型
如果我理解正确,内部VecSum
是临时的,外部VecSum
存储对内部的 const 引用VecSum
。我相信在表达式被评估之前,内部VecSum
临时的生命周期是有保证的。正确的?这是否意味着在没有创建悬空引用的危险的情况下不能重用表达式?a+b+c
如果是这样,如何修改此示例,以便
- 表达式是可重用的
- 表达式不存储其操作数的副本(至少在不需要的情况下)?
完整代码示例
为了完整起见 - 如果同时更新了 wikipedia 文章,让我在这里重复示例代码并给出一个示例main
,我相信它会创建一个悬空引用。
编辑:
我刚刚意识到这可能是这个问题的重复。然而,这两个问题的答案非常不同,而且都很有用。
c++ - C ++ - 如何编写适用于临时且不分配的函数
我正在尝试实现一个固定大小的数组类,它将代表小尺寸的向量。我想定义典型的向量运算,例如乘以标量并与另一个向量求和。问题是我无法使用这两个代码获得相同的性能:
原因是第二个选项是在此过程中创建更多数组,而第一个选项是在原地添加。我想知道是否有一种方法可以编写一个对临时对象(r 值引用)进行操作的函数,以便在临时对象上执行求和,而无需分配额外的向量。
我当前的代码:
c++ - boost::multiprecision::cpp_dec_float - 使用“auto const”时的表达式模板令人惊讶的行为?
我花了一天的大部分时间来跟踪这个例子中的问题:
输出
似乎val对依赖项的依赖违反了 const 承诺。
将auto const更改为float_t const可以解决问题。
使用cpp_bin_float解决了这个问题
随机怀疑,禁用表达式模板可以解决问题
这发生在多个 VS 版本、mingw8.1 和 Coliru 上。
任何更熟悉内部运作的人可以解释发生了什么吗?
c++ - 现有资源编程模式的共享所有权
我知道关于现有资源的共享所有权的问题之前已经被问过很多次了,但不知何故我没能找到我的具体问题的答案。如果我错了,请纠正我。
我正在使用表达式模板库。这是一个玩具库,我想探索的一件事是通过表达式模板使用 C++ 类型对算法进行编码的优缺点。这可以用于例如惰性评估和算法微分。为此,库的用户应该能够修改现有的代码块,以便它通过运算符重载在后台使用我的库的表达式模板。
现在我不确定如何处理子表达式的所有权。例如,考虑以下函数:
此函数创建一个新的类型表达式
似乎很清楚,表示1-alpha
和alpha*something_else
应该共享所有权的表达式alpha
,因为alpha
在我们退出时将超出范围Foo
。这告诉我,我应该shared_ptr
在表达式中使用成员来子表达式。- 或者这已经是一个误解?
我的问题
我将如何编写我的二元运算表达式的构造函数Sub
和Mult
,以便表达式真正占用传递给构造函数的对象/子表达式/操作数的共享所有权 - 这样,用户必须对函数进行的更改Foo
保持不变最小?
- 我不想将对象移动到
1-alpha
中,因为alpha
在我调用alpha*something_else
. - 如果我使用
make_shared
,则两个表达式都将shared_ptr
s 存储到 的副本中alpha
,这并不是真正的共享权限。评估结果表达式意味着每个 alpha 副本都会被评估,从而产生冗余计算。 - 我可以在函数体中创建一个
shared_ptr
to ,并将这个指针按值传递给and的构造函数。但这将是图书馆用户的负担。优选地,实现细节很好地隐藏在运算符重载之后:理想情况下,用户只需对其现有函数进行最小的更改即可将其与表达式模板库一起使用。我要求太多了吗,在这里?alpha
Foo
1-alpha
alpha*something_else
Foo
编辑1:
这是一个示例,我使用第二个选项,在构造函数中创建副本(我认为......):https ://godbolt.org/z/qn4h3q
编辑2:
我找到了一个可行的解决方案,但我不愿意回答我自己的问题,因为我对我的解决方案不是 100% 满意。
如果我们想要共享作为自定义类的资源的所有权,我们可以修改(在我的情况下是这样),我们可以为该类配备一个shared_ptr
自身的副本。shared_ptr
只要没有人获得该nullptr
对象的所有权,就可以。
输出:
实时代码示例:https ://godbolt.org/z/xP45q6 。
这是使用实际表达式模板对编辑 1中给出的代码示例的改编: https ://godbolt.org/z/86YGfe 。
我对此不满意的原因是我担心我真的扼杀了我希望从 ET 获得的任何性能提升。首先,我必须将shared_ptr
s 带入操作数,这已经够糟糕的shared_ptr
了. ET 是轻量级的。
c++ - 可能的最长类型名称
表达式模板(例如)表示深度嵌套的类模板中的计算。当模板被实例化时,这可能会导致非常长的类型名称。
类型名称的长度(或者这里的正确术语是什么?)在 C++ 语言中是否受到限制?生成的损坏符号是否有一些硬性限制?
c++ - 如何将 CRTP 中的模板派生类与派生类表达式模板结合起来?
我的目标是实现一个向量类Vec
,允许高效计算算术表达式,如auto vecRes = vecA + vecB * vecC
. 这是一个已知问题,可以在维基百科上找到使用奇怪重复模板模式 (CRTP) 的解决方案。
我首先采用硬编码向量元素类型的实现,double
包括用于添加的派生类,
可以正常工作。
然而,在我用模板替换的方法中double
,基类得到一个模板模板参数Vec
,当然,plain 变成了模板化的。
问题出现在VecSum
类定义中,该类定义已经是硬编码double
情况下的模板类,现在不被识别为VecExn
.
我该如何解决这个问题?