function [x, err_norm] = xabx(a, b, c, TRANSPOSE_FLAG) % xabx -- Solve x*a + b*x = c for x. % xabx(a, b, c, 'TRANSPOSE_FLAG') solves the linear % system x*a + b*x = c for x. If the TRANSPOSE_FLAG % is any string, then the system to be solved is % x'*a + b*x = c for x. % xabx(a, c, 'TRANSPOSE_FLAG') solves the linear % system x*a + a*x = c or x'*a + a*x = c for x. % [x, err_norm] = ... returns x and the error-norm. % Copyright (C) 1997 Dr. Charles R. Denham, ZYDECO. % All Rights Reserved. % Disclosure without explicit written consent from the % copyright owner does not constitute publication. if nargin < 1, help xabx, a = 2; end if nargin < 2 n = a; if isstr(n), n = eval(n); end a = fix(rand(n, n) .* 10); b = fix(rand(n, n) .* 10); c = fix(rand(n, n) .* 10); if n < 4, a, b, c, end if nargout > 0 [x, err_norm] = xabx(a, b, c); else xabx(a, b, c) end return end flag = 0; if nargin == 4 if isstr(TRANSPOSE_FLAG) flag = 1; end elseif nargin == 3 if isstr(c) flag = 1; c = b; b = a; end elseif nargin == 2 c = b; b = a; end [ma, na] = size(a); [mb, nb] = size(b); [mc, nc] = size(c); if na ~= nc | mb ~= mc error(' ## Incompatible data sizes.') return end % Construct u and v as index-arrays for x. mv = nb; nv = nc; v = zeros(mv, nv); v(:) = 1:prod(size(v)); u = v; if flag, u = u.'; end [mu, nu] = size(u); % Construct d to solve d * x(:) = c(:). d = zeros(prod(size(v)), prod(size(c))); % Assemble the x*a portion first. k = 0; for j = 1:na for i = 1:mu indices = u(i, :); k = k + 1; d(k, indices) = d(k, indices) + a(:, j).'; end end % Assemble the b*x portion next. k = 0; for j = 1:nv for i = 1:mb indices = v(:, j); k = k + 1; d(k, indices) = d(k, indices) + b(i, :); end end % Solve the system. v(:) = d \ c(:); % v is already the right size. % Error-norm. if nargout ~= 1 u = v; if flag, u = u'; end err_norm = norm(u*a + b*v - c); end % Output. if nargout > 0 x = v; else disp(' '), disp(['ans =']), disp(' '), disp(v), err_norm end