4

我有一个符号表达式 inMATLAB和一个==可以在 in 中使用的运算符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
4

3 回答 3

4

从 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
于 2017-03-12T13:07:56.827 回答
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 的字符串操作更强大,原因很简单:您的左侧和右侧可能包含等号本身。

于 2013-03-15T16:06:56.857 回答
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([[...]])语法)。

现在我们使用正则表达式搜索和替换来提取 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));

lhs请注意,和之间的唯一区别rhsregexprep.
using$1提取左侧, using$2提取右侧。

于 2013-01-22T16:53:14.860 回答