As is well known, if f() is linear function then there exists a matrix A such that for any Y=f(X), where X and Y are array-valued input/output arguments, the operation can equivalently be expressed Y(:)=A*X(:). In MATLAB, we are often given linear operations f() in function form only, but need the matrix form to do linear algebraic manipulations: transpose, pseudo-inversion, etc... Examples of such operations are INTERPN, RADON, IMTRANSFORM, etc...
The file FUNC2MAT in this submission computes the matrix A given a handle, fun, to any linear function
Here Xtypical is just some sample input argument to tell the code the dimensions and class of the input to fun().
The approach to computing A is largely brute force. If A is MxN, then the code works essentially by applying fun to each column of eye(N) in a loop. However, options are available to leverage the Parallel Computing Toolbox if you have it
This assumes a matlabpool is already open. By default, A is computed as a sparse matrix, but if sufficiently small/dense, it is sometimes more efficient memory-wise and speed-wise to compute A in full form
I would mention that this code is not the solution I would prefer to anything. In my perfect world, TMW would provide efficient function-form transposes and inverses, etc... to INTERPN, IMTRANSFORM, and every other linear code routine they provide. But since that is not feasible, this brute force approach is often the only alternative.
Frequent instances where the matrix form is needed are parameter estimation problems that one wishes to solve with the Optimization Toolbox. For example, consider the simple super-resolution problem where we have a noisy 300x300 image Y1 of some object and a noisy 300x300 image of the same object Y2, but rotated 30 degrees. We can fuse Y1 and Y2 into a less noisy image X by minimizing the least squares cost function
f=@(X) norm(Y1-X,'fro')^2 + norm(Y2-imrotate(X,30),'fro')^2
This minimization can be done using LSQNONLIN or FSOLVE. However, these solvers use finite difference approximations which would be very costly when f is expressed as above.
Using FUNC2MAT, however, I can solve this non-iteratively follows,
A=func2mat(@(X) imrotate(X,30), zeros(300));
Or, if I wish to impose constraints on X, e.g., positivity, I can still use iterative solvers in the Optimization Toolbox, but because I have the function in matrix form, I can supply my own gradient computation using GradObj='on',
which will be much faster than with finite difference gradient approximations.
Matt J (2020). FUNC2MAT: Convert linear function to matrix (https://www.mathworks.com/matlabcentral/fileexchange/44669-func2mat-convert-linear-function-to-matrix), MATLAB Central File Exchange. Retrieved .