Matlab error: input argument not defined - matlab-guide

I wrote the function as:
function f = factorial(x)
f = prod(1:x);
f =factorial(5);
end
But when I tried running it, it says input argument not defined.
What's wrong with this?

You have defined a function which recurses endlessly.
f = factorial(5);
in the third line will call your function again, which will then again call your function once it reaches the third line, which then again will call your function... so it will never get done.
When implementing a recursive solution you need to provide a base case. Here's an example for calculating factorials.
function f = factorial(x)
if x == 0 % this is the base case
f = 1;
else
f = x*factorial(x-1); % this is the recursive case
end
end
example:
>> factorial(5)
ans =
120
As for your
input argument not defined
problem, you need to tell us what you actually used as an input argument. For the above example, any* integer x>=0 should work.
*as long as f has enough bytes to hold the result.

Related

Execution time julia program to count primes

I am experimenting a bit with julia, since I've heard that it is suitable for scientific calculus and its syntax is reminiscent of python. I tried to write and execute a program to count prime numbers below a certain n, but the performances are not the ones hoped.
Here I post my code, with the disclaimer that I've literally started yesterday in julia programming and I am almost sure that something is wrong:
n = 250000
counter = 0
function countPrime(counter)
for i = 1:n
# print("begin counter= ", counter, "\n")
isPrime = true
# print("i= ", i, "\n")
for j = 2:(i-1)
if (i%j) == 0
isPrime = false
# print("j= ", j, "\n")
break
end
end
(isPrime==true) ? counter += 1 : counter
# print("Counter= ", counter, "\n")
end
return counter
end
println(countPrime(counter))
The fact is that the same program ported in C has about 5 seconds of execution time, while this one in julia has about 3 minutes and 50 seconds, which sounds odd to me since I thought that julia is a compiled language. What's happening?
Here is how I would change it:
function countPrime(n)
counter = 0
for i in 1:n
isPrime = true
for j in 2:i-1
if i % j == 0
isPrime = false
break
end
end
isPrime && (counter += 1)
end
return counter
end
This code runs in about 5 seconds on my laptop. Apart from stylistic changes the major change is that you should pass n as a parameter to your function and define the counter variable inside your functions.
The changes follow one of the first advices in the Performance Tips section of the Julia Manual.
The point is that when you use a global variable the Julia compiler is not able to make assumptions about the type of this variable (as it might change after the function was compiled), so it defensively assumes that it might be anything, which slows things down.
As for stylistic changes note that (isPrime==true) ? counter += 1 : counter can be written just as isPrime && (counter += 1) as you want to increment the counter if isPrime is true. Using the ternary operator ? : is not needed here.
To give a MWE of a problem with using global variables in functions:
julia> x = 10
10
julia> f() = x
f (generic function with 1 method)
julia> #code_warntype f()
MethodInstance for f()
from f() in Main at REPL[2]:1
Arguments
#self#::Core.Const(f)
Body::Any
1 ─ return Main.x
You can see that here inside the f function you refer to the global variable x. Therefore, when Julia compiles f it must assume that the value of x can have any type (which is called in Julia Any). Working with such values is slow as the compiler cannot use any optimizations that would take advantage of more specific type of value processed.

How to write a subroutine for initial condition in Nonlinear Schrodinger Equation that depends on x

I am solving Nonlinear Schrodinger equation by split-step Fourier method:
i df/dz+1/2* d^2f/dX^2+|f|^2*f=0
using an initial condition:
f=q*exp(-(X/X0)^24).
But I have to use the condition that q=1 for |x|<1, otherwise, q=0.
So I write the following subroutine (excerpt of the code involving transverse variable) for transverse variable x:
fs=120;
N_fx=2^11; %number of points in frequency domain
dX=1/fs;
N_X=N_fx;
X=(-(N_X-1)/2:(N_X-1)/2)*dX;
X0=1;
Xn=length(X);
for m=1:Xn
Xnn=Xn/8;
pp=m;
if pp>3*Xnn && pp<5*Xnn
q=1.0;
f=q*exp(-(X/X0).^24);
else
f=0;
end
end
But it seems that 'f' is getting wrong and it is a 1 by 2048 vector with all entries zero. I'm not getting the expected result. If my initial condition is only f=q*exp(-(X/X0).^24), q=1, it is straightforward, but with the above condition (q=1 for |x|<1, otherwise, q=0) what I need to do?
Any help will be much appreciated.
Thanks in advance.
A MWE, this has 0 < [f(867) : f(1162)] <= 1:
fs=120;
N_fx=2^11; %number of points in frequency domain
dX=1/fs;
N_X=N_fx;
X=(-(N_X-1)/2:(N_X-1)/2)*dX;
X0=1;
Xn=length(X);
f = zeros(1,Xn); % new: preallocate f size and initialise it to 0
for m=1:Xn
Xnn=Xn/8;
if m>3*Xnn && m<5*Xnn
%if abs(X(m)) < 1 %alternative to line above
q=1.0;
% error was here below: you overwrote a 1x1 f at each iteration
f(m)=q*exp(-(X(m)/X0).^24);
else
f(m)=0;
end
end

