代码之家  ›  专栏  ›  技术社区  ›  sobek

MATLAB编码器动态调整结构数组大小

  •  3
  • sobek  · 技术社区  · 10 年前

    我试图在一段代码中使用一个动态增长的结构数组,该代码应该使用Coder转换为C:

    我初始化结构,然后为编码器声明其字段变量大小,然后继续增长结构。注意,我已经简化了这个示例以帮助生成代码的可读性,所以我使用结构数组的原因在这个示例中并不明显。

    MATLAB:

    function [ events ] = testArraysOfStructs( data)
    //%#codegen
    
    ii=1;
    events = struct('typ'   ,int32(0),...
                    'title' ,int32(1),...
                    'value' ,double(0),...
                    'sta'   ,int32(2),...
                    'end'   ,int32(3));
    
    coder.varsize('events','events.typ','events.title','events.value','events.sta','events.end','events.title')
    
    for n=1:length(data.temperatur_spikes_daily)
    
        events(ii).typ      = int32(101);
        events(ii).title    = int32(1234);
        events(ii).value    = double(1234);
        events(ii).sta      = int32(4321);
        events(ii).end      = int32(3412);
    
        ii = length(events)+1;
    end
    end
    

    问题是,在生成的代码中,变量 ii 消失,数据被连续写入到结构的相同数组元素上,而不考虑循环的迭代次数。

    C:

    void testArraysOfStructs(const struct0_T *data, struct1_T events_data[], int
      events_size[2])
    {
      struct1_T r0;
      int n;
      r0.typ.size[0] = 1;
      r0.typ.size[1] = 1;
      r0.typ.data[0] = 0;
      r0.title.size[0] = 1;
      r0.title.size[1] = 1;
      r0.title.data[0] = 1;
      r0.value.size[0] = 1;
      r0.value.size[1] = 1;
      r0.value.data[0] = 0.0;
      r0.sta.size[0] = 1;
      r0.sta.size[1] = 1;
      r0.sta.data[0] = 2;
      r0.end.size[0] = 1;
      r0.end.size[1] = 1;
      r0.end.data[0] = 3;
      events_size[0] = 1;
      events_size[1] = 1;
      events_data[0] = r0;
      for (n = 0; n < data->temperatur_spikes_daily->size[0]; n++) {
        events_data[0].typ.size[0] = 1;
        events_data[0].typ.size[1] = 1;
        events_data[0].typ.data[0] = 101;
        events_data[0].title.size[0] = 1;
        events_data[0].title.size[1] = 1;
        events_data[0].title.data[0] = 1234;
        events_data[0].value.size[0] = 1;
        events_data[0].value.size[1] = 1;
        events_data[0].value.data[0] = 1234.0;
        events_data[0].sta.size[0] = 1;
        events_data[0].sta.size[1] = 1;
        events_data[0].sta.data[0] = 4321;
        events_data[0].end.size[0] = 1;
        events_data[0].end.size[1] = 1;
        events_data[0].end.data[0] = 3412;
      }
    }
    

    我想我在声明结构动态时有一个错误,但不幸的是,文档中只包含了声明标准数组动态或预先分配结构数组大小的示例,尽管提到支持动态调整大小。如果能帮助我们实现这一目标,我们将不胜感激。

    1 回复  |  直到 10 年前
        1
  •  3
  •   Ryan Livingston    10 年前

    简单的回答是:通过索引一个数组的末尾来增加一个数组是 not supported 使用编码器。

    所以你的循环增加了 events Coder不支持每次迭代。您可以使用:

    function [ events ] = foo(data)
    %#codegen
    
    events = struct('typ'   ,int32(0),...
                    'title' ,int32(1),...
                    'value' ,double(0),...
                    'sta'   ,int32(2),...
                    'end'   ,int32(3));
    
    for n = 1:length(data.temperatur_spikes_daily)
        events = [events, struct('typ'   ,int32(101),...
                    'title' ,int32(1234),...
                    'value' ,double(1234),...
                    'sta'   ,int32(4321),...
                    'end'   ,int32(3412))];
    end
    

    或:

    function [ events ] = foo(data)
    %#codegen
    % Allocate events
    s = struct('typ'   ,int32(0),...
        'title' ,int32(1),...
        'value' ,double(0),...
        'sta'   ,int32(2),...
        'end'   ,int32(3));
    events = coder.nullcopy(repmat(s, 1, length(data.temperatur_spikes_daily)));
    
    % Populate values of events
    for n = 1:numel(events)
        events(n).typ      = int32(101);
        events(n).title    = int32(1234);
        events(n).value    = double(1234);
        events(n).sta      = int32(4321);
        events(n).end      = int32(3412);
    end
    

    相反

    如果您从原始代码而不是独立代码生成MEX函数,并在MATLAB中运行此MEX函数时,将出现错误:

    Index exceeds matrix dimensions.  Index value 2 exceeds valid range [1-1] of array events.
    
    Error in foo (line 15)
        events(ii).typ      = int32(101);
    

    生成并运行MEX函数是验证MATLAB代码是否使用Coder支持的构造的最佳方法。