问题标签 [valarray]
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++ - valarray 就地操作给出不同的结果作为临时分配
以下程序:
输出:
正确答案是2 2
( <1 1> + <1 1> * 1 = <2 2>
。为什么内联版本输出不同的东西?
万一这很重要,我正在这样编译:
的输出g++ -v
是:
c++11 - 在 std::valarray 上使用 .sum() 和 +=
我正在使用该类型std::valarray<std::valarray<double>>
并希望明智地对每个包含的 valarrays 元素求和,以留下std::valarray<double>
.
std::valarray<T>
C++ 文档指出,只要为类型 T 定义了运算符,就可以应用运算符 .sum() +=
。我下面的代码 (method1) 尝试将此应用于std::valarray<std::valarray<double>>
,但结果似乎是无稽之谈。
但是,如果我使用运算符(method2)手动执行此操作+=
,我会得到我想要的结果。但是method2有效的事实似乎意味着运算符+=
是为type定义的std::valarray<double>
,因此method1是使用.sum()定义的。应该管用。我真的无法理解这里发生了什么......
我的代码:
我的输出:
c++ - 避免在 C++ 向量或 valarray 中初始化
在我的项目中,我必须从 CUDA (GPU) 设备(从视频卡的内存到 std::valarray)复制 std::valarray(或 std::vector)中的大量数值数据。
所以我需要尽可能快地调整这些数据结构的大小,但是当我调用成员方法 vector::resize 时,它会使用循环将数组的所有元素初始化为默认值。
显然我不需要这个初始化,因为我必须从 GPU 复制数据并且所有旧数据都被覆盖。并且初始化需要一些时间;所以我失去了表现。
为了处理我需要分配内存的数据;由方法 resize() 生成。
我非常肮脏和错误的解决方案是使用方法vector::reserve(),但是我失去了vector的所有特征;如果我调整数据大小,则将其替换为默认值。
因此,如果您知道,有一种策略可以避免这种预初始化为默认值(在 valarray 或向量中)。
表演示例:
输出:
注意:替换 std::allocator 不起作用,因为循环是由 resize() 调用的。
c++ - 修改 std::valarray 的元素是否安全同时?
如果我理解正确的话,从 C++11 开始,只要容器本身不作为操作的一部分进行修改,就可以安全地同时调用容器的 const 成员函数并修改容器的元素(从例如cppreference.com中有关线程安全的表)。由于 std::valarray 未列在(草案)标准的容器部分中,我不确定线程安全是否也适用于它。换句话说,
- 同时从 std::valarray 读取是否安全(特别是通过将 operator[] 与切片一起使用)?
- 如果对 T 的操作是安全的,那么同时修改 std::valarray<T> 的元素是否安全?
我想将 std::valarray 用于将使用多个线程填充的多维数字数组。
c++ - glibcxx STL 在 std::valarray::sum() 的实现中是否不正确?
当我遇到我认为编译器的 STL 实现中的错误时,我正在玩弄 valarrays 。这是我可以制作的最小示例:
这将输出:
您可以在coliru编译并运行它
为什么我认为这是一个错误?因为根据标准(26.6.2.8)
T sum() 常量;
此函数只能为可以应用 operator+= 的类型 T 实例化。此函数返回数组中所有元素的总和。如果数组的长度为 0,则行为未定义。如果数组的长度为 1,则 sum() 返回元素 0 的值。否则,通过将 operator+= 应用于数组元素的副本和数组的所有其他元素以未指定的顺序计算返回值。
valarray 确实有一个+= 运算符
所以我希望X.sum()
具有与 相同的值X[0]
。但显然不是这样,因为它的大小是 0 而不是 1。
我查看了它的实现sum()
并将其追溯到这段代码:
我们知道问题出在哪里。代码将总和累加到__r
中,但不是__r
使用 valarray 中的第一项进行初始化,而是默认构造。valarray 的默认构造函数创建一个大小为 0 的数组。所以最终结果仍然是一个大小为 0 的 valarray。
我对标准的理解是否有效(并且 glibcxx STL 有错误)?还是我应该纠正?
作为记录,我在cygwin下使用g ++ 7.3.0,但它是在coliru上复制的,它可能没有在cygwin下运行......
c++ - 具有嵌套表达式模板的 C++ 类
我想定义一个Nested
在此处调用的类,它将包含两个或多个(此处为一个)数据成员,这些数据成员支持使用表达式模板的算术运算,例如std::valarray
. 对于这个类本身,我定义了它自己的表达式模板,我想将算术运算“转发”给成员。
下面给出了一个最小(非)工作示例:
这个程序的输出是
即,将表达式向下转发给成员似乎无法提供直接从使用 valarray 获得的预期结果。
任何帮助在这里表示赞赏。
c++ - 为什么 valarray 在 Visual Studio 2015 上这么慢?
为了加快库中的计算速度,我决定使用std::valarray
该类。文档说:
std::valarray 和辅助类被定义为没有某些形式的别名,因此允许对这些类的操作进行优化,类似于 C 编程语言中关键字限制的效果。此外,允许接受 valarray 参数的函数和运算符返回代理对象,以使编译器可以优化表达式,例如 v1 = a * v2 + v3; 作为执行 v1[i] = a * v2[i] + v3[i] 的单个循环;避免任何临时或多次通行证。
这正是我所需要的。当我使用 g++ 编译器时,它按照文档中的描述工作。我开发了一个简单的示例来测试std::valarray
性能:
在 g++ 上,我得到:
看起来所有的操作d = a + b * c;
真的都放在了一个循环中,这样在保持性能的同时简化了代码。但是,当我使用 Visual Studio 2015 时,这不起作用。对于相同的代码,我得到:
差值几乎是四倍;没有优化!为什么std::valarray
在 Visual Studio 2015 上无法按需要工作?我做的一切都正确吗?如何在不放弃的情况下解决问题std::valarray
?
c++ - std::valarray 的 operator* 有什么问题?
考虑以下 MCVE,其中我有两个值数组,其中w
是两次v
(在此处尝试):
此示例无法在最后一个循环中使用 clang 和 gcc 编译(此处为 gcc 输出):
问题的根源似乎是 decuced 类型v * 2
(我假设因为明确写下类型有效,所以似乎正在发生一些隐式转换)。
查看参考说明,似乎operator*
返回的内容可能与std::valarray<T>
. 我不明白这样做的原因,但更令人费解的是,这似乎也适用于operator*=
,除了我的auto
作业在这里有效。我希望 和 的返回值operator*=
在operator*
这里是相同的(增量参考)。
所以我的问题是:
- 这是一个实施问题/错误吗?还是我错过了什么?
- 参考说明背后的基本原理是什么(例如,为什么操作员可以返回可能不适用于
std::begin
/的不同内容std::end
)?
(注意:我标记了这个问题 c++11,但它似乎也适用于 17 及以下的所有版本)
c++ - 它是在 gcc 中实现 std::valarray 的错误吗?
我尝试了以下程序
并收到一条错误消息,表明在此语句中隐式使用begin
了适当的函数v3
找不到。
所以我尝试了以下代码
并得到了结果
但是当这句话
改为
那么输出是
foroperator *
声明std::valarray<int>
如下
那么这是实现的错误std::valarray<int>
吗?