我在构建执行特定任务的可变参数函数时遇到了问题。对于我的特定示例,我使用的是2x2矩阵,但您可以想象我的问题可以归结为许多数据类型。另外,对于我的例子,“眼睛”是2x2单位矩阵。
好的,所以我想构建一个可变参数f,其输入可能是(给出3个例子):
f(Y, 2, Z, 5, X, 3)
f(X, 4)
f(X, 2, Y, 1)
其中X,Y,Z是矩阵,数字是正整数。它应该分别返回以下伪代码kronecker产品:
KroneckerProduct(eye, Y, X, eye, Z)
KroneckerProduct(eye, eye, eye, X)
KroneckerProduct(Y, X)
所以基本上它在矩阵后面的int指定的KroneckerProduct中的位置应用矩阵,并填充其间的标识矩阵。
由于我对可变功能的经验不足,我对此并不了解。我最大的问题是使用可变函数的“递归”步骤来完成我需要的操作(见最后的评论):
template<typename M, typename I, typename... Args>
arma::mat f(M matrix, I position, Args... args)
{
std::vector<arma::mat> matrixList;
while(position > matrixList.size())
{
matrixList.push_back(eye<arma::mat>(2,2));
}
matrixList(position-1) = matrix;
//Up until here, it's satisfied the first pair of arguments.
//However, if I call f(args...) now, it'll just re-initialize matrixList
}
我缺少一种解决方法吗?
答案 0 :(得分:2)
我不知道你将如何计算回报值(我还没有理解那种数学),但是如果你从最终的matrixList
计算它,你可以围绕函数做一个包装:
template<typename... Args>
arma::mat calculateSomething(Args&&... args) {
std::vector<arma::mat> list;
f(list, std::forward<Args...>(args...)); //First argument for recursion
//Calculate return value
return return_value;
};
f
看起来像这样:
//Default case with just 1 argument
void f(std::vector<arma::mat>&) {}
template<typename M, typename I, typename... Ts>
void f(std::vector<arma::mat>& matrixList, M matrix, I position, Ts... args)
{
while(position > matrixList.size())
{
matrixList.push_back(eye<arma::mat>(2,2));
}
//This is not valid syntax, no idea what you are trying to do here
//matrixList(position-1) = matrix;
//recursive call
f(matrixList, args...);
}
答案 1 :(得分:1)
建立Rakete1111的建议,这是我打算使用的代码。它会生成k-qubit Heisenberg interactions。
#include <iostream>
#include <armadillo>
const arma::cx_mat eye = "(1,0) (0,0); (0,0) (1,0)";
const arma::cx_mat sx = "(0,0) (1,0); (1,0) (0,0)";
const arma::cx_mat sy = "(0,0) (0,-1); (0,1) (0,0)";
const arma::cx_mat sz = "(1,0) (0,0); (0,0) (-1,0)";
void ArgsToMatrixList(std::vector<arma::cx_mat>&) {}
template<typename M, typename I, typename... Ts>
void ArgsToMatrixList(std::vector<arma::cx_mat>& matrixList, M matrix, I position, Ts... args)
{
while(position > matrixList.size())
{
matrixList.push_back(eye);
}
matrixList[position - 1] = matrix;
ArgsToMatrixList(matrixList, args...);
}
template<typename... Args>
arma::cx_mat J(Args&&... args)
{
std::vector<arma::cx_mat> list;
ArgsToMatrixList(list, std::forward<Args>(args)...); //First argument for recursion
//Calculate return value
arma::cx_mat return_value = list.front();
for(int i = 1; i < list.size(); ++i)
{
return_value = arma::kron(return_value, list[i]);
}
return return_value;
}
int main(int argc, const char * argv[]) {
arma::cx_mat example = J(sx, 1, sy, 2, sz, 3);
std::cout << example << std::endl;
return 0;
}