ワークシートから行列に変換

分析またはグラフ作成時に、ワークシートから行列に変換またはその反対の操作をして、データを再構成する必要があるかもしれません。このページはワークシートを行列に変換する時のサンプルと情報を紹介します。なお、反対の操作をする際は行列をワークシートに変換するを参照してください。

ワークシートグリッディング

  1. コマンドウィンドウで次のコマンドを実行し、nag_utils.cファイルをコンパイルし、現在のワークスペースにそれを追加します。
    Run.LoadOC(Originlab\nag_utils.c, 16);
  2. Origin Cファイルにヘッダファイルを含めます。
    #include <wks2mat.h>
    #include <Nag_utils.h>
  3. アクティブなワークシートのXYZ列からXYZデータを取得します。
    // XYZ列からXYZデータ範囲を取得
    XYZRange rng;
    rng.Add(wks, 0, "X");
    rng.Add(wks, 1, "Y");
    rng.Add(wks, 2, "Z");
     
    // データ範囲オブジェクトからベクターにXYZデータを取得
    vector vX, vY, vZ;
    rng.GetData(vZ, vY, vX);
  4. 元のデータ型を調査します。例:XY等間隔配置、疎データ
    UINT nVar;
    double xmin, xstep, xmax, ymin, ystep, ymax;
    int nSize = vX.GetSize();
    int nMethod = ocmath_xyz_examine_data(nSize, vX, vY, vZ, 1.0e-8, 1.0e-8, 
    &nVar, &xmin, &xstep, &xmax, &ymin, &ystep, &ymax);
  5. 結果の行列ウィンドウに対する行と列の数を計算します。
    int nRows = 10, nCols = 10;
    if( 0 == nMethod || 1 == nMethod ) // XY等間隔または疎データ
    {
            double dGap = 1.5;
            if( !is_equal(ystep, 0) )
                    nRows = abs(ymax - ymin)/ystep + dGap; 
     
            if( !is_equal(xstep, 0) )
                    nCols = abs(xmax - xmin)/xstep + dGap;
    }
  6. 結果の行列ウィンドウを準備します。
    // グリッディング結果を配置する行列ウィンドウを準備
    MatrixPage mp;
    mp.Create("origin"); // 行列ウィンドウを作成
    MatrixLayer ml = mp.Layers(0); // 第1行列シートを取得
    MatrixObject mo(ml, 0); // 第1行列オブジェクトを取得
     
    mo.SetXY(xmin, ymin, xmax, ymax); // XとYの開始/終了値をセット   
    mo.SetSize(nRows, nCols); // 行と列の数をセット
  7. 異なるメソッドの種類でXYZグリッディングを行います。
    matrix& mat = mo.GetDataObject(); // 行列オブジェクトからデータオブジェクトを取得
    
    int iRet;
    switch(nMethod) 
    {
    case 0: // XY等間隔
    	iRet = ocmath_convert_regular_xyz_to_matrix(nSize, vX, vY, vZ, 
    		mat, xmin, xstep, nCols, ymin, ystep, nRows);
    	printf("--- %d: regular conversion ---\n", iRet);	
    	break;
    
    case 1: // 疎データ
    	iRet = ocmath_convert_sparse_xyz_to_matrix(nSize, vX, vY, vZ, 
    		mat, xmin, xstep, nCols, ymin, ystep, nRows);
    	printf("--- %d: sparse conversion ---\n", iRet);		
    	break;
    
    case 2: // ランダム(Renka Cline) 
    	vector vxGrid(nRows*nCols), vyGrid(nRows*nCols);
    	iRet = ocmath_mat_to_regular_xyz(NULL, nRows, nCols, xmin, 
    		xmax, ymin, ymax, vxGrid, vyGrid);
    	if( iRet >= 0 )
    	{
    		iRet = xyz_gridding_nag(vX, vY, vZ, vxGrid, vyGrid, mat);
    	}
    	printf("--- %d: random conversion ---\n", iRet);
    	break;
    
    default: // エラー
    	printf("--- Error: Other method type ---\n");
    }

