writing function using varargin and varargout - matlab

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.

Related

How to solve a differential equation with non-constant coefficient?

I have an equation like this:
dy/dx = a(x)*y + b
where a(x) is a non-constant (a=1/x) and b is a vector (10000 rows).
How can I solve this equation?
Let me assume you would like to write a generic numerical solver for dy/dx = a(x)*y + b. Then you can pass the function a(x) as an argument to the right-hand side function of one of the ODE solvers. e.g.
a = #(x) 1/x;
xdomain = [1 10];
b = rand(10000,1);
y0 = ones(10000,1);
[x,y] = ode45(#(x,y,a,b)a(x)*y + b,xdomain,y0,[],a,b);
plot(x,y)
Here, I've specified the domain of x as xdomain, and the value of y at the bottom limit of x as y0.
From my comments, you can solve this without MATLAB. Assuming non-zero x, you can use an integrating factor to get a 10000-by-1 solution y(x)
y_i(x) = b_i*x*ln(x) + c_i*x
with 10000-by-1 vector of constants c, where y_i(x), b_i and c_i are the i-th entries of y(x), b and c respectively. The constant vector c can be determined at some point x0 as
c_i = y_i(x0)/x_0 - b_i*ln(x0)

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]);

system of non-linear equations given in matrix form ( using fsolve)

I am trying to solve a system of nonlinear equations using fsolve. The system is given in the matrix form (image), u_i being the unknowns.
plz suggest how can I create the function to be given input to fsolve.
thanks
Check out the documentation for fsolve. You can create a function handle, either for a function in its own file or anonymously, and call it using fsolve:
h = #(U) P'*U.^2; % function handle
U_next = fsolve(h, U);
If you are doing an inner product, you also need to make sure that your left-hand side has the same number of columns as your right-hand side has rows. For instance, if you have some arbitrary 4x1 matrix P and initial 1x4 vector U, you have to take some transposes to make sure that your inner product works out:
P = rand(4, 1); % random column vector
U = rand(1, 4); % random row vector
h = #(U) P'*U'.^2; % (1x4) * (4x1) = scalar result
Or if you are trying to do element-wise multiplication:
h = #(U) P'.*U.^2; % (1x4) .* (1x4) = (1x4) result with element-wise multiplication

Get coefficients of symbolic polynomial in Matlab

I have a Matlab function that returns a polynomial of the form:
poly = ax^2 + bx*y + cy^2
where a, b, and c are constants, and x and y are symbolic (class sym).
I want to get the coefficients of the polynomial in the form [a b c], but I'm running into the following problem. If the function returns poly = y^2, then coeffs(poly) = 1. I don't want this – I want it to return [0 0 1].
How can I create a function that will give me the coefficients of a symbolic polynomial in the form that I want?
You can use sym2poly if your polynomial is a function of a single variable like your example y^2:
syms y
p = 2*y^2+3*y+4;
c = sym2poly(p)
which returns
c =
2 3 4
Use fliplr(c) if you really want the coefficients in the other order. If you're going to be working with polynomials it would probably also be a good idea not to create a variable called poly, which is the name of a function you might want to use.
If you actually need to handle polynomials in multiple variables, you can use MuPAD functions from within Matlab. Here is how you can use MuPAD's coeff to get the coefficients in terms of the order of variable they precede (x or y):
syms x y
p = 2*x^2+3*x*y+4*y;
v = symvar(p);
c = eval(feval(symengine,'coeff',p,v))
If you want to extract all of the information from the polynomial, the poly2list function is quite helpful:
syms x y
p = 2*x^2+3*x*y+4*y;
v = symvar(p);
m = eval(feval(symengine,'poly2list',p,v));
c = m(:,1); % Coefficients
degs = m(:,2:end); % Degree of each variable in each term
The polynomial can then be reconstructed via:
sum(c.*prod(repmat(v,[size(m,1) 1]).^degs,2))
By the way, good choice on where you go to school. :-)
There is also an alternative to this problem. For a given degree, this function returns a polynomial of that degree and its coefficients altogether.
function [polynomial, coefficeint] = makePoly(degree)
syms x y
previous = 0 ;
for i=0:degree
current = expand((x+y)^i);
previous= current + previous ;
end
[~,poly] = coeffs(previous);
for j= 1:length(poly)
coefficeint(j) = sym(strcat('a', int2str(j)) );
end
polynomial = fliplr(coefficeint)* poly.' ;
end
Hope this helps.