问题是我想用滑块控制符号变量的值并动态绘制结果。这是一个非常缓慢的操作,我无法弄清楚如何加快速度,同时仍然保持使用符号表达式的好处。
我试图设计一个用于构建表达式树的接口,该树将输出输入到合成器中的方程式。
合成器生成一个256个值的表,这些值根据方程式中变量的使用方式进行内插。例如,“ w”是指单个波形的X轴。 “ y”等于表中的当前位置除以256。因此,您可以生成一个简单的变形波形,如:
(1-y)*sin(w)+y*cos(w)
(https://i.imgur.com/2xh2Nc2.png)
这是当滑块更改时更新图的功能。
this.plotLine = fplot(this.wavePlot, sym('x'));
function plotRefresh(src, event)
yVal = (event.Value-1)/255;
set(this.yLabel, 'Value', string(yVal));
set(this.zLabel, 'Value', string(yVal*2-1));
set(this.plotLine, 'Function', subs(this.eTree.activeSym, sym('y'), yVal));
end
树中的每个节点都具有一个符号表达式,如下所示。当新节点添加到树中时,其子节点将被馈送到匿名函数中以在树中的该点生成表达式。
case nTypes.W
sy = sym('w');
case nTypes.X
sy = sym('w')*2-1;
case nTypes.Y
sy = sym('y');
case nTypes.Z
sy = sym('y')*2-1;
case nTypes.ADD
sy = @(n)fold(@(a,b)a+b, n);
case nTypes.SUBTRACT
sy = @(n)fold(@(a,b)a-b, n);
case nTypes.MULTIPLY
sy = @(n)fold(@(a,b)a*b, n);
case nTypes.DIVIDE
sy = @(n)fold(@(a,b)a/b, n);
case nTypes.EXPONENTIATE
sy = @(n)fold(@(a,b)a^b, n);
case nTypes.AND
sy = @(n)fold(@(a,b)and(a, b), n);
case nTypes.OR
sy = @(n)fold(@(a,b)or(a, b), n);
case nTypes.EQUAL
sy = @(n)fold(@(a,b)eq(a, b), n);
case nTypes.NOTEQUAL
sy = @(n)fold(@(a,b)ne(a, b), n);
case nTypes.GREATER
sy = @(n)fold(@(a,b)gt(a, b), n);
case nTypes.LESSER
sy = @(n)fold(@(a,b)lt(a, b), n);
case nTypes.GREATEROREQ
sy = @(n)fold(@(a,b)ge(a, b), n);
case nTypes.LESSEROREQ
sy = @(n)fold(@(a,b)le(a, b), n);
case nTypes.MIN
sy = @(n)fold(@(a,b)piecewise(a<=b, a, a>b, b), n);
case nTypes.MAX
sy = @(n)fold(@(a,b)piecewise(a>=b, a, a<b, b), n);
case nTypes.SIN
sy = @(n)sin(n{:});
case nTypes.COS
sy = @(n)cos(n{:});
case nTypes.TAN
sy = @(n)tan(n{:});
我尝试了在没有符号表达式的情况下实现这一点,并且它的运行速度更快。在那种情况下,每个节点都有一个双/嵌入式句柄,它将其子节点作为第一个匿名函数的参数,然后返回另一个匿名函数,该函数将在给定全局变量w和y的情况下执行其求值。
case nTypes.SIN
sy = @(children)@(w, y)sin(children(w, y));
然后我制作了一个512x256的单元格数组,以缓存每个可能的滑块位置的值。
cached = cellfun(@(y)cellfun(@(w)tNode.sy(w, y), linspace(0, 1, 512)), linspace(0, 1, 256))
然后,当滑块更改时,我会set(gca, 'YData', cached{sliderPosition})
进行缓存,使图更新更加平滑。但是,如果有一种方法可以使用符号评估而不是深度嵌套的匿名函数树类似地进行缓存,则是首选。
这可能吗?