.mat 文件中的“函数工作区”字段包含什么?

Rob*_*ier 2 matlab scipy mat-file

我正在使用保存在程序末尾的 .mat 文件。命令就是save foo.mat这样一切都被保存。我希望通过检查 .mat 文件来确定程序是否发生变化。我发现,从一次运行到另一次运行,大部分 .mat 文件都是相同的,但标记的字段__function_workspace__有所变化。

(我正在通过以下方式检查 .mat 文件scipy.io.loadmat——只需加载文件并将它们打印为纯文本,然后比较文本。我发现save -ascii在 Matlab 中不会在事物上放置字符串标签,因此通过 Python 是迂回的,但是我得到标签,这很有用。)

我试图确定这些变化的根源。谁能解释一下其中__function_workspace__包含什么?为什么给定程序的一次运行与下一次运行不一样?

我真正感兴趣的变量是相同的,但我担心我可能会忽略一些可能会反过来影响我的变化。预先感谢您对这个问题的任何启发。

编辑:正如我在评论中提到的, 的值__function_workspace__是一个整数数组。我查看了数组的元素,发现这些数字是 ASCII 或非 ASCII 字符代码。我看到一系列字符看起来像变量或函数的名称,所以这是有道理的。但也有一些字符(非 ASCII)似乎不是名称的一部分,并且还有很多空(零)字符。因此,除了在 中看到事物的名称之外__function_workspace__,我不确定这些东西到底是什么。

第二次编辑:我发现在注释掉对绘图函数的调用之后,__function_workspace__程序的一次运行到下一次运行的内容是相同的,所以这很好。此时,一次运行与下一次运行的唯一区别是,有一个__header__字段包含创建 .mat 文件的时间的时间戳,该时间戳在每次运行时都会发生变化。

第三次编辑:我找到了一篇文章,http://nbviewer.jupyter.org/gist/mbauman/9121961 “解析其中包含类对象的 MAT 文件”,关于该__function_workspace__领域的逆向工程。感谢 Matt Bauman 写了这篇非常有启发性的文章,并感谢 @mpaskov 的指点。看起来这__function_workspace__是一个未记录的各种内容的包罗万象的东西,其中只有一部分实际上是“功能工作区”。

Flo*_*ner 6

1) 比较 .mat 文件

您可能想看看DiffPlug。它可以对 MAT 文件进行比较,我相信它也有一个命令行界面。

2)function_workspace的内容

SciPy 是__function_workspace__指 MAT 文件末尾的一个特殊变量,其中包含引用类型(例如 、 、 等)所需的额外数据table以及string官方handle文档未涵盖的各种其他内容。该名称具有误导性,因为它实际上指的是“子系统”(在官方规范中作为标题中的偏移量简要提及)。

例如,如果您保存引用类型,例如emptyString = "",结果.mat将包含以下两个条目:

(1) 变量本身。它看起来有点像UInt32矩阵,但实际上是子系统中某个位置的对象Opaque MCOS Reference的(MATLAB 类对象系统) 。string

 [0] Compressed (81 bytes, position = 128)
  [0] Matrix (144 bytes, position = 0)
    [0] UInt32[2] = [17, 0] // Opaque
    [1] Int8[11] = ['emptyString'] // Variable Name
    [2] Int8[4] = ['MCOS'] // Object Type
    [3] Int8[6] = ['string'] // Class Name
    [4] Matrix (72 bytes, position = 72)
      [0] UInt32[2] = [13, 0] // UInt32
      [1] Int32[2] = [6, 1] // Dimensions
      [2] Int8[0] = [''] // Variable Name (not needed)
      [3] UInt32[6] = [-587202560, 2, 1, 1, 1, 1] // Data (Reference Target)
Run Code Online (Sandbox Code Playgroud)

(2)文件末尾UInt8没有名称的矩阵(SciPy 将其重命名为)。__function_workspace__除了缺少名称之外,它看起来像一个标准矩阵,但数据实际上是另一个包含真实数据的 MAT 文件(带有缩减的标头)。

[1] Compressed (251 bytes, position = 217)
  [0] Matrix (968 bytes, position = 0)
    [0] UInt32[2] = [9, 0] // UInt8
    [1] Int32[2] = [1, 920] // Dimensions
    [2] Int8[0] = [''] // Variable Name
    [3] ... 920 bytes ... // Data (Nested MAT File)
Run Code Online (Sandbox Code Playgroud)

不幸的是,数据的格式完全没有记录,而且有些混乱。我可以发布子系统的内容,但即使对于这样一个简单的案例,它也会变得有些不知所措。它本质上是一个 MAT 文件,其中包含一个struct特殊变量 ( MCOS FileWrapper__),该变量包含一个具有各种值的元胞数组,其中包括神奇地编码各种Object Properties.

Matt Bauman 做了一些伟大的逆向工程工作(解析其中包含类对象的 MAT 文件),我相信所有支持实现都是基于这些工作的。MFL Java库包含此功能的完整(只读)实现(请参阅McosFileWrapper.java)。

我们发现的 Matt Bauman 帖子的一些更新是:

  • MCOS 引用可以引用句柄对象数组,并且可以具有超过 6 个值。它包含大小信息,后跟索引数组(请参阅McosReference.java)。
  • 该Object Id字段看起来像是一个唯一的 ID,但顺序似乎是随机的,有时甚至不匹配。我不知道这个值是什么,但完全忽略它似乎效果很好:)
  • 我已经看到了文件Segment 5中的填充内容.fig,但我还无法缩小其中的内容。

编辑:仅供参考,一旦string正确解析了对象并填写了所有属性,实际字符串值就会以另一种未记录的格式进行编码(请参阅testDoubleQuoteString)