Matlab:将ID与数据集(例如struct)相关联吗?

时间:2019-04-14 18:47:58

标签: matlab data-structures struct finite-element-analysis

我正在为Matlab中的高阶有限元模拟算法开发某些功能,我想知道什么是实现特定任务的好方法。我相信我面临着一个普遍的问题,但是在进行一些挖掘之后,我并没有真正找到一个好的解决方案。

基本上,我有一个很长的ID列表(对应于我的网格上的某些节点),其中每个ID与较小的数据集相关联。然后,当我运行我的求解器时,我需要访问与这些节点关联的数据并更新数据(多次)。

例如,假设这是我列出的这些特定节点:

nodelist = [3 27 38] %(so these are my node ID's) 

然后为每个节点关联以下数据集

a (scalar)
b (5x5 double matrix)
c (10x1 double vector)

(a total of 36 double values associated with each node ID)

实际上,我当然会拥有更长得多的节点ID列表以及与每个节点相关联的数据集(但仍然只有双标量,矩阵和向量(没有字符,字符串等))。

方法1

因此,我准备的一种方法是将所有内容存储在2D双矩阵中,然后在需要时执行一些相对复杂的索引以访问我的数据。对于上面的示例,我的2D矩阵的大小为

size(2Dmat) = [length(nodelist), 36]

说我想访问节点ID 27的b(3,3),我访问2Dmat(2,14)。

从原理上讲,这是可行的,但是由于这种复杂的索引编制,代码不是很干净和可读性(更不用说,当我改变数据集的设置方式时,我需要重新调整完整的索引代码)。

方法2

另一种方法是对节点列表中的每个节点使用某种结构:

a = 4.4;
b = rand(5,5);
c = rand(10,1);
s = struct('a',a,'b',b,'c',c)

然后我可以通过s.b(3,3)等访问数据。但是我只是不知道如何将结构与节点ID相关联?

方法3

我能想到的最后一件事是建立某种SQL数据库,但这似乎是一个过大的选择。另外,我需要我的代码尽可能快,因为我需要多次访问与这些选定节点关联的数据集中的这些字段,并且我想对数据库进行一些查询会降低速度。

请注意,最终我将把代码从Matlab转换为C / C ++,所以我宁愿实现一些不太依赖Matlab特定功能的东西。

那么,关于如何以干净的方式实现此功能的任何想法?希望我的问题有道理,并预先感谢!

2 个答案:

答案 0 :(得分:2)

方法2是最简洁的方法,可以轻松转换为C ++。对于每个节点,您都有一个结构s,然后:

data(nodeID) = s;

是所谓的struct数组。您索引为

data(id).b(3,3) = 0.0;

这假定ID是连续的,或者ID的值之间没有巨大的差距。但这始终可以确保,如有必要,可以很容易地重新编号节点ID。


在C ++中,您将有一个结构向量:

struct Bla{
   double a;
   double b[3][3];
   double c[10];
};

std::vector<Bla> data(N);

或在C中:

Bla* data = malloc(sizeof(Bla)*N);

free(data)做完后不要忘记)。

然后,在C或C ++中,您可以通过以下方式访问元素:

data[id].b[2][2] = 0.0;

翻译是显而易见的,除了索引在C ++中从0开始,在MATLAB中从1开始。


请注意,此方法的内存开销比MATLAB中的方法1大,但在C或C ++中则没有。

方法3是个坏主意,只会减慢您的代码速度而没有任何好处。

答案 1 :(得分:2)

我认为,给定一组不连续的节点ID,最干净的解决方案是使用map container的方法2,其中您的节点ID是映射中的键(即索引)。这可以在MATLAB中使用containers.Map对象来实现,而在C ++中可以使用std::map容器来实现。例如,下面是如何在MATLAB中创建值并将其添加到节点图中的方法:

>> nodeMap = containers.Map('KeyType', 'double', 'ValueType', 'any');
>> nodelist = [3 27 38];
>> nodeMap(nodelist(1)) = struct('a', 4.4, 'b', rand(5, 5), 'c', rand(10, 1));
>> nodeMap(3)

ans = 

  struct with fields:

    a: 4.400000000000000
    b: [5×5 double]
    c: [10×1 double]

>> nodeMap(3).b(3,3)

ans =

   0.646313010111265

在C ++中,您需要为要存储在地图中的数据类型定义结构或类(例如Node)。这是一个示例(...表示传递给Node构造函数的参数):

#include <map>

class Node {...};   // Define Node class
typedef std::map<int, Node> NodeMap;  // Using int for key type

int main()
{
  NodeMap map1;

  map1[3] = Node(...);  // Initialize and assign Node object
  map1.emplace(27, std::forward_as_tuple<...>);  // Create Node object in-place
}