我在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
答案 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))
瞧。
以下是复制粘贴友好lhs
和rhs
功能:
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
和rhs
之间的唯一区别是regexprep
中已替换的令牌。
使用$1
提取左侧,并使用$2
提取右侧。