How to dynamically construct a matrix of functions ?

조회 수: 13 (최근 30일)
Thomas Barbier
Thomas Barbier 2019년 5월 20일
댓글: Fangjun Jiang 2019년 5월 24일
Dear all,
I do have two functions and that both return a matrix (let's say 2x2 for the sake of the argument). I would like to construct a biggerA matrix function which takes some arguments such that:
I cant "hard-code" the handles as the size of A may not always be the same: if and are available thenA would be:
Is this possible?
Thanks for your help.
Regards

답변 (2개)

Guillaume
Guillaume 2019년 5월 23일
If I understood correctly:
function A = makeMatrix(Jc, Jf, x)
%Jc: function handle to a function that takes scalar input xi and returns a fixed size matrix
%Jf: function handle to a function that takes scalar input xi and returns a fixed size matrix
%x: vector of xi, must have an EVEN number of elements
assert(mod(numel(x), 2) == 0, 'Precondition broken');
Jcx = arrayfun(Jc, x, 'UniformOutput', false); %apply Jc to each x, store result in cell array
Jfx = arrayfun(Jf, x, 'UniformOutput', false); %apply Jf to each x, store result in cell array
Jcz = repmat({zeros(size(Jcx{1}))}, 1, numel(x)/2); %matrices of zeros to insert in first two columns
Jcmat = cell2mat(reshape([Jcx{1:2:end}, Jcz; Jcz, Jcx{2:2:end}], [], 2)); %build first two columns
Jfx = cellfun(@(odd, even) [odd;even], Jfx(1:2:end), Jfx(2:2:end), 'UniformOutput', false); %concatenate odd and even consecutive indices
Jfmat = blkdiag(Jfx{:}); %blkdiag the odd-even matrices
A = [Jcmat, Jfmat];
end
  댓글 수: 4
Thomas Barbier
Thomas Barbier 2019년 5월 24일
Yes indeed, I came with the same conclusion. So I'll reconstruct each time...
Guillaume
Guillaume 2019년 5월 24일
Without the symbolic toolbox, what you could do to speed up the reconstruction is store the location of the Jcx and Jfx in the final matrix beforehand, so the only thing you have to do in the loop is calculate the actual values and insert them at the precalculated locations:
function [locJc, locJf] = PrepareA(xlength, matsize)
%xlength: number of elements in x. Must be even
%matsize: two element vectors indicated the size of matrices returned by Jcx and Jfx
%locJx: 2 columns matrices indicating the insertion point of Jxx
locJc = [(0:xlength-1)*matsize(1) + 1; repmat([1, matsize(2)+1], 1, xlength/2)].';
locJf = [(0:xlength-1)*matsize(1) + 1; repelem(0:xlength/2-1, 2)*matsize(2) + 2*matsize(2) + 1].';
end
When it's time to reconstruct A:
function A = constructA(Jc, Jf, x, locJc, locJf, matsize)
%Jc, Jf: function handles
%x: array of x values
A = zeros(matsize(1) * numel(x), matsize(2) * (numel(x)/2 + 2));
for xidx = 1:numel(x)
A(locJc(xidx, 1) + (0:matsize(1)-1), locJc(xidx, 2) + (0:matsize(2)-1)) = Jc(x(xidx));
A(locJf(xidx, 1) + (0:matsize(1)-1), locJf(xidx, 2) + (0:matsize(2)-1)) = Jf(x(xidx));
end
end
To speed up even more, you could make locJc and locJf cell arrays of indices so as to avoid any index calculation in constructA.

댓글을 달려면 로그인하십시오.


Fangjun Jiang
Fangjun Jiang 2019년 5월 20일
편집: Fangjun Jiang 2019년 5월 20일
I think you can make the matrix using
M1=vertcat(blkdiag(JcX1,JcX2), blkdiag(JcX3,JcX4), ...)
M2=blkdiag(vertcat(JfX1,JfX2), vertcat(JfX1,JfX2), ...)
A=horzcat(M1,M2)
  댓글 수: 8
Fangjun Jiang
Fangjun Jiang 2019년 5월 24일
편집: Fangjun Jiang 2019년 5월 24일
This should do it.
x=1:6;
Jc=@(u) u-0.1+ones(2);
Jf=@(u) u-0.9+ones(2);
A=ZeroA(x);
for k=1:numel(x)
A=FillA(A,k,x(k),Jc,Jf);
end
open A;
function A=ZeroA(x)
n=numel(x);
A=zeros(2*n, 4+n);
end
function A=FillA(A,n,Xn,Jc,Jf)
IndX=(-1:0)+2*n;
IndY=IndX-4*ceil(n/2-1);
A(IndX,IndY)=Jc(Xn);
IndY=(3:4)+2*ceil(n/2);
A(IndX,IndY)=Jf(Xn);
end
Fangjun Jiang
Fangjun Jiang 2019년 5월 24일
Function ZeroA() creates the matrix A with the proper size based on X=[X1, X2, ..., Xn].
Function FillA() fills the proper elments of A based on one element of X (for example X2). It does provide efficiency if X is 1x300 and chenges only one element at a time.
Any way, it seems much harder to understand a question than to anwer one.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Matrix Indexing에 대해 자세히 알아보기

제품


릴리스

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by