Error while calculating limit - Conversion to logic from syms is not possible - MATLAB -2014a - matlab

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

Related

How to calculate the expected value of a function with random normally distributed X?

I am trying to calculate on MatLab the Expectation for the function e^X where X ~ N(mu,sigma^2). In my example, mu = 0 and sigma = 1.
function [E] = expectedval(m,s)
%find E(e^x) with X~N(mu,sigma)
% mu = 0 , sigma = 1
X = normrnd(m,s);
f=exp(X);
mean(f)
So by the end I can run expectedval(0,1) to get my solution. The code runs with no issue, but I would like to compile a histogram to analyse the data with several runs. How may I collect this data with some sort of loop?
I'd appreciate any improvement ideas or suggestions!
Actually, your function just creates one random value for the given mean and variance... so there's actually no point in calculating a mean. On the top of that, the output E value is not assigned before the function finishes. The function can therefore be rewritten as follows:
function E = expectedval(m,s)
X = normrnd(m,s);
E = exp(X);
end
If you want to draw a sample from the normal distribution, and use the mean to compute the correct expected value, you can rewrite it as follows instead:
function E = expectedval(m,s,n)
X = normrnd(m,s,[n 1]);
f = exp(X);
E = mean(f);
end
And here is an example on how to run your function many times with different parameters, collecting the output on each iteration:
m = 0:4;
m_len = numel(m);
s = 1:0.25:2;
s_len = numel(s);
n = 100;
data = NaN(m_len*s_len,1);
data_off = 1;
for s = 1:s_len
for m = 1:m_len
data(data_off) = expectedval(m,s,n);
data_off = data_off + 1;
end
end

MATLAB - Finding Zero of Sum of Functions by Iteration

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

Fibonacci function not accepting 0 and not displaying the last term only

I wrote a function that displays the Fibonacci sequence up to the nth term. The code runs fine, but I want to make two changes and am not sure how to do so.
Here is my code:
function [ F ] = get_fib( k )
F(1) = 1;
F(2) = 1;
i = 3;
while k >= i;
F(i) = F(i-1) + F(i-2);
i = i + 1;
end
end
The first problem is that the code does not accept 0 as an input. I tried changing the function to:
function [ F ] = get_fib( k )
F(0) = 0;
F(1) = 1;
F(2) = 1;
i = 3;
while k >= i;
F(i) = F(i-1) + F(i-2);
i = i + 1;
end
end
But the following error appears:
Attempted to access F(0); index must be a positive integer or logical.
Error in get_fib (line 2)
F(0) = 0;
I would also like the code to display the last term in the sequence, rather than the entire sequence.
I changed the function to:
function [ F ] = get_fib( k );
F(1) = 1;
F(2) = 1;
i = 3;
while k >= i;
F(i) = F(i-1) + F(i-2);
i = i + 1;
end
term = F(k)
end
but the sequence it still being assigned to ans.
How can I make my function accept 0 as an argument and only display the last term of the sequence?
First let's get your function to output just the last item in the sequence. You're setting term like this:
term = F(k);
Which is good (notice I added the ; at the end, though). But the return value from your function is F. You need to change it to term.
function [ term ] = get_fib( k )
%// ^^^^- change this ^-- semicolon not necessary here
Now, to handle an input of 0, you can add a special check for zero:
function [ term ] = get_fib( k )
if k == 0
term = [];
return;
end
while k >= i
%// ^-- semicolon not needed here, either
<the rest of your code>
The semicolons after the function header and the while statement don't hurt anything, they just represent empty statements. But they might be misleading, so it's best to remove them.
The semicolon after the assignment to term prevents the ans = ... line from printing out to the console.
To address your first problem, F(0) is not a valid call. This is because MATLAB indexing starts from 1. In other words, the first element of a matrix is index 1. There is no 0th index of a matrix in MATLAB. See here for why MATLAB indexing starts from 1. What I would recommend to address this is to shift your output array by one index.
Thus, your code for the function should be:
function [ F ] = get_fib( k )
k = k + 1
F(1) = 0; % 0th Fibonacci term
F(2) = 1; % 1st Fibonacci term
F(3) = 1; % 2nd Fibonacci term
i = 4;
while k >= i
F(i) = F(i-1) + F(i-2);
i = i + 1;
end
term = F(k)
end
To address your second problem, it would depend on what you want. Do you (1) want the last term in the sequence to be returned when you call term = get_fib(k)or (2) want the last term of the sequence to be displayed and the entire sequence to be returned?
To achieve (1), fix the top line of your code to function term = F(k). To achieve (2), call the function with F = get_fib(some_number), as #rayryeng stated.
Since others already pointed out how to fix your code, I'd like to show you one approach to calculate the nth Fibonacci number without relying on the F(n-1) and F(n-2) terms calculation.
It involves the golden ratio, and you can read more about its relationship to the Fibonacci sequence here.
function [ F ] = get_fib( n )
% Changed your input variable from k to n (standard notation)
Phi = (1+sqrt(5))/2; % Golden ratio value
F = round((Phi^n - ((-1)^n)/(Phi^n))/sqrt(5)); %nth fibonacci number
end
Since you are only interested in the last value of the sequence, it could speed up the calculation for large values of n.
Note i have rounded the output (F) to avoid floating point arithmetic errors.