ワークシートから行列へ

ワークシートに含まれるデータは、一連の関数を使って行列に変換することができます。

行列のようなワークシートデータを直接行列に変換するために、ワークシートの最初の列と行にXまたはYの値を入力します。しかし、行列の座標は等間隔でなければならいので、元のワークシートに等間隔なX/Y値が入力されている必要があります。メソッド CopyFromWks を直接使用するか、単に行列にXYZデータ範囲を付けます。

次のサンプルはワークシートから直接変換する方法を示しています。

// 方法 1: CopyFromWksを使用
Worksheet wks = Project.ActiveLayer();
if(!wks) 
{
	return;
}
MatrixPage matPg;
matPg.Create("Origin");
MatrixLayer matLy = matPg.Layers(0);
Matrix mat(matLy);

matrix<double> mat1;
if(!mat1.CopyFromWks(wks, 1, -1, 1, -1)) 
{
	out_str("Error: CopyFromWks failed!");
	return;
}
mat = mat1;


// 方法 2: 行列オブジェクトに付加
Worksheet wks = Project.ActiveLayer();
if(!wks) 
{
	return;
}
int nCols = wks.GetNumCols();
int nRows = wks.GetNumRows();
DataRange dr;
dr.Add("X", wks, 0, 1, 0, nCols - 1);  // 最初のセルを除いた最初の行
dr.Add("Y", wks, 1, 0, nRows - 1, 0);  //最初のセルを除いた最初の列
dr.Add("Z", wks, 1, 1, nRows - 1, nCols - 1);
MatrixPage matPg;
matPg.Create("Origin");
MatrixLayer matLy = matPg.Layers(0);
MatrixObject mo = matLy.MatrixObjects(0);
MatrixObject moTmp;
moTmp.Attach(dr);
matrixbase &matTmp = moTmp.GetDataObject();
matrixbase &mat = mo.GetDataObject();
mat = matTmp;
moTmp.Detach();

ワークシートデータがXYZ列形式で構成されているとき、グリッディング法を使ってこのようなデータを行列に変換します。多くのグリッディング法が利用でき、これにより元のデータを補間し、指定した次数での等間隔なXYで、値の配列を生成します。

次のサンプルでは、Renka-Clineの手法によりXYZデータを変換します。

// Renka-Clineグリッディング手法によりワークシートデータを20*20の行列に変換
Worksheet wks = Project.ActiveLayer();
if(!wks) 
{
	return;
}
Dataset dsX(wks, 0);
Dataset dsY(wks, 1);
Dataset dsZ(wks, 2);
int nPoints = dsX.GetSize();
vector vX = dsX;
vector vY = dsY;
vector vZ = dsZ;

ocmath_RenkaCline_Struct comm;
ocmath_renka_cline_interpolation(nPoints, vX, vY, vZ, &comm);


//グリッディングのXとYをセット
double dXMin, dXMax, dYMin, dYMax;
vX.GetMinMax(dXMin, dXMax);
vY.GetMinMax(dYMin, dYMax);

//Kriging アルゴリズムを使用したランダム行列変換
int nRows = 20;
int nCols = 20;
matrix mZ(nRows, nCols);
vector vEvalX(nRows * nCols);
vector vEvalY(nRows * nCols);
ocmath_mat_to_regular_xyz(NULL, nRows, nCols, dXMin, dXMax, dYMin, dYMax, vEvalX, vEvalY, NULL, true);
ocmath_renka_cline_eval(&comm, nRows * nCols, vEvalX, vEvalY, mZ);    
ocmath_renka_cline_struct_free(&comm);

// 行列を作成して結果を格納
MatrixLayer    mResultLayer;
mResultLayer.Create();
Matrix    matResult(mResultLayer);
matResult = mZ;
MatrixObject mo = mResultLayer.MatrixObjects(0);
mo.SetXY(dXMin, dYMin, dXMax, dYMax);//行列を作成して結果を格納