2016-10-04 134 views
0

構建可執行特定任務的可變參數函數時遇到了問題。對於我的特定示例,我使用的是2×2矩陣,但您可以想象我的問題可以概括爲許多數據類型。另外,就我的例子而言,「眼睛」是2x2單位矩陣。Kronecker產品的可變參數函數

好了,我想建立一個可變參數的函數f的輸入端可能是(以得到3個實施例):

f(Y, 2, Z, 5, X, 3) 
f(X, 4) 
f(X, 2, Y, 1) 

,其中X,Y,Z是矩陣,和數量是正整數。它應該返回下面的僞代碼克羅內克產品,分別爲:

KroneckerProduct(eye, Y, X, eye, Z) 

KroneckerProduct(eye, eye, eye, X) 

KroneckerProduct(Y, X) 

所以基本上它在通過下面的基質中的int指定的克羅內克積位置應用矩陣,並填寫身份之間的矩陣英寸

由於我對variadic函數沒有經驗,所以我沒有太多的瞭解它。我最大的問題是越來越可變參數函數的「遞歸」一步我需要什麼(見末註釋):

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

這是完全一樣的解決方法是「正常」的遞歸函數:) – Rakete1111

+0

你是在暗示聲明matrixList後的東西要放在另一個函數g(標準::矢量&matrixList,ARGS ... ),並在g內進行遞歸?就我所瞭解的可變參數模板而言,由於g在參數前面只有一個參數...,參數是不是隻能一次一個解壓縮?我需要他們一次解包兩個,以便讓作業變得有意義。 – user2520385

回答

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...); 
} 
+0

謝謝,這讓它工作,但我仍然不完全瞭解如何轉發工作...我需要閱讀它。我會發布完成的代碼片段。 – user2520385

1

建立關Rakete1111的建議,這是代碼,我想要它工作。它生成k-量子位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; 
}