如何将对子矩阵视图的持久引用作为函数参数传递?

克里斯托弗

我对将矩阵的子视图传递给其他对象(或函数)感兴趣,以便该对象/函数可以修改列/矩阵的已定义段。

我目前正在使用armadillo库,并且可以获取和使用对单个矩阵条目的引用(f下面的函数)。我正在寻找一种有效的方法来传递对子视图的引用。我认为h下面的函数代码可以实现此目标,但是我不确定。我的主要问题是:假设我想将一个引用存储在一个类中(而不仅仅是在函数中使用h),是否可以改进h下面的函数

三个不太重要的跟进问题是:1)在编写接受arma :: Col参数类型的函数而不是指定子视图时是否可以完成此操作?2)如果没有,是否还有另一个C ++矩阵库将允许这种事情而无需明确地涉及子视图?(我查看了Eigen及其.blocks语法,但我认为问题是相同的);和3)我对传递给函数的引用g在表达式完成后消失了吗?

#include <iostream>
#include <armadillo>

void f(double & x) { x = 5.33392;}
void g(arma::subview_col<double> && x, double y) { x(0) = y; }
void h(arma::subview_col<double>    x, double y) { x(0) = y; }

int main () {
  arma::Mat<double> A = arma::randu<arma::Mat<double> >(3,3);
  A(1,1) = 3;
  A.submat(0,0,1,1) = arma::zeros<arma::Mat<double> >(2,2);
  std::cout << A << std::endl;

  double & k = A(1,1);
  std::cout << k << std::endl;

  f(k);         // THis is ok, works.


  g(A.col(2), 153.0);    // It compiles and the value changes...
  // A.col(2) gets destroyed when the above expression is done
  // evaluating... so not a reference one can keep around.

  std::cout << A << std::endl;

  // Here the subview is passed by value, and it keeps its reference to 
  h(A.col(1), 153.0);

  std::cout << A << std::endl;

  return 0;
}

为我编译:

 g++ -o submatrix_views -std=c++11 ./submatrix_views.cpp
IAVR

我还没有用过犰狳,所以我不是最适合回答的问题,但是我认为这是一个更一般的C ++问题,此外,还没有答案:-)

所以:

假设我想将引用存储在类中(不仅像在h中那样在函数中使用),有没有办法改善下面的函数h?

我认为您混淆了一些与矩阵和视图无关的C ++基本概念。引用本质上指向一个对象,因此您应该首先担心存储对象本身,然后是引用。

存在对对象的引用这一事实可能是将对象的生存期延长到引用的生存期的原因,但这并非总是如此。有关某些解释和规则,请参见我先前的问题之一的答案

因此,确定的最佳方法是首先存储对象。我敢打赌A.col(1)A.submat(0,0,1,1)它们是临时对象,您可以通过以下任何一种方式将它们存储在变量中:

arma::subview_col<double> col = A.col(1);
decltype(A.col(1)) col = A.col(1);
auto col = A.col(1);

如果知道类型,则可以只使用一个这样的变量作为类的成员(如果不知道,请使用decltype)。我不知道犰狳的详细信息,但是我敢打赌,它所A.col(1)包含的不仅仅是引用Asize_tvalue的整数(我想是1它是一个轻量级的对象,旨在充当一种通用的引用不要害怕存储它。只是练习,尝试

auto col = A.col(2);
col = 153.0;

任何人都看到它与A.col(2) = 153.0;相同g(A.col(2), 153.0);在这一点上,没有什么可以阻止您将其存储col在任何地方以备后用。

将视图存储在某个地方,然后需要将其传递给函数。如果该视图仅用于读取,请编写以下两个重载:

void read(      arma::subview_col<double> && x, double& y) { y = x(0); }
void read(const arma::subview_col<double> &  x, double& y) { y = x(0); }

如果它也用于书写,则:

void write(arma::subview_col<double> && x, double y) { x(0) = y; }
void write(arma::subview_col<double> &  x, double y) { x(0) = y; }

我推荐的通用解决方案如下:

template <typename X> void read (X&& x, double& y) { y = std::forward<X>(x)(0); }
template <typename X> void write(X&& x, double  y) { std::forward<X>(x)(0) = y; }

或者,甚至更通用:

template <typename X, typename Y>
void read (X&& x, Y&& y) { std::forward<Y>(y) = std::forward<X>(x)(0); }

template <typename X, typename Y>
void write(X&& x, Y&& y) { std::forward<X>(x)(0) = std::forward<Y>(y); }

现在X并且Y可以是任何东西,或更确切地说,可以X是任何类型的数组或视图,并且Y是与元素类型兼容(可转换为或从转换为)的任何类型X如果不是,编译器将对其进行诊断。如果armadillo支持,您甚至可以拥有一个数组Y和一个数组(或视图)X

另外,您可以泛化为n元函数,而不必担心无限const/非const重载组合。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在C#中将对STATIC方法的引用作为函数参数传递?

将对向量的引用作为参数传递

如何将 ng-model 的引用作为函数的参数传递?

如何弱引用作为参数传递的函数

如何将对象作为参数传递给函数?

如何将对象作为参数传递给函数

如何将对象属性作为函数参数传递?

如何将对象/类作为函数的参数传递

如何将对象的属性作为参数传递给函数

将函数引用作为参数传递

将对基类的引用作为模板参数传递

perl将对象方法引用作为函数的参数

如何将对象作为参数传递?

C++:将引用作为参数传递,但该函数不接受引用作为参数

如何将泛型方法引用作为参数传递?

如何将对象属性作为函数参数传递给lambda函数?

将类引用作为构造函数参数传递

Elixir将模块的引用作为函数参数传递

将引用作为函数参数传递不起作用

如何将对象作为默认参数传递给ecmascript中的函数?

如何将对象的函数名称作为参数传递

如何将对象列表作为函数中的参数传递,然后使用对象的属性C#

我们如何将对象作为参数传递给对象值中的函数名?

如何将指针传递给在 C++ 中作为引用传递参数的函数

在F#中,是否可以将对可变的默认值的引用作为参数传递?

如何将对象数组作为参数传递给模板

如何将对象作为BlackBerry SOAP请求参数传递

如何将对象作为参数传递给弹簧方面?

如何将对象属性作为参数传递?(JavaScript)