2

いくつかのマトリックスを解析して抽出するコードがいくつかあります。これらのマトリックスは、特定のタグに関連付けられています。

私がやりたいことは、将来のアクセスのために、これらの行列を関連するタグとともに保存することです。基本的に、更新されるファイル/構造/配列/何かを作成したいのですが、同じ実行で必要に応じて行列演算を呼び出すこともできます。さらに、次にプログラムを実行したときに、これまでに再コーディングした配列とタグを呼び出すことができるはずです。最後に、行列とタグのデータベースが必要です。

誰かが私を正しい方向に向けて始めることができますか?

いくつかの疑似コードをいただければ幸いです。

4

2 に答える 2

1

私があなたの質問に答えているかどうかはわかりませんが、ベクトル、行列、その他のランク配列 (画像も) を格納するためのファイルを読み書きするための C API を探している場合は、FITS ファイル形式を使用できます。保存された情報にタグを付けたり、他のことを行うことができます。ここで CFITSIO ライブラリとドキュメントを見つけることができます: http://heasarc.gsfc.nasa.gov/fitsio/ (はい、NASA のもの ;-) )

上記のページから:

CFITSIO is a library of C and Fortran subroutines for reading and 
writing data files in FITS (Flexible Image Transport System) data format. 
CFITSIO provides simple high-level routines for reading and writing FITS files 
that insulate the programmer from the internal complexities of the FITS format. 
CFITSIO also provides many advanced features for manipulating and filtering the
information in FITS files.

さまざまなデータ型の要素を含む多次元配列 (ヒストグラム、画像など) を格納するために FITS を使用します。このライブラリは古くからあり、特定のフィルターでファイルを開くことでベクトル/行列を選択することもできます。複雑な I/O、エンコードまたはデコード ルーチンについて心配する必要はありません。

于 2012-08-20T15:42:54.883 に答える
0

現在行列を (メモリ内に) 格納している構造のタイプは関連しています。

たとえば、次のような構造を使用して二次元行列を格納できます。

struct {
    size_t w;
    size_t h;
    double **values;
    size_t n;
    char **tags;
}

そして、次のようにディスクに書き込みます。

fwrite(&(m->w), sizeof(size_t), 1, fp);
fwrite(&(m->h), sizeof(size_t), 1, fp);
for (y = 0; y < h; y++)
    fwrite(m->values[y], sizeof(double), m->w, fp);
fwrite(&(m->n), sizeof(size_t), 1, fp);
for (y = 0; y < m->n; y++)
{
    size_t len = strlen(m->tags[y]);
    fwrite(&len, sizeof(size_t), 1, fp);
    fwrite(m->tags[y], sizeof(char), len, fp);
}

fwrites を freads に置き換えて再読み込みします。

if (1 != fread(&(m->w), sizeof(size_t), 1, fp))
    // ERROR
if (1 != fread(&(m->h), sizeof(size_t), 1, fp))
    // ERROR
if (NULL == (m->values = malloc(sizeof(double *) * m->h)))
    // ERROR: OUT OF MEMORY
for (y = 0; y < h; y++)
{
    if (NULL == (m->values[y] = malloc(sizeof(double) * m->w)))
        // OOM
    if (m->w != fread(m->values[y], sizeof(double), m->w, fp))
        // File truncated error
}
if (1 != fread(&(m->n), sizeof(size_t), 1, fp))
    // Truncated
for (y = 0; y < m->n; y++)
{
    size_t len;
    fread(&len, sizeof(size_t), 1, fp);
    if (NULL == (m->tags[y] = malloc(len + 1)))
        // OOM
    if (len != fread(m->tags[y], sizeof(char), len, fp))
        // Truncated
    m->tags[y][len] = 0x0; // C strings must be zero-terminated
}

...しかし、これは二次元行列のみをカバーし、各行列を独自のファイルに保存する必要があります。

もちろん、システムをさらに複雑にして、単一の「データベース」にヘッダー、多数のマトリックスなどを保存し、各マトリックスを次々に保存することもできます。

おそらく、長期的には、CLaudixが提案したFITS標準が行列を文字列にシリアライズできるかどうかを確認する方がよいでしょう。そうであれば、それらの文字列を実際のデータベース (PostgreSQL、MySQL、または SQLite3 でさえも) に格納できるため、独立したサーバーを用意する必要はありません)。これにより、タグが変更されるたびに全体を書き直す必要がなくなり、メモリ オブジェクトから SQL 化されたフィールド値に、またはその逆に変換する 2 つの FITS ラップ関数を作成するという代償を払って、コードをより保守しやすくすることができます。

FITS 形式で変数タグを行列やベクトルに関連付けることができない場合、FITS を直接使用すると問題が発生する可能性があります。

文字列オブジェクトへの書き込みに FITS を適合させることができない場合でも、上記のコードを使用して、行列オブジェクトから文字列へのラッパーを書き込むことができる場合があります (たとえば、結果のバッファーを base64 エンコードすることにより)。マトリックスを文字列オブジェクトとして取得したら、そこからは単なる SQL です。

INSERT INTO MatrixTable (matrixId, matrixEncoding) VALUES (...);
INSERT INTO MatrixTags (matrixId, tagName, tagValue) VALUES (2418, 'Taken', '2012-08-20 at noon');
于 2012-08-20T16:00:53.687 に答える