はじめに
Pythonのsparse matrixをどうしてもC++のvector配列にして使いたいということで僕が行った作業をメモしておく。
全体の流れ
1.[Python]疎行列要素の出力
2.[C++]読み込み、代入
[Python]疎行列要素の出力
scipyで作成した疎行列(非ゼロ要素のみを格納している行列)をCSVファイルに出力。
from scipy import io
io.mmwrite('AVWeight',author_venue)
with open('AVWeight.mtx','r') as t:
lines = t.read().split('\n')
lines = lines2[3:]
import os
import csv
with open('AVWeight.csv', 'wt') as f:
writer = csv.writer(f)
for l in lines:
dat = l.split()
if len(dat) == 3:
# 行列位置を0オリジンに
dat[0] = int(dat[0]) - 1
dat[1] = int(dat[1]) - 1
writer.writerow(dat)
$ cat AVWeight.csv
0,15,2.300000000000000e+01
0,16,4.900000000000000e+01
0,17,1.000000000000000e+01
:
5637,18,1.000000000000000e+00
5638,5,5.000000000000000e+00
5638,6,1.000000000000000e+00
あとはこのCSVファイルのインデックス、値を読み込み代入。
2.[C++]読み込み、代入
カンマを取り除く
C++の読み込み的にカンマがないほうがやりやすかったため、trコマンドを利用してカンマをスペースに
$ cat AVWeight.csv | tr ',' ' ' > AVWeight.csv
$ cat AVWeight.csv
0 15 2.300000000000000e+01
0 16 4.900000000000000e+01
017 1.000000000000000e+01
:
5637 18 1.000000000000000e+00
5638 5 5.000000000000000e+00
5638 6 1.000000000000000e+00
代入
getlineとsscanfを使ってインデックス、値を読み込み代入する。
ここでは二次元vector配列に代入する例を示す。
#include <string>
#include <iostream>
#include <vectro>
#include <fstream>
using namespace std;
int row,col;
int val;
char c[10];
ifstream ifs("AVWeight.csv");
while(getline(ifs,str)){
str.copy(c, 10);
sscanf(c, "%d %d %d", &row, &col, &val);
W[col][row] = val;
}
getline で行を読み取り
sscanfでスペースで区切られた数値を読み込む。
まとめ
今回は既存のプログラムを利用したいため、vector配列に入れることを目標にした。
しかしC++でもmap型等を使って疎行列を作るほうが好ましい。(結果論)