【问题标题】:Number of outputs from constant anonymous function (anonymous function not known a priori)常量匿名函数的输出数(匿名函数先验未知)
【发布时间】:2013-11-18 03:13:38
【问题描述】:

这个问题最初可能看起来类似于this other question,但我的情况有点不同。

我有一个函数“deriv”,它以符号表达式作为输入,然后取该符号表达式的一阶导数。然后使用matlabFunction() 将该导数转换为匿名函数,然后对一组点进行评估。稍后我还会在其他一些代码中使用匿名函数。

我遇到的问题是,有时输入符号表达式恰好是线性的,因此导数是常数;因此匿名函数也是一个常数。当我在点数组上评估匿名函数时,我只得到一个输出而不是输出数组。

这里有一些代码显示我在做什么。这里为了简单起见,我们假设符号输入表达式将只涉及一个名为 q 的符号变量。

function[derivFun,derivVals] = deriv(input)
derivSym = diff(input,q);
derivFun = matlabFunction(derivSym,'vars',q);
evalPoints = [1;2;3;4;5]; %in my true application, a much larger array
derivVals = derivFun(evalPoints);
end

因此,如果输入是 q^2,那么输出 derivVals 将是 [2;4;6;8;10]。但如果输入恰好是 3*q,那么 derivVals 将是 3(只是一个标量)。我想要的是derivVals 是 [3;3;3;3;3]。 也就是说,我希望derivVals 的大小与evalPoints 相同,即使输入函数恰好是线性(或常数)。而且我不提前知道输入表达式会是什么。

任何人都可以就可以做到这一点的方案提出建议吗?我知道一个常量匿名函数只会返回一个常量标量,而不管其输入的大小。我希望通过某种方式识别匿名函数何时保持不变,然后仍然导致derivVals 的大小与evalPoints 相同。

我知道我可以使用for 循环来为evalPoints 的每一行评估derivFun,但我想尽可能避免使用这样的循环。

感谢您的时间和考虑。

【问题讨论】:

  • 我不知道为什么我之前没有想到这个:使用symvarif isempty(symvar(derivSym)) 然后derivFun = @(q) double(derivSym)*ones(size(q));。还有其他想法吗?

标签: matlab anonymous-function


【解决方案1】:

我认为这是一个稍微简单的解决方案。问题是您使用的是matlabFunction,它简化了方程式并且不允许进行太多自定义。但是,您可以创建匿名函数的匿名函数。只需在您的 matlabFunction 行之后添加此行:

derivFun = @(evalPoints)derivFun(evalPoints)+zeros(size(evalPoints));

这只会评估原始derivFun 一次。不过,我确实喜欢你 symvar 的解决方案(请记住,添加 zeros 总是比乘以 ones 更好)。

【讨论】:

  • 哇,太聪明了!我喜欢。感谢您对matlabFunction 的提醒
【解决方案2】:

不是 100% 确定我正确地解决了问题。 这会解决你的问题吗?:

if isscalar(derivVals)
    derivVals = repmat(derivVals, size(evalPoints));
end

【讨论】:

  • 感谢您的回复。那肯定行得通。但是,与其检查属性derivVals,我更希望函数derivFun 已经给出了正确大小的输出。那是因为我在其他一些代码中广泛使用了derivFun(我在原始问题中没有强调)。
猜你喜欢
  • 2016-03-14
  • 1970-01-01
  • 2012-10-30
  • 1970-01-01
  • 1970-01-01
  • 2011-12-29
  • 2011-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多