如何在Matlab上为符号表达式编写`lhs()`或`rhs()`函数

时间:2013-01-22 15:36:17

标签: matlab symbolic-math mupad

我在MATLAB中有一个带有==运算符的符号表达式,我可以在solve()中使用它。我想要的是将表达式的左侧和右侧分成两个单独的符号表达式。

例如:

expr = sym('[1-x^2==2*y; 1+x^2==x+y]');
side1 = lhs(expr);        % returns side1 = [1-x^2; 1+x^2];

当然,我的表达式要复杂得多,它总是矢量或矩阵形式。

解决方法1 我可以使用MuPAD内置函数lhs(),但我想知道是否可以仅使用MATLAB函数来执行此操作,并且我希望使其适用于表达式的向量而不是只有一个值。

这是我到目前为止按预期工作的内容。也许结果填充可以通过使用:以某种方式进行矢量化,但我无法让它工作。

function [ r ] = lhs( expr )
%LHS Returns the left hand side an expression
%   LHS(sym('[1-x^2==2*y'; 1+x^2==x+y]')) = [1-x^2; 1+x^2]

  cmd = @(e)['lhs(',char(e),')'];
  [m,n] = size(expr);
  r = sym(zeros(m,n));
  for i=1:m
      for j=1:n
          r(i,j) = evalin(symengine, cmd(expr(i,j)));
      end
  end  
end

3 个答案:

答案 0 :(得分:3)

启动R2017a,使用“lhs”和“rhs”作为

syms x
expr = [1-x^2==2*y; 1+x^2==x+y];
lhsExpr = lhs(expr)
lhsExpr =
 1 - x^2
 x^2 + 1


rhsExpr = rhs(expr)
rhsExpr =
  2*y
 x + y

答案 1 :(得分:2)

expr = sym('[1-x^2==2*y; 1+x^2==x+y]');
lr = children(expr);
lr{1}

ans =

[ 1 - x^2, 2*y]

请注意,这比EitanT的字符串操作更强大,原因很简单:您的左侧和右侧可能包含等号。

答案 2 :(得分:0)

我正在思考正则表达式,所以这是我对此的看法。

假设您有一个符号表达式expr,例如:

expr = sym('[1-x^2==2*y; 1+x^2==x+y]')

因为它不能被假定为标量表达式,所以第一步是将它分成子元素,并将每一个转换为字符串,如下所示:

C = arrayfun(@(n)char(expr(n)), 1:numel(expr), 'Uniform', false)

(我没有使用简单的char(expr)转换,因为它添加了matrix([[...]])语法。

现在我们使用正则表达式search-and-replace来提取LHS:

C = arrayfun(@(n)char(expr(n)), 1:numel(expr), 'Uniform', false)
C = regexprep(C, '([^><=]*)(?:[><=]*)(.*)', '$1')  %// $1 for lhs, $2 for rhs

然后将元素连接回字符串并将其转换为符号表达式:

str = sprintf('%s,', C{:})
result = reshape(sym(str(1:end - 1)), size(expr))

瞧。


以下是复制粘贴友好lhsrhs功能:

function y = lhs(x)
    C = arrayfun(@(n)char(x(n)), 1:numel(x), 'Uniform', false);
    C = regexprep(C, '([^><=]*)(?:[><=]*)(.*)', '$1');
    str = sprintf('%s,', C{:});
    y = reshape(sym(str(1:end - 1)), size(x));

function y = rhs(x)
    C = arrayfun(@(n)char(x(n)), 1:numel(x), 'Uniform', false);
    C = regexprep(C, '([^><=]*)(?:[><=]*)(.*)', '$2');
    str = sprintf('%s,', C{:});
    y = reshape(sym(str(1:end - 1)), size(x));

请注意,lhsrhs之间的唯一区别是regexprep中已替换的令牌。
使用$1提取左侧,并使用$2提取右侧。