matlab Dimensions of matrices being concatenated are not consistent - matlab

here is my code:
C=#(k) [k,k,2.*k;3,2.*k,5;1,k,k];
AV=#(k,t) [3*t, 6, 9]*C(k)*[3*t ;6 ;9];
avaint=#(k,a,b) quadgk(#(k) AV(k,t),a,b);
AVAR=#(t) avaint(t,0,87600);
Is shows:
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
when I want to print AVAR(3)

Source of Error
The quadgk function passes a vector of integration points to the function handle given to it.
From the documentation:
The function y = fun(x) should accept a vector argument x and return a vector result y, where y is the integrand evaluated at each element of x.
This creates the dimension mismatch causing the error.
Solutions
To get around this implementation, you can perform the numerical integration using the integral function with the ('ArrayValued',true) option pair:
avaint = #(t,a,b) integral(#(k) AV(k,t),a,b,'ArrayValued',true);
Or, you can use arrayfun within AV to abide by the requirement of quadgk:
AV = #(k,t) arrayfun(#(k_el) [3*t, 6, 9]*(C(k_el)*[3*t ;6 ;9]),k);

Related

MATLAB - integral function vectorization warning

When trying to use the integral2 function, I get the following warning:
"Integrand function outputs did not match to the required tolerance when the same input values were supplied in two separate calls with different size input matrices. Check that the function is vectorized properly."
My code is:
z1=0; z2=5;
t1=0; t2=10;
a=1:500;
b=linspace(0.15,0.02,length(a));
c=[a;b];
d=4.9e-07;
func = #(z,t) my_func((z + t),c) .* exp(-d.*t);
int_x = integral2(func,z1,z2,t1,t2,'RelTol',1e-3,'AbsTol',1e-3) ./ (z2 - z1);
my_func is:
function out = my_func(z_in,c)
z=reshape(z_in,1,numel(z_in));
for i=1:length(z)
if (z(i)<0.0)
z(i)=0.0;
end
end
expfactor=exp(-z/150);
sB=5.5*0.9*4*expfactor;
mB=0.9*interpolate(c(1,:),c(2,:),z);
out=sB+mB;
out=reshape(out,size(z_in,1),size(z_in,2));
end
z1=0, z2=9.6, t1=0, t2=3000 (i.e. all have the size (1,1)), and I have used element-wise operations, so not sure what the problem is.
When debugging, my_func is called three times, with z and t having different sizes each time (although same as each other; (14,14), (2,3) and (14,14)). When sizes are (14,14), the values of z are unique for each column, but the same for each row (e.g. [3,2,1;3,2,1]), and vice versa for t (e.g. [4,4,4;5,5,5]). But when sizes are (2,3), all values in the z and t matrices are unique. The warning comes after the second and third call.
What could be the reasons for the warning?
Edit: to accommodate the dimension requirements in my_func, I've reshaped z to a vector at the start, then reshaped the output back to matrix at the end, copying a similar function I've seen. But this returns the warning:
"Non-finite result. The integration was unsuccessful. Singularity likely."
Thanks

Using `lsqnonlin` with vector inputs

I have a question about using the lsqnonlin function.
In my case I have two functions:
f_1=#(t,x)sin(t+x.^2);
f_2=#(t,x)cos(x.^2)+3.*t.^2;
f = {f_1, f_2};
I want to find the values of the arguments t and x which would result in the least square error, defined as: f_1(t,x)^2+f_2(t,x)^2. In other words, argmin for LSE.
My code is as follow with initial guess [1,2]:
lsqnonlin(f,[1,2])
And I'm getting the error:
Error in lsqnonlin (line 196)
initVals.F = feval(funfcn{3},xCurrent,varargin{:});
Caused by:
Failure in initial objective function evaluation. LSQNONLIN cannot continue.
lsqnonlin can be used for vector function and vector input according to the documentation. I wonder how to prepare corresponding codes for it. Could anyone suggest the solution?
You are getting an error because lsqnonlin expects a scalar function handle that maps a vector to a vector, whereas you specify a cell array of function handles. To fix this, instead of a vector of functions outputting one scalar each, you need to rewrite it into a single function that accepts a vector of inputs and also outputs a vector:
f = #(xt)[sin(xt(2)+xt(1).^2), cos(xt(1).^2)+3.*xt(2).^2];
% xt = [x,t]
% f = [f_1(xt), f_2(xt)]
so f and xt are both vectors of 2 elements.
Then, the solver works:
lsqnonlin(f,[1,2])
ans =
1.6144 0.5354

Using matlab fit object as a function

