【问题标题】:MATLAB: How to copy a handle object as quickly as possibleMATLAB:如何尽快复制句柄对象
【发布时间】:2013-10-02 15:04:21
【问题描述】:

我想知道如何在 MATLAB 中复制(甚至删除)句柄对象。

我目前正在使用 MATLAB 和一个名为 CPLEX 的插件为大型方程组编写求解器。此求解器本质上涉及创建 CPLEX 句柄对象,然后使用如下求解方法求解它们:

P = Cplex() %Create a Cplex object
%Code to specify the Cplex parameters
P.solve() %solve the Cplex object

在上面的代码中,P 是属于 Cplex() 类的 MATLAB 句柄对象。它存储与其方程的因子相关的矩阵结构。

我正在运行的主要问题是我必须多次“解决”同一个 CPLEX 对象,我想使用 parfor 循环并行执行此操作。不幸的是,MATLAB 中的 parfor 循环需要透明性,因为多个线程不能在同一个对象上工作。

我已经想到了几种解决方法:之前,我在 parfor 循环中创建并设置了 Cplex() 文件(结果证明这比单线程实现要慢);我还尝试将对象保存到磁盘并在 parfor 循环中加载它(同样太慢了)。现在我想看看我是否可以复制该对象(在 parfor 循环内或在它之外)。然而不幸的是,Cplex 对象没有内置的“复制”功能,我必须自己编写类似的代码。

基本上我想做的事情归结为:

P = Cplex() %creates Cplex object
%Setup Cplex object

Q = cell(1,n) %create a container for Cplex objects

parfor 1:n

Q{i} = P.copy %create a copy of P and label it as Q{i}
Q{i}.solve()
Q{i} = [] %delete Cplex object (for memory purposes /preferable, but not necessary)

end

【问题讨论】:

  • 只是出于好奇,多次解决它如何改变结果?求解器是随机的吗?
  • 其实方程组有很多随机参数,我需要针对每一种不同的随机参数组合来求解。最终会发生的是,我将在 parfor 循环之外创建一个 Cplex() 对象,然后将其复制/替换为 parfor 循环内的随机参数。
  • 我试图了解您在这里需要什么时的其他一些问题... 1) 创建对象的函数调用Cplex() 是否昂贵? 2)一旦你设置了参数(或者无论如何设置),a=Cplex()b=Cplex()会代表同一个系统吗? 3) ab 有相同的句柄吗?
  • @yoda 1) 函数/构造函数调用 Cplex() 相对昂贵,因为从头开始构建它并在 parfor 循环中设置它基本上减少了并行处理所节省的所有时间。 2)/3) 不完全确定这里的问题,a = Cplex() 将创建一个可以使用 a 访问的 CPLEX 对象。 b = a 将简单地创建另一个指向同一 CPLEX 对象的指针,而 b = Cplex() 将创建一个完全不同的 CPLEX 对象。
  • 感谢您的帮助!

标签: matlab parallel-processing


【解决方案1】:

我没有 CPLEX,因为我无法复制您的代码,请尝试以下建议并告诉我它是否有效(或者如果您遇到错误,错误是什么)。

尝试在parfor 循环之外将Q 定义为

Q=arrayfun(@(x)P.copy,1:n,'UniformOutput',false);

这应该像您之前一样创建一个单元格,您可以以Q{i} 访问它,并且应该可以节省一些时间(因为如果您担心在处理后删除每个元素的内存问题,那么复制它可能涉及还有一些时间开销)。

【讨论】:

  • 问题是 P 没有复制方法,所以 P.copy 在这种情况下不起作用。我更广泛的问题是如何将其添加到类定义中。
  • @Berk: 啊,那就试试不带.copyarrayfun(@(x)P,1:n,... 那应该将对象P 分配给Q 中的每个单元格,然后可以作为@987654329 访问@
  • 所以这也行不通,因为 P 本质上表现得像一个指向 CPlex() 对象的指针。所以 Q = P 将创建指针的副本,而不是对象的副本。
  • @Berk:我明白了...您知道 MATLAB 中的等效对象及其行为类似于您的 Cplex 对象的工具箱吗?我问是因为我想在我的电脑上摆弄一些代码,看看有什么用。现在我只是在瞎拍。
  • 我无法在 MATLAB 中考虑等效对象,但当我创建 a = Cplex() 时,MATLAB 将“a”称为“句柄类”,因此任何其他句柄类都应该表现类似。
【解决方案2】:

我认为基本上有 3 种可能性,具体取决于 CPlex 的实现细节:

  1. 编写一个复制函数:如果 CPlex 的所有重要属性都是公开可写的,这应该可以工作 - 这基本上是 copyobj 用于图形对象的内容。
  2. 将 CPlex 子类化为 MyCPlex 并实现复制方法。只要没有任何重要属性是private,这应该可以工作。
  3. 如果有私有属性,那么您要么必须将它们更改为受保护,然后使用解决方案编号。 2 或简单地将复制函数实现为 CPlex 中的方法。

鉴于构造函数在 CPU 时间方面的开销很大,因此 2. 或 3. 可能是更好的版本,因为您可能必须实现一个空构造函数:它只返回一个对象句柄而无需所有内部初始化内容。 复制的实现细节应该是直截了当的——将复制对象的所有属性设置为原始对象的值: 在它的幼稚版本中:

copyObj = CPlex();
props = {'propA', 'propB', ...}; % list of a all non-dependent, non-constant properties
for i=1:numel(props)
     copyObj.(props{i}) = originalObj.(props{i});
end

根据 CPlex 内部的复杂性,事情当然可能会更复杂一些...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 2012-09-26
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多