How to decide between Global or Local vector for m choose n

Suppose we want to write a code that prints all ways of selecting n out of m options.
I think, the programming language does not matter, but if I should state it, Python.
I put the assignments in a vector A. Do I better define A as a global variable or pass it to the function each time? Why?
def choose(ind, n):
if n == 0:
print(A)
return
elif len(A)<= ind:
return
else:
A[ind] = 1
choose(ind + 1, n - 1)
A[ind] = 0
choose(ind + 1, n)
Always prefer passing over mutating globals whenever feasible.
Say you have the following functions:
def some_fun1 (n):
return n + 1;
m = 1;
def some_fun2 ():
return m + 1
With the first function, you can load up your REPL and throw data at it just by passing it as an argument. Your testing of that pure function has 0 effect on the rest of the program, which makes testing significantly easier.
With the second function, any time you need to test it, you must manually set all the globals the function relies on, which could potentially affect the operation of other functions if they rely on the same globals. This makes testing harder, and for that reason, among others, mutating globals should be avoided.

Modify a matrix in ocaml

I want to write a function that is modify every elements inside a matrix.
But I have some problem when compiling.
Warning 10: this expression should have type unit.
I think because all function in ocaml need to return to a value or unit, so if I implement two tasks inside one function, it is not acceptable.
Please help me to fix it.
let nomalize_matrix d a x =
for i = 1 to d do
for j = 1 to d do
let n = i*j in
x.(i)(j) = sprintf "%s_%d" a n
done
done;
x;;
In an expression the = operator in OCaml is a comparison operator that tests for equality. To assign to an array, use the <- operator.
The compiler is complaining because your expression has type bool (i.e., the result of the comparison). The expression in a for should have type unit since its return value is ignored. And indeed, the <- operator returns (), the unit value.
To access an element of a two-dimensional array, the syntax looks like: x.(i).(j). Note the extra dot, not present in your code.
There is no problem in general with doing two things in a function. You can separate two expressions with ; if the first has type unit. The result is the value of the second expression. Your code is OK in this respect.
Just be careful to do not use the operator "=" when you set one item from an array and use the operator "<-" instead so in your code, you have this :
let nomalize_matrix d a x =
for i = 1 to d do
for j = 1 to d do
let n = i*j in
x.(i)(j) <- sprintf "%s_%d" a n
done
done;
x;;

Am I using a wrong numerical method?

This is the code:
f = dsolve('D3y+12*Dy+y = 0 ,y(2) = 1 ,Dy(2) = 1, D2y(2) = -1');
feval(symengine, 'numeric::solve',strcat(char(f),'=1'),'t=-4..16','AllRealRoots')
If I remove 'AllRealRoots' option it works fast and finds a solution, but when I enable the option Matlab does not finish for an hour. Am I using a wrong numerical method?
First, straight from the documentation for numeric::solve:
If eqs is a non-polynomial/non-rational equation or a set or list containing such an equation, then the equations and the appropriate optional arguments are passed to the numerical solver numeric::fsolve.
So, as your equation f is non-polynomial, you should probably call numeric::fsolve directly. However, even with the 'MultiSolutions' it fails to return more than one root over your range (A bug perhaps? – I'm using R2013b). A workaround is to call numeric::realroots to get bounds on each of the district real roots in your range and then solve for them separately:
f = dsolve('D3y+12*Dy+y = 0 ,y(2) = 1 ,Dy(2) = 1, D2y(2) = -1');
r = feval(symengine, 'numeric::realroots', f==1, 't = -4 .. 16');
num_roots = numel(r);
T = zeros(num_roots,1); % Wrap in sym or vpa for higher precision output
syms t;
for i = 1:num_roots
bnds = r(i);
ri = feval(symengine, '_range', bnds(1), bnds(2));
s = feval(symengine, 'numeric::fsolve', f==1, t==ri);
T(i) = feval(symengine, 'rhs', s(1));
end
The resultant solution vector, T, is double-precision (allocate it as sym or vpa you want higher precision):
T =
-0.663159371123072
0.034848320470578
0.999047064621451
2.000000000000000
2.695929753727520
3.933983894260340
4.405822476913172
5.868112290810963
6.108685019679461
You may be able to remove the for loop if you can figure out how to cleanly pass in the output of 'numeric::realroots' to 'numeric::fsolve' in one go (it's doable, but may require converting stuf to strings unless you're clever).
Another (possibly even faster) approach is to switch to using the numeric (floating-point) function fzero for the second half after you bound all of the roots:
f = dsolve('D3y+12*Dy+y = 0 ,y(2) = 1 ,Dy(2) = 1, D2y(2) = -1');
r = feval(symengine, 'numeric::realroots', f==1, 't = -4 .. 16');
num_roots = numel(r);
T = zeros(num_roots,1);
g = matlabFunction(f-1); % Create anonymous function from f
for i = 1:num_roots
bnds = double(r(i));
T(i) = fzero(g,bnds);
end
I checked and, for your problem here and using the default tolerances, the resultant T is within a few times machine epsilon (eps) of the numeric::fsolve' solution.

Resources