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);
}

并通过用 freads 替换 fwrites 来重新读取:

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,这样您就不必拥有独立的服务器)。这也将允许您不必在每次更改标记时都重写整个 wipper,并拥有更多可维护的代码,但代价是编写两个 FITS-wrap 函数,将内存对象转换为 SQLited 字段值,反之亦然。

如果 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 回答