我有兴趣将矩阵的 subview 传递给其他对象(或函数),以便对象/函数可以修改列/矩阵的定义段。
我目前正在使用 armadillo 库,我可以获得并使用对单个矩阵条目的引用(下面的函数 f)。我正在寻找一种有效的方法来传递对 subview 的引用。我认为下面的函数 h 的代码实现了这个目标,但我不确定。我的主要问题是:假设我想要一个存储在类中的引用(不仅仅是在 h 中的函数中使用),有没有办法改进函数 h下面?
三个不太重要的后续问题是:1) 这可以在编写接受 arma::Col 类型参数的函数而不是指定 subview 时完成吗? 2)如果没有,是否有另一个 C++ 矩阵库允许这种事情而不明确地说明 subview ? (我查看了 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
最佳答案
我没有用过 Armadillo ,所以我不是最合适的人选,但我认为这是一个更普遍的 C++ 问题,另外,目前还没有答案:-)
所以:
Assuming I want a reference to store in a class (not just use in a function as in h), is there a way to improve on function h below?
我认为您混淆了一些与矩阵和 View 无关的基本 C++ 概念。引用本质上指向一个对象,因此您应该首先担心存储对象本身,然后才是引用。
存在对对象的引用的事实可能是将对象的生命周期延长到引用的生命周期的原因,但情况并非总是如此。参见 this answer回答我之前的一个问题,以获得一些解释和规则。
因此,最好的确定方法是先存储对象。我打赌 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)。我不知道 Armadillo 的细节,但我敢打赌 A.col(1) 只包含对 A 的引用和一个整数(我猜 size_t),值为 1。它是一个轻量级对象,旨在充当一种通用的引用。不要害怕存储它。只是为了练习,试试
auto col = A.col(2);
col = 153.0;
任何人都看到它与 A.col(2) = 153.0; 或 g(A.col(2), 153.0); 相同。此时,没有什么能阻止您将 col 存储在任何地方供以后使用。
将 View 存储在某个地方,然后您需要将它传递给一个函数。如果 View 只用于读取,则编写以下两个重载:
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 是任何类型的数组或 View ,Y 是与 X 的元素类型兼容(可转换为/自)的任何类型。如果不是,编译器将对其进行诊断。如果 Armadillo 支持,你甚至可以有一个数组 Y 和一个数组(或 View )的数组 X。
此外,您可以泛化到 n 元函数,而不必担心无限的 const/非 const 重载组合。
关于c++ - 如何将对子矩阵 View 的持久引用作为函数参数传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22716671/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/