加快符号变量的动态绘图

时间:2019-06-10 18:53:39

标签: matlab optimization plot symbolic-math

问题是我想用滑块控制符号变量的值并动态绘制结果。这是一个非常缓慢的操作,我无法弄清楚如何加快速度,同时仍然保持使用符号表达式的好处。

我试图设计一个用于构建表达式树的接口,该树将输出输入到合成器中的方程式。

合成器生成一个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})进行缓存,使图更新更加平滑。但是,如果有一种方法可以使用符号评估而不是深度嵌套的匿名函数树类似地进行缓存,则是首选。

这可能吗?

0 个答案:

没有答案