How can I get multiple values from arrayfun in Matlab - matlab

I have the following sample code.
clear
clc
a = 1:1000;
b = linspace(100,200,1000);
x1 = arrayfun( #(v,w) fminsearch(#(x) (x(1)-v).^2 + (x(2)-w).^2, [1;1]), a, b, 'UniformOutput', false);
and x1 returns 1*1000 cells and each of the cells gives me the minimizer v and w that minimizes the objection function given v and w.
However, I want to get 21000 double instead of 11000 cells.
Is there any way I can get x1 as 2*1000?
Thanks in advance.

Related

Matlab 3d plot custom function

I am new to Matlab and i ran into this problem:
I have a function that takes 3 doubles as arguments and outputs a single double e.g.:
function l = myFunct(a,b,c)
l = a^2*b^2 + (2*(c^2 - b) / (a - sqrt(c)))
end
Now, I need to plot the result of this function for intervals:
a = b = [0.1,3], while keeping c = 2.
I managed to do this for 2d plot of a single variable, but not for 3d...
R = 0:0.01:2;
fun = #(x) myFunct(0.2, x, 3);
B = arrayfun(fun,R);
plot(R, B);
Could you please help and explain?
You can indeed use meshgrid, or ndgrid, to create the two grid arrays. A and B. Then, if your function is not vectorized you need to loop over the entries of A and B. To loop over both at the same time you can use arrayfun. Lastly, you can plot with surf or imagesc.
[A,B] = ndgrid(1.4:0.0001:1.44, -1:.01:3);
Z = arrayfun(#(a,b) myFunct(a,b,2), A, B);
surf(A,B,Z,'edgecolor','none')
I finally solved it with:
V = 2;
[X,Y] = meshgrid(0.1:0.1:3);
Z = myFunct(X,Y,X*0+V);
figure
surf(X,Y,Z);
Thanks all for the replies.

Matlab: Computations with the translations of a function

Before the question, thank you for reading this post.
I have defined a real function, f= #(x) sin(x) + x.^2 and I want to store the N translates of f from 0 to N-1, in a vector w. I mean, I want to store the vector w=( sin(x) + x.^2 , ...., sin(x- (N-1)) + (x-(N-1)).^2)
I have a vector, v, of N real numbers.
Question: How to get the inner product, u, of v and w? I want to store it as a function because I want to calculate the FFT coefficients of u.
I'm trying to do this with a loop but I'm making a mess with the loop/s.
Would you help me, please?
Many thanks.
What I did with the help of #m7913d:
%%%code
N=10;
v=rand(1,N);%%vector
tras=1:N;
tsi=t.*ones(1,N);
%%ff(x)=sin(x)+x.^2
ff=sin(tsi+tras) +(tsi+tras).^2 ;
total=sum(ff.*v,2);
vpa(subs(total,t,0.1));%%check
Fs=100;% Sampling frequency
tt=-pi:1/Fs:pi;% Time vector
L=length(tt); % Signal length
X=double(subs(total, t,tt));
n=2^nextpow2(L);
coef=fft(X,n);
You can generate a cell array of functions as follows:
N = 10;
f= #(x) sin(x) + x.^2;
u = cell(N, 1);
v = rand(N, 1);
g = 0;
for i=0:(N-1)
u{i+1} = #(x) v(i+1)*f(x + i);
g = #(x) g(x) + u{i+1}(x);
end
Note that I calculated the u vector at once, without using the intermediate variable w.
Note that the calculations will be easier (and faster) if you immediately insert your desired x vector. In that case, you do not have to hassle with function handles.
The question is solved. Here is the code
%%%code
N=10;
v=rand(1,N);%%vector
tras=1:N;
tsi=t.*ones(1,N);
%%ff(x)=sin(x)+x.^2
ff=sin(tsi+tras) +(tsi+tras).^2 ;
total=sum(ff.*v,2);
vpa(subs(total,t,0.1));%%check
Fs=100;% Sampling frequency
tt=-pi:1/Fs:pi;% Time vector
L=length(tt); % Signal length
X=double(subs(total, t,tt));
n=2^nextpow2(L);
coef=fft(X,n);
Thanks to everyone for your help.

Using a vector as an input for a function of multiple inputs in matlab

I want to use a vector input such of dimension [m;1] in a function that takes in m number of inputs. For example:
syms x1 x2;
f = x1^2 + x2^2;
F = matlabFunction(f);
x = [1;1];
F(x);
The above code does not work because F is a function of 2 inputs and it only sees the vector x as a single input. I know I can say F(x(1),x(2)) and the above would work but I want it to work for a function of m variables and a vector of m length.
All help is appreciated.
Thanks.
You will want to first convert x to a cell and then pass it with {:}.
xcell = num2cell(x);
F(xcell{:});
Alternately, you can specify that you want x1 and x2 to be passed as an array when you call matlabFunction using the Vars parameter.
F = matlabFunction(f, 'Vars', {[x1, x2]});
F([1 1]);

Vectorize with Matlab Meshgrid in Chebfun

I am trying to use meshgrid in Matlab together with Chebfun to get rid of double for loops. I first define a quasi-matrix of N functions,
%Define functions of type Chebfun
N = 10; %number of functions
x = chebfun('x', [0 8]); %Domain
psi = [];
for i = 1:N
psi = [psi sin(i.*pi.*x./8)];
end
A sample calculation would be to compute the double sum $\sum_{i,j=1}^10 psi(:,i).*psi(:,j)$. I can achieve this using two for loops in Matlab,
h = 0;
for i = 1:N
for j = 1:N
h = h + psi(:,i).*psi(:,j);
end
end
I then tried to use meshgrid to vectorize in the following way:
[i j] = meshgrid(1:N,1:N);
h = psi(:,i).*psi(:,j);
I get the error "Column index must be a vector of integers". How can I overcome this issue so that I can get rid of my double for loops and make my code a bit more efficient?
BTW, Chebfun is not part of native MATLAB and you have to download it in order to run your code: http://www.chebfun.org/. However, that shouldn't affect how I answer your question.
Basically, psi is a N column matrix and it is your desire to add up products of all combinations of pairs of columns in psi. You have the right idea with meshgrid, but what you should do instead is unroll the 2D matrix of coordinates for both i and j so that they're single vectors. You'd then use this and create two N^2 column matrices that is in such a way where each column corresponds to that exact column numbers specified from i and j sampled from psi. You'd then do an element-wise multiplication between these two matrices and sum across all of the columns for each row. BTW, I'm going to use ii and jj as variables from the output of meshgrid instead of i and j. Those variables are reserved for the complex number in MATLAB and I don't want to overshadow those unintentionally.
Something like this:
%// Your code
N = 10; %number of functions
x = chebfun('x', [0 8]); %Domain
psi = [];
for i = 1:N
psi = [psi sin(i.*pi.*x./8)];
end
%// New code
[ii,jj] = meshgrid(1:N, 1:N);
%// Create two matrices and sum
matrixA = psi(:, ii(:));
matrixB = psi(:, jj(:));
h = sum(matrixA.*matrixB, 2);
If you want to do away with the temporary variables, you can do it in one statement after calling meshgrid:
h = sum(psi(:, ii(:)).*psi(:, jj(:)), 2);
I don't have Chebfun installed, but we can verify that this calculates what we need with a simple example:
rng(123);
N = 10;
psi = randi(20, N, N);
Running this code with the above more efficient solution gives us:
>> h
h =
8100
17161
10816
12100
14641
9216
10000
8649
9025
11664
Also, running the above double for loop code also gives us:
>> h
h =
8100
17161
10816
12100
14641
9216
10000
8649
9025
11664
If you want to be absolutely sure, we can have both codes run with the outputs as separate variables, then check if they're equal:
%// Setup
rng(123);
N = 10;
psi = randi(20, N, N);
%// Old code
h = 0;
for i = 1:N
for j = 1:N
h = h + psi(:,i).*psi(:,j);
end
end
%// New code
[ii,jj] = meshgrid(1:N, 1:N);
hnew = sum(psi(:, ii(:)).*psi(:, jj(:)), 2);
%// Check for equality
eql = isequal(h, hnew);
eql checks if both variables are equal, and we do get them as such:
>> eql
eql =
1

writing function using varargin and varargout

I have this function and I want to use varargin and varargout for all the inputs and the outputs and I don't know exactly how to do it.
Any suggestions? This is my function:
function [Output0,Output1] = myfunction(p0,p1,normal0,normal1,c0,c1)
t0 = sqrt((c0^2)/((normal0(1)^2) + (normal0(2)^2) + (normal0(3)^2)));
Output0= p0 + normal0*t0;
t1 = sqrt((c1^2)/((normal1(1)^2) + (normal1(2)^2) + (normal1(3)^2)));
Output1= p1 + normal1*t1;
Thanks in advance
I don't think this is an appropriate case for varargin or even for nargin. This is a case for vectorizing your function.
OK so lets say you have these inputs: xo, yo, zo, x1, y1, z1 (all scalar), normal0 (1x3), normal1 (1x3) and c0 and c1 both scalar.
Lets see if we can vectorize your function to calculate all the outputs in one shot. So first we'll rearrange your data:
P = [x0, x1;
y0, y1
z0, z1];
N = [normal0;
normal1]'; %better here to just make normal0 a (3x1) so no need to transpose
C = [c0, c1]
now lets look at how you got your first output:
t0 = sqrt((c0^2)/((normal0(1)^2) + (normal0(2)^2) + (normal0(3)^2)));
Output0= p0 + normal0*t0;
this can be simplified to
p0 + normal0 * sqrt(c0^2/sum(normal0.^2))
which can be generalized to
P + bsxfun(#times,N,sqrt(bsxfun(#rdivide,C.^2,sum(N.^2))))
So now you get any number of outputs in one shot! In one line too!
Just a quick explanation of where bsxfun came into it. So in your original calcs you sometimes multiply or add a scalar to a vector. Matlab allows this but it doesn't allow the higher dimensional case of say adding a vector to a 2D matrix. bsxfun does this for us. so where I have bsxfun(#times, N, B) above, it just takes the 3x1 B vector and does an elementwise multiplication (#times is the function handle to .*) of B on each column of the 3x2 N. But here it's fine for N to be 3xX i.e. have any number of columns i.e. any number of inputs.