I'm trying to run this function like this: calcSQNRA(0,4,6) and I'm getting these errors:
??? Error using ==> mtimes Inner matrix dimensions must agree.
Error in ==> calcSQNRA>#(x)x.^2*e.^(-x) at 6 f = #(x) x.^2 * e.^(-x);
Error in ==> quadl at 70 y = feval(f,x,varargin{:}); y = y(:).';
Error in ==> calcSQNRA at 7 x = 10 * log10(3 * 4^t *
quadl(f,xmin,xmax));
function [x] = calcSQNRA(xmin, xmax, N)
e = exp(1);
t = log2(N);
f = #(x) x.^2 * e.^(-x);
x = 10 * log10(3 * 4^t * quadl(f,xmin,xmax));
The function is trying to compute the SQNR of an exponential distribution (if I thought of it correctly), after a uniform quantization. Note that if I erase the e.^(-x) from f it actually produces a result. Any ideas?
I kill 15 minutes debugging quadl and feval functions. And going so deep in this process I just think about this simple thing:
it just works if I set . in your f anonymous function this way:
f = #(x) x.^2 .* e.^(-x);
then
calcSQNRA(0,4,6) give result: 22.1635.
Is it what you want to achieve?
Related
I'm wondering if it's possible to multiplying a function for a rectangularPulse.
I tried to wrote this code, but it's wrong:
Tc = 0.01;
t = [0:Tc:3];
y = t.^2 * rectangularPulse(1,2,t);
Can you tell me if there is a solution (I want to use rectangularPulse, not other function)?
The error is the following:
Error using *
Inner matrix dimensions must agree.
Error in aaa (line 12)
y = t.^2 * rectangularPulse(1,2,t);
Thank you for your time.
The multiplication should be a element-wise multiplication:
y = t.^2 .* rectangularPulse(1,2,t);
I'm having difficulty using the fsolve function to solve a set of 5 equations in Matlab.
Here are the 5 equations:
y = a + d + e
y + x = c + d + 2e
2x = 4a + 2b + 2c
k1 = (d * b^3 / (a * c) ) * ((P/Pref)/(a+b+c+d+e))^2
k2 = be/(dc)
y,x,k1,k2,P,Pref are all parameters that I set, but would like to leave them in the function so that I can change them quickly in my code to find new answers. a,b,c,d,e are the variables that I'd like to solve for (they are compositions of a reaction equilibrium equation)
I tried to hard code the parameters in the function, but that didn't work. I'm just not sure what to do. Every thing I change creates a new error. The most common is that the data type has to be "double".
Edit: adding code
first the function:
function F = myfun(Q,I)
a = Q(1);
b = Q(2);
c = Q(3);
d = Q(4);
e = Q(5);
x = I(1);
y = I(2);
k1 = I(3);
k2 = I(4);
P = I(5);
Pref = I(6);
F(1) = a + d + e - y;
F(2) = c + d + 2*e - y - x;
F(3) = 4*a + 2*b + 2*c - 2*x;
F(4) = ((d * b^3)/(a*c))*((P/Pref)/(a+b+c+d+e))^2 - k1;
F(5) = (b*e)/(c*d);
next is the program:
%Q = [a,b,c,d,e]
%I = [x,y,k1,k2,P,Pref]
%The values for the inputs will be changed to vary the output
%Inputs:
x=5;
y=1;
k1=5;
Pref=1;
P=1;
k2=-0.01;
syms K
k1 = solve(log10(k1) - k1);
syms L
k2 = solve(log10(k2) - k2);
x = double(x);
y = double(y);
Pref = double(Pref);
P = double(P);
k1 = double(k1);
k2 = double(k2);
%Solving:
I = [x,y,k1,k2,P,Pref];
q = [0,0,0,0,0]; %initial guess
Q = fsolve(#myfun,[q,I])
when I run this, these errors comes up:
Error using myfun (line 7)
Not enough input arguments.
Error in fsolve (line 218)
fuser = feval(funfcn{3},x,varargin{:});
Error in Coal (line 27)
Q = fsolve(#myfun,[q,I])
Caused by:
Failure in initial user-supplied objective function evaluation. FSOLVE cannot continue.
Edit 2: changed the fsolve line, but still got errors:
Error using trustnleqn (line 28)
Objective function is returning undefined values at initial point. FSOLVE cannot continue.
Error in fsolve (line 376)
[x,FVAL,JACOB,EXITFLAG,OUTPUT,msgData]=...
Error in Coal (line 27)
fsolve(#(q) myfun(q,I),q)
Edit3: changed a couple parameters and the initial guess, I am now getting an answer, but it also comes up with this:
Solver stopped prematurely.
fsolve stopped because it exceeded the function evaluation limit,
options.MaxFunEvals = 500 (the default value).
ans =
0.0000 2.2174 3.7473 1.4401 3.8845
how can I get it to not stop prematurely?
Re: how can I get it to not stop prematurely?
Pass non-default options in your call to fsolve.
Refer to the signature, fsolve(myfun,q,options) here,
http://www.mathworks.com/help/optim/ug/fsolve.html
And read about creating the options using optimoptions here,
http://www.mathworks.com/help/optim/ug/optimoptions.html
You should be able to get it to "not stop prematurely" by increasing the values of convergence criteria such as TolFun and TolX.
However, it's advisable to read up on the underlying algorithms you're relying upon to perform this numerical solution here,
(EDIT: I tried to fix non-linky links, but I'm not allowed to provide more than two ... Boo) www.mathworks.com/help/optim/ug/fsolve.html#moreabout
The error you received simply indicates that after 500 function evaluations the algorithm has not yet converged on an acceptable solution conforming to the default solver options. Just increasing MaxFunEvals may allow the algorithm extra iterations needed to converge within default tolerances. For example,
options = optimoptions('MaxFunEvals',1000); % try something bigger than 500
fsolve(#(q) myfun(q,I),q,options);
I'm trying to minimize an objective function that contains absolute terms including some of the variables. The target function looks like this (I'll only write down two terms, the actual problem contains between 500 and 5000, depending on other parameters):
min |f_11 * x_1 + f_21 * x_2 - y_1| + |f_12 * x_1 + f_22 * x_2 - y_2|
There can also be different types of constraints. Since I don't have the Symbolic Toolbox I have no clue how to put this into Matlab.
I thought of interpreting this as a quadratic program, where I square each term and get the squareroot of it. With an anonymous function this would look like this I think:
f = #(X) sqrt((F*X - Y) .* (F*X - Y)) * ones(size(Y));
Where F and Y contain the values of f_ij and y_j. So in my case F ís of size ix2, Y is of size ix1 and X is of size 1x2.
The problem here is, I can't calculate the numerical hessian via the DERIVESTsuite (http://www.mathworks.com/matlabcentral/fileexchange/13490-adaptive-robust-numerical-differentiation). I'll get the error:
Error using *
Inner matrix dimensions must agree.
Error in calcHq>#(W)sqrt((F*W-Y).*(F*W-Y))*ones(size(Y)) (line 16)
f = #(W) sqrt((F*W - Y) .* (F*W - Y)) * ones(size(Y));
Error in hessdiag>#(xi)fun(swapelement(x0,ind,xi)) (line 60)
#(xi) fun(swapelement(x0,ind,xi)), ...
Error in derivest (line 337)
f_x0(j) = fun(x0(j));
Error in hessdiag (line 59)
[HD(ind),err(ind),finaldelta(ind)] = derivest( ...
Error in hessian2 (line 74)
[hess,err] = hessdiag(fun,x0);
I assume there is some problem with the elementwise multiplication, but I really can't figure out what I'm doing wrong.
Maybe someone can give me a hint on what I'm doing wrong.
Ok guys, thank you very much. I just found out what I did wrong and it is so embarassing ...
The order of multiplications is wrong ...
f = #(X) sqrt((F*X - Y) .* (F*X - Y)) * ones(size(Y));
This gives back an ixi matrix, while
f = #(X) ones(size(Y)) * sqrt((F*X - Y) .* (F*X - Y));
gives back a scalar.
I am trying to compute log(N(x | mu, sigma)) in MATLAB where
x is the data vector(Dimensions D x 1) , mu(Dimensions D x 1) is mean and sigma(Dimensions D x D) is covariance.
My present implementation is
function [loggaussian] = logmvnpdf(x,mu,Sigma)
[D,~] = size(x);
const = -0.5 * D * log(2*pi);
term1 = -0.5 * ((x - mu)' * (inv(Sigma) * (x - mu)));
term2 = - 0.5 * logdet(Sigma);
loggaussian = const + term1 + term2;
end
function y = logdet(A)
y = log(det(A));
end
For some cases I get an error
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
NaN
I know you will point out that my data is not consistent, but I need to implement the function so that I can get the best approximate instead of throwing an warning. . How do I ensure that I always get a value.
I think the warning comes from using inv(Sigma). According to the documentation, you should avoid using inv where its use can be replaced by \ (mldivide). This will give you both better speed and accuracy.
For your code, instead of inv(Sigma) * (x - mu) use Sigma \ (x - mu).
The following approach should be (a little) less sensitive to ill-conditioning of the covariance matrix:
function logpdf = logmvnpdf (x, mu, K)
n = length (x);
R = chol (K);
const = 0.5 * n * log (2 * pi);
term1 = 0.5 * sum (((R') \ (x - mu)) .^ 2);
term2 = sum (log (diag (R)));
logpdf = - (const + term1 + term2);
end
If K is singular or near-singular, you can still have warnings (or errors) when calling chol.
I'm trying build a matlab function that will evaluate a function and vector that are sent in as parameters. I'm having a hard time trying to figure out how to send in the function so that it can be evaluated in the matlab function. I figured out how to do it without the function but I'm a little lost trying to evaluate it within a matlab function. Below is my code...
This is what I'm trying to do...
x = [x1 x2]';
f = x(x1)^2 + 2 * (x2)^2
x = [5 10];
f = (5)^2 + 2 * (10)^2 % which I would like to return 225, not a column vector
This is what I have and what I have tried...
x = [5 10]';
% without using a matlab function
% k = 1
% f = x(k)^2 + 2 * x(k + 1)^2; % returns the correct answer of 225
f = x^2 + 2 * x^2 % complains about the scalar 2
f = x.^2 + 2 * x.^2 % returns a column vector [75; 300]
function [value] = evalFunction(f,x)
value = f(x);
I've tried...
f = #(x) x.^2 + 2 * (x+1).^2;
value = evalFunction(#f,x) %Error: "f" was previously used as a variable
So I tried...
f = #(x) x.^2 + 2 * (x+1).^2;
value = evalFunction(f,x) %value = [97;342]
I'm new to matlab so any help is appreciated. I've been doing some research and found some stuff here on stackoverflow but can't seem to get it to work. I've seen there are other ways to do this, but I will eventually be adding more code to the matlab evalFunction function so I'd like to do it this way. Thanks!
Anonymous functions and function handles plus array indexing. Taking x as a 2-element vector, define and use your function like:
f = #(x) x(1).^2 + 2 * x(2).^2;
value = evalFunction(f,x) % but you can just do f(x) if that is all you need
However, if evalFunction does nothing other than evaluate f at x, then you don't need it at all. Just do f(x).
Alternately,
f = #(x1,x2) x1.^2 + 2*x2.^2;
value = evalFunction(f,x1,x2); % here your function will call it by f(x1,x2)
You are probably coming at this from a C background - in Matlab, x+1 is the entire vector x with 1 added - not the element offset by 1.
The function you need is
f = #(x)x(1).^2 + 2 * (x(2)).^2;
or, to be a little more "matlab-like":
f = #(x) [1 2] * x(1:2)'.^2;
Which performs the element-wise square of the first two elements of x as a column vector, and then does the matrix multiplication with [1 2], resulting in
1 * x(1) .^2 + 2 * x(2) .^2;
Which seems to be what you were asking for.
caveat: did not have opportunity to test this...