I am trying to evaluate a function which is an infinite cosine series at some input values.
EDIT: Posting an image to describe what the infinite series looks like
I wrote the following code to describe it in MATLAB.
function func = cosfun_hat(a,i)
syms m x;
assume(m,'integer');
assumeAlso(m > 0);
sum(x) = sqrt(1-a^2)*symsum(sqrt(2)*a^m*cos(i*sym(pi)*x*2^m+1),m,0,Inf);
func(x) = sum(x);
end
I want to evaluate the returned 'function' func to get numerical values for some input range say x_in = 0:0.001:1.
%Trying to evaluate func at x = 2
%In the command window I write
func = cosfun_hat(0.5,2);
func(2)
which returns the symbolic expression:
(2^(1/2)*3^(1/2)*sum((1/2)^m*(exp(- pi*exp(m*log(2))*4*i - i)/2 + exp(pi*exp(m*log(2))*4*i + i)/2), m == 0..Inf))/2
I tried using subs to evaluate the expression:
%In the command window
syms y;
w(y) = func(y);
y = 2;
subs(w);
But that returns the same symbolic expression. I am quite new to symbolic MATLAB.
Thanks!
EDIT Based on the comment by #NickyMattsson I tried
vpa(func(2))
which returns the numerical value of the expression.
However,
vpa(func(0.1)) returns a symbolic expression:
ans =
1.2247448713915890490986420373529*numeric::sum((1/2)^m*(exp(- (pi*exp(m*log(2))*i)/5 - i)/2 + exp((pi*exp(m*log(2))*i)/5 + i)/2), m == 0..Inf)
The same problem with using double(func(0.1)), double doesn't return anything and is stuck.
Figured out a way to do it without using symbolic MATLAB.
function func = cosfun_hat(a,i,x)
m = 0;
sum = zeros(1,length(x));
sum2 = Inf(1,length(x));
while max(sum2-sum) > 1e-16
disp(m);
sum2 = sum;
sum = sum + sqrt(1-a^2)*sqrt(2)*a^m*cos(i*pi*x*2^(m+1));
m = m+1;
end
func = sum;
end
The sum converges inside 100 iterations.
Now if I do,
%In command window
x_in = -2:0.001:2;
f = cosfun_hat(0.6,2,x_in);
plot(x_in,f);
I get the plot:
Thanks everyone for your help!
Use this command
double(func(2))
Related
I'm working on my own Matlab code for the bisection method, and have defined an anonymous function I am trying to find the root for. It produces a simple graph and I know it could easily find the root if it would run properly.
When my code gets up to evaluating the function at a given x value, it returns:
Error using feval
Function to evaluate must be represented as a string scalar, character vector, or
function_handle object.
Error in bisection (line 3)
fa = feval(f, a);
My full code is:
function m=bisection(f,a,b,imax,tol)
fa = feval(f, a);
fb = feval(f, b);
i=0;
if fa*fb>0
disp('No root here: pick a new interval')
return
end
while abs(b-a) >= tol
i = i + 1;
m=(a+b)/2;
fm = feval(f, m);
if fa*fb<0
b = m;
else
a = m;
end
abs(fm);
end
% Show the last approximation considering the tolerance
w = feval(f, m);
fprintf('\n x = %f produces f(x) = %f \n %i iterations\n', m, fm, i-1);
fprintf(' Approximation with tolerance = %f \n', tol);
end
With my function being:
function [T] = freezing(x)
alpha = 0.138*10^-6;
Ti = 20;
Ts = -15;
t = 60*60*24*60;
tol = 10^-13;
%x = linspace(0,3);
T = #(x) (Ti-Ts)*erf(x./(2*sqrt(alpha*t)))+Ts;
dT = #(x) (Ti-Ts)*(1/sqrt(pi*alpha*t))*exp(-x.^2./(4*alpha*t));
T = T(x);
end
I'm really not sure what the issue is here – in my command window, I can easily input x values and get output. Any suggestions are much appreciated!
feval needs f to be a function handle. When you call bisection, I suspect you're passing the result of freezing to bisection instead of the function handle to freezing
You need to do bisection(#freezing, ...) instead of bisection(freezing(...), ...)
The #freezing creates a function handle that is passed to bisection. Doing the latter passes the result of freezing to bisection.
I am trying to feed a function handle into the function I created below. I'm not exactly sure how to do this.
For example, how do I get:
conjugate_gradient(#(y) ABC(y), column_vector, initial_guess)
to not error?
If I use matlab's pcg function in the same way it will work:
pcg(#(y) ABC(y),b,tol).
I tried reading the pcg function, and they do take about this in the function description, however I'm still super inexperienced with MATLAB and had shall we say some difficulty understanding what they did.Thank You!
function [x] = conjugate_gradient(matrix, column_vector, initial_guess)
y = [];
col_size = length(column_vector);
temp = size(matrix);
mat_row_len = temp(2);
% algorithm:
r_cur = column_vector - matrix * initial_guess;
p = r_cur;
k = 0;
x_approx = initial_guess;
for i=1:mat_row_len
alpha = ( r_cur.' * r_cur ) / (p.' *(matrix* p));
x_approx = x_approx + alpha * p;
r_next = r_cur - alpha*(matrix * p);
fprintf(num2str(r_next'*r_next), num2str(i))
y = [y; i, r_next'*r_next];
%exit condition
if sqrt(r_next'*r_next) < 1e-2
y
break;
end
beta = (r_next.'* r_next )/(r_cur.' * (r_cur) );
p = r_next + beta * p;
k = k+1;
r_cur = r_next;
end
y
[x] = x_approx;
end
When you do
f = #(y) ABC(y)
You create a function handle. (Note that in this case it's the same as f=#ABC). This handle is a variable, and this can be passed to a function, but is otherwise the same as the function. Thus:
f(1)
is the same as calling
ABC(1)
You pass this handle to a function as the first argument, which you have called matrix. This seems misleading, as the variable matrix will now be a function handle, not a matrix. Inside your function you can do matrix(y) and evaluate the function for y.
However, reading your function, it seems that you treat the matrix input as an actual matrix. This is why you get errors. You cannot multiply it by a vector and expect a result!
I want to calculate the limit of log(CR(r))/log(r) as r tends to 0.
MATLAB code is written below.
function cd = CD(data)
syms r
cd = limit(log(CR(r,data))/log(r),r,0) ;
end
function val = hf(xi,xj,r)
dis = abs(xi-xj);
if(dis <= r)
val = 1;
else
val = 0 ;
end
end
function cr = CR(r,data)
N = length(data);
sum = 0;
for i = 1 : N
for j = i+1 : N
sum = sum + hf(data(i),data(j),r);
end
end
cr = sum/(N*(N-1));
end
Error:-
Well, the error message says it all really:
You can't use a symbolic variable in an equality check. How can you know if dis <= r when r doesn't have a value?
I'm obligated to say this:
Don't use sum as a variable name! It's a very important and useful builtin function. You're making it useless when doing that.
i and j are bad variable names in MATLAB, since they denote the imaginary unit (sqrt(-1)).
Also, did I remember to say: Dont use sum as a variable name!
PS! Your hf-function is equivalent to:
function val = hf(xi,xj,r)
var = abs(xi-xj) <= r; % Still doesn't work since r is symbolic
end
I am trying to sum a function and then attempting to find the root of said function. That is, for example, take:
Consider that I have a matrix,X, and vector,t, of values: X(2*n+1,n+1), t(n+1)
for j = 1:n+1
sum = 0;
for i = 1:2*j+1
f = #(g)exp[-exp[X(i,j)+g]*(t(j+1)-t(j))];
sum = sum + f;
end
fzero(sum,0)
end
That is,
I want to evaluate at
j = 1
f = #(g)exp[-exp[X(1,1)+g]*(t(j+1)-t(j))]
fzero(f,0)
j = 2
f = #(g)exp[-exp[X(1,2)+g]*(t(j+1)-t(j))] + exp[-exp[X(2,2)+g]*(t(j+1)-t(j))] + exp[-exp[X(3,2)+g]*(t(j+1)-t(j))]
fzero(f,0)
j = 3
etc...
However, I have no idea how to actually implement this in practice.
Any help is appreciated!
PS - I do not have the symbolic toolbox in Matlab.
I suggest making use of matlab's array operations:
zerovec = zeros(1,n+1); %preallocate
for k = 1:n+1
f = #(y) sum(exp(-exp(X(1:2*k+1,k)+y)*(t(k+1)-t(k))));
zerovec(k) = fzero(f,0);
end
However, note that the sum of exponentials will never be zero, unless the exponent is complex. Which fzero will never find, so the question is a bit of a moot point.
Another solution is to write a function:
function [ sum ] = func(j,g,t,X)
sum = 0;
for i = 0:2*j
f = exp(-exp(X(i+1,j+1)+g)*(t(j+3)-t(j+2)));
sum = sum + f;
end
end
Then loop your solver
for j=0:n
fun = #(g)func(j,g,t,X);
fzero(fun,0)
end
I am trying to compute the value of this integral using Matlab
Here the other parameters have been defined or computed in the earlier part of the program as follows
N = 2;
sigma = [0.01 0.1];
l = [15];
meu = 4*pi*10^(-7);
f = logspace ( 1, 6, 500);
w=2*pi.*f;
for j = 1 : length(f)
q2(j)= sqrt(sqrt(-1)*2*pi*f(j)*meu*sigma(2));
q1(j)= sqrt(sqrt(-1)*2*pi*f(j)*meu*sigma(1));
C2(j)= 1/(q2(j));
C1(j)= (q1(j)*C2(j) + tanh(q1(j)*l))/(q1(j)*(1+q1(j)*C2(j)*tanh(q1(j)*l)));
Z(j) = sqrt(-1)*2*pi*f(j)*C1(j);
Apprho(j) = meu*(1/(2*pi*f(j))*(abs(Z(j))^2));
Phi(j) = atan(imag(Z(j))/real(Z(j)));
end
%integration part
c1=w./(2*pi);
rho0=1;
fun = #(x) log(Apprho(x)/rho0)/(x.^2-w^2);
c2= integral(fun,0,Inf);
phin=pi/4-c1.*c2;
I am getting an error like this
could anyone help and tell me where i am going wrong.thanks in advance
Define Apprho in a separate *.m function file, instead of storing it in an array:
function [ result ] = Apprho(x)
%
% Calculate f and Z based on input argument x
%
% ...
%
meu = 4*pi*10^(-7);
result = meu*(1/(2*pi*f)*(abs(Z)^2));
end
How you calculate f and Z is up to you.
MATLAB's integral works by calling the function (in this case, Apprho) repeatedly at many different x values. The x values called by integral don't necessarily correspond to the 1: length(f) values used in your original code, which is why you received errors.