Call arguments in a function in MATLAB - function

I tried to run this function in MATLAB:
function llik = log_likelihood(p)
global d;
N = length(d);
tau = fzero(#(t) (t - (t^2 * p + 1 - p) / (2 * (t * p + 1 - p))), [0,1]);
loglik = 0;
for i = 1 : N
loglik = loglik + log(isnan(d(i)) * (1 - p * (1 - tau) + ~isnan(d(i))* p * (1 - tau)));
end
llik = loglik / N;
end
Here, p is a scalar. MATLAB gives me an error warning saying
Error using fzero>localFirstFcnEval
FZERO cannot continue because user-supplied function_handle ==>
#(t)(t-(t^2*p+1-p)/(2*(t*p+1-p))) failed with the error below.
Unrecognized function or variable 'p'.
I am confused since p should be the argument of the function. How can it be unrecongized? Thank you for your help!

Everything seems okay with my Matlab if i assign the value d inside the function, where do you define the variable d, if it's a global variable, it must be define as:
global d;
This is my result:

Related

Matlab - Undefined function 'int_f_1' for input arguments of type 'double'

Currently, I am working on a program that integrates x + x^2 + e^x + 2cos(x/2) - 1 with three input variables, a, b, and n. What I need returned is the numerical integral from a to b with n increments. The function also has to return trapezoids for each n as a column vector. Thus, the integral value as a scalar, and a vector of values.
I've gotten to a point where the function int_f_1 is undefined for some reason, and I have no idea why. I thought by nesting that function under the test function, it would help. But it does not, and I don't know why that is. Any suggestions?
function [y] = test_function_1(x);
y = x + x.^2 + exp(x) + 2*cos(x/2) - 1
end
function [int_f, increment] = int_f_1 (a, b, n);
f = #test_function_1;
h = a + b ./ n
increments = h
int_f = integral(h, f)
end

How do I convert Matlab script to function

I wrote my script for a class but the next step is to convert that script into a function. What do I type in?
This is my script:
% Find max volume
b = 2.75; %ft for diameter
h = 3.00; %ft for height
v = (b*h)/3; %ft^3
% use volume to find mass
p = 62.3;
m = p*v;
The following syntax is used to create a function in MATLAB:
function [y1,...,yN] = myfun(x1,...,xM)
In the example below, the maximumVolume() method takes 3 parameters (b, h, p) and returns the value of the m variable.
result = maximumVolume(2.75, 3.0, 62.3);
function m = maximumVolume(b, h, p)
v = (b * h)/3;
m = p * v;
end
References
function

Undefined argument when declaring function in Octave

I get undefined variable/argument when trying to define my own random generator function.
Code:
function result = myrand(n, t, p, d)
a = 200 * t + p
big_rand = a * n
result = big_rand / 10**d
return;
endfunction
mrand = myrand(5379, 0, 91, 4)
error:
>> myrand
error: 't' undefined near line 2 column 15
error: called from
myrand at line 2 column 7
You can't start a script with a function keyword.
https://www.gnu.org/software/octave/doc/v4.0.1/Script-Files.html
This works:
disp("Running...")
function result = myrand(n, t, p, d)
a = 200 * t + p
big_rand = a * n
result = big_rand / 10**d
return;
endfunction
mrand = myrand(5379, 0, 91, 4)
You should get:
warning: function 'myrand' defined within script file 'myrand.m'
Running ...
a = 91
big_rand = 489489
result = 48.949
mrand = 48.949

Octave variable definition error

I'm trying to generate Blackman-Harris window coefficients in Octave. I have declared a function in a .m file like so:
function result = BlackmanHarris(window_size)
a0 = 0.35875
a1 = 0.48829
a2 = 0.14128
a3 = 0.01168
result = [0:window_size - 1];
if(nargin != 1)
print_usage("BlackmanHarris(int window_size)");
endif
if(isinteger(window_size))
for n = 0:window_size - 1
result(n) = a0 - (a1 * cos((2 * pi * n)/(window_size - 1))) + (a2 * cos((4 * pi * n)/(window_size - 1))) - (a3 * cos((6 * pi * n)/(window_size - 1)));
endfor
else
error("BlackmanHarris: Expecting integer argument.");
endif
endfunction
When I attempt to run this, I get the error:
>> window = BlackmanHarris(window_size);
error: 'a0' undefined near line 15 column 16
error: called from
BlackmanHarris at line 15 column 14
I have tried declaring the variables as 'global' and 'persistent', nether of which solve this issue. I'm sure I'm just doing something slightly wrong, but Google has yielded little help on this.
Thanks in advance.
As #Sardar_Usama said, I was attempting to access element 0 of the result array, which of course will not work.
Changing that to n+1 fixed the issue.

Intersection of parabolic curve and line segment

I have an equation for a parabolic curve intersecting a specified point, in my case where the user clicked on a graph.
// this would typically be mouse coords on the graph
var _target:Point = new Point(100, 50);
public static function plot(x:Number, target:Point):Number{
return (x * x) / target.x * (target.y / target.x);
}
This gives a graph such as this:
I also have a series of line segments defined by start and end coordinates:
startX:Number, startY:Number, endX:Number, endY:Number
I need to find if and where this curve intersects these segments (A):
If it's any help, startX is always < endX
I get the feeling there's a fairly straight forward way to do this, but I don't really know what to search for, nor am I very well versed in "proper" math, so actual code examples would be very much appreciated.
UPDATE:
I've got the intersection working, but my solution gives me the coordinate for the wrong side of the y-axis.
Replacing my target coords with A and B respectively, gives this equation for the plot:
(x * x) / A * (B/A)
// this simplifies down to:
(B * x * x) / (A * A)
// which i am the equating to the line's equation
(B * x * x) / (A * A) = m * x + b
// i run this through wolfram alpha (because i have no idea what i'm doing) and get:
(A * A * m - A * Math.sqrt(A * A * m * m + 4 * b * B)) / (2 * B)
This is a correct answer, but I want the second possible variation.
I've managed to correct this by multiplying m with -1 before the calculation and doing the same with the x value the last calculation returns, but that feels like a hack.
SOLUTION:
public static function intersectsSegment(targetX:Number, targetY:Number, startX:Number, startY:Number, endX:Number, endY:Number):Point {
// slope of the line
var m:Number = (endY - startY) / (endX - startX);
// where the line intersects the y-axis
var b:Number = startY - startX * m;
// solve the two variatons of the equation, we may need both
var ix1:Number = solve(targetX, targetY, m, b);
var ix2:Number = solveInverse(targetX, targetY, m, b);
var intersection1:Point;
var intersection2:Point;
// if the intersection is outside the line segment startX/endX it's discarded
if (ix1 > startX && ix1 < endX) intersection1 = new Point(ix1, plot(ix1, targetX, targetY));
if (ix2 > startX && ix2 < endX) intersection2 = new Point(ix2, plot(ix2, targetX, targetY));
// somewhat fiddly code to return the smallest set intersection
if (intersection1 && intersection2) {
// return the intersection with the smaller x value
return intersection1.x < intersection2.x ? intersection1 : intersection2;
} else if (intersection1) {
return intersection1;
}
// this effectively means that we return intersection2 or if that's unset, null
return intersection2;
}
private static function solve(A:Number, B:Number, m:Number, b:Number):Number {
return (m + Math.sqrt(4 * (B / (A * A)) * b + m * m)) / (2 * (B / (A * A)));
}
private static function solveInverse(A:Number, B:Number, m:Number, b:Number):Number {
return (m - Math.sqrt(4 * (B / (A * A)) * b + m * m)) / (2 * (B / (A * A)));
}
public static function plot(x:Number, targetX:Number, targetY:Number):Number{
return (targetY * x * x) / (targetX * targetX);
}
Or, more explicit yet.
If your parabolic curve is
y(x)= A x2+ B x + C (Eq 1)
and your line is
y(x) = m x + b (Eq 2)
The two possible solutions (+ and -) for x are
x = ((-B + m +- Sqrt[4 A b + B^2 - 4 A C - 2 B m + m^2])/(2 A)) (Eq 3)
You should check if your segment endpoints (in x) contains any of these two points. If they do, just replace the corresponding x in the y=m x + b equation to get the y coordinate for the intersection
Edit>
To get the last equation you just say that the "y" in eq 1 is equal to the "y" in eq 2 (because you are looking for an intersection!).
That gives you:
A x2+ B x + C = m x + b
and regrouping
A x2+ (B-m) x + (C-b) = 0
Which is a quadratic equation.
Equation 3 are just the two possible solutions for this quadratic.
Edit 2>
re-reading your code, it seems that your parabola is defined by
y(x) = A x2
where
A = (target.y / (target.x)2)
So in your case Eq 3 becomes simply
x = ((m +- Sqrt[4 A b + m^2])/(2 A)) (Eq 3b)
HTH!
Take the equation for the curve and put your line into y = mx +b form. Solve for x and then determine if X is between your your start and end points for you line segment.
Check out: http://mathcentral.uregina.ca/QQ/database/QQ.09.03/senthil1.html
Are you doing this often enough to desire a separate test to see if an intersection exists before actually computing the intersection point? If so, consider the fact that your parabola is a level set for the function f(x, y) = y - (B * x * x) / (A * A) -- specifically, the one for which f(x, y) = 0. Plug your two endpoints into f(x,y) -- if they have the same sign, they're on the same side of the parabola, while if they have different signs, they're on different sides of the parabola.
Now, you still might have a segment that intersects the parabola twice, and this test doesn't catch that. But something about the way you're defining the problem makes me feel that maybe that's OK for your application.
In other words, you need to calulate the equation for each line segment y = Ax + B compare it to curve equation y = Cx^2 + Dx + E so Ax + B - Cx^2 - Dx - E = 0 and see if there is a solution between startX and endX values.