Stopping the output of a for cycle in matlab

I'm facing an issue with this simple Fibonacci number generator program:
function f = fibonr(n)
f(1) = 1;
f(2) = 1;
for i = 3:n
f(i) = f(i-1) + f(i-2);
end
end
If I want to display only the n-th number of the sequence, what adjustments should I make?
function f = fibonr(n)
f = zeros(n,1); %//initialise the output array
f(1,1) = 1;
f(2,1) = 1;
for ii = 3:n
f(ii,1) = f(ii-1,1) + f(ii-2,1);
end
%//create a string with text and variables
str = sprintf('The %d th number in the Fibonacci sequence is %d',n,f(ii,1));
disp(str) %//display your output.
end
first up: don't use i as a variable. Secondly, I switched to using column vectors, since MATLAB processes them faster, as well as I initialised the array, which is way faster (hence the shiny orange wiggles below your f(i)= line).
Call your function:
output = fibonr(10);
The 10 th number in the Fibonacci sequence is 55
If you use e.g. n=20 and still want the 10th argument just call output(10)
if you want the specified output right away you can use nargin. This code will give you all of the sequence if you call fibonr(n), or you can specify a vector to get the fibonacy numbers at said positions. If you are interested in both, your specified output and all the numbers, you can call the function with:
[output, fibnumbers] = fibonr(n,v);
function [output,f] = fibonr(n,v)
f(1) = 1;
f(2) = 1;
for i = 3:n
f(i) = f(i-1) + f(i-2);
end
if nargin() > 1
output = f(v);
else
output = f;
end

Plotting own function in scilab

Hey i have an issuse with plotting my own function in scilab.
I want to plot the following function
function f = test(n)
if n < 0 then
f(n) = 0;
elseif n <= 1 & n >= 0 then
f(n) = sin((%pi * n)/2);
else
f(n) = 1;
end
endfunction
followed by the the console command
x = [-2:0.1:2];
plot(x, test(x));
i loaded the function and get the following error
!--error 21
Invalid Index.
at line 7 of function lala called by :
plot(x, test(x))
Can you please tell me how i can fix this
So i now did it with a for loop. I don't think it is the best solution but i can't get the other ones running atm...
function f = test(n)
f = zeros(size(n));
t = length(n);
for i = 1:t
if n(i) < 0 then
f(i) = 0;
elseif n(i) <= 1 & n(i) >= 0
f(i) = sin((%pi * n(i)/2));
elseif n(i) > 1 then
f(i) = 1;
end
end
endfunction
I guess i need to find a source about this issue and get used with the features and perks matlab/scilab have to over :)
Thanks for the help tho
The original sin is
function f = test(n)
(...)
f(n) = (...)
(...)
endfunction
f is supposed to be the result of the function. Therefore, f(n) is not "the value that the function test takes on argument n", but "the n-th element of f". Scilab then handles this however it can; on your test case, it tries to access a non-integer index, which results in an error. Your loop solution solves the problem.
Replacing all three f(n) by f in your first formulation makes it into something that works... as long as the argument is a scalar (not an array).
If you want test to be able to accept vector arguments without making a loop, the problem is that n < 0 is a vector of the same size as n. My solution would use logical arrays for indexing each of the three conditions:
function f = test(n)
f = zeros(size(n));
negative = (n<0);//parentheses are optional, but I like them for readability
greater_than_1 = (n>1);
others = ~negative & ~greater_than_1;
f(isnegative)=0;
f(greater_than_1)=1;
f(others) = sin(%pi/2*n(others));
endfunction