Matlab fit is no doubt useful but it is not clear how to use it as a function
apart from trivial integration and differentiation given on the official website:
http://uk.mathworks.com/help/curvefit/example-differentiating-and-integrating-a-fit.html
For example given a fit stored in the object 'curve' one can evaluate
curve(x) to get a number. But how one would, e.g. integrate |curve(x)|^2 (apart from clumsily creating a new fit)? Trying naively
curve = fit(x_vals,y_vals,'smoothingspline');
integral(curve(x)*curve(x), 0, 1)
gives an error:
Output of the function must be the same size as the input. If FUN is an array-valued integrand, set the 'ArrayValued' option to true.
I have also tried a work around by definining a normal function and an implicit function for the integrand (below) but both give the same error.
func=#(x)(curve(x))...; % trial solution 1
function func_val=func(curve, x)...; % trial solution 2
Defining function for the integrand followed by integration with option 'ArrayValued' set to 'true' works:
func=#(x)(curve(x)*curve(x));
integral(func,0,1,'ArrayValued',true)
You need to have the function vectorized, i.e use element-wise operations like curve(x).*curve(x) or curve(x).^2.
Also make sure that the shape of the output matches the input, i.e a row input gives a row output, similarly a column comes out as a column. It seems that evaluating the fit object always returns a column vector (e.g. f(1:10) returns a 10x1 vector not 1x10).
With that said, here is an example:
x = linspace(0,4*pi,100)';
y = sin(x);
y = y + 0.5*y.*randn(size(y));
f = fit(x, y, 'smoothingspline');
now you can integrate as:
integral(#(x) reshape(f(x).^2,size(x)), 0, 1)
in this case, it can be simplified as a simple transpose:
integral(#(x) (f(x).^2)', 0, 1)

integral2 with fun calculated using vector

Im new to MATLAB. Want to use integral2 as follows
function num = numer(x)
fun=#(p,w) prod((p+1-p).*(1-w).*exp(w.*x.*x/2))
num= integral2(fun ,0,1,0,1)
end
I get several errors starting with
Error using .*
Matrix dimensions must agree.
Error in numer>#(p,w)prod(p+(1-w).*exp(w.*x.*x/2)) (line 5)
fun=#(p,w) prod(p+(1-w).*exp(w.*x.*x/2))
Can you please tell me what I do wrong.
Thanks
From the help for integral2:
All input functions must accept arrays as input and operate
elementwise. The function Z = FUN(X,Y) must accept arrays X and Y of
the same size and return an array of corresponding values.
When x was non-scalar, your function fun did not do this. By wrapping everything in prod, the function always returned a scalar. Assuming that your prod is in the right place to begin with and taking advantage of the properties of the exponential, I believe this version will do what you need for vector x:
x = [0 1];
lx = length(x);
fun = #(p,w)(p+1-p).^lx.*(1-w).^lx.*exp(w).^sum(x.*x/2);
num = integral2(fun,0,1,0,1)
Alternatively, fun = #(p,w)(p+1-p).^lx.*(1-w).^lx.*exp(sum(x.*x/2)).^w; could be used.

MATLAB: sym function does not works

In matlab I want to create symbolic vector:
X = sym(['x_n' 'x_(n-1)' 'x(n-2)'])
however, I get
??? Error using ==> sym.sym>expression2ref at 2408
Error: Unexpected 'identifier' [line 1, col 11]
Error in ==> sym.sym>char2ref at 2378
s = expression2ref(x);
Error in ==> sym.sym>tomupad at 2147
S = char2ref(x);
Error in ==> sym.sym>sym.sym at 102
S.s = tomupad(x,'');
if I try create, e.g. just X = sym(['x_n' 'x_(n-1)']), it's ok, so what's wrong?
If you want to create a symbolic vector (or matrix) you just need one set of quotes around the square brackets:
X = sym('[x_(n) x_(n-1) x_(n-2)]')
Or
X = sym('[x_(n);x_(n-1);x_(n-2)]')
I'm assuming that you had typos in the first and third element of the vector and desire to define x_ as a function of n (if not, see below). However, this often isn't the most flexible way of building symbolic arrays. I'd use the syms function instead of sym and avoid building strings (though sometimes creating large vector/matrix equations systematically with strings can be easier):
syms x_(n)
X = [x_(n) x_(n-1) x_(n-2)]
Lastly, as the help for sym indicates, one can also automatically create vectors and matrices of enumerated variables, e.g.:
X = sym('x_',[1 3])
If you don't actually want to specify a vector of functions, then this option is very convenient.