Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am new to octave. I was asked to write a function [k,y,info]=ivs(a,b,fun,N) which computes the approximated values of the inverse of a given univariate function: fun:[a,b] -- >R; over N equidistant points over the interval [fun(a),fun(b)] (or [fun(b),fun(a)]).
y is the result
k - vector of aprroximated values of inverse function (evaluated over equidistant points)
y - vector of equidistant points
info - 0 if computation ended with success, not 0 otherwise
I wrote some code, it does not work, I get a lot of errors, but I cannot find out from them whats wrong. I expect to be a lot of mistakes in this code. I would like someone to point out whats wrong.
function [k,y,info]=ivs(a,b,fun,N)
if(a-b==0)
error('computation cannot take place, a=b');
else
if(fun(a)=fun(b))
error('we have a problem, interval is zero length')
end
if(fun(a)<fun(b))
x=linspace(fun(a), fun(b), N);
for l in 1:N
[j,FS,info,out]=fzero(#(j) fun(j)-x(l),[f(a),f(b)]);
y(i)=j;
if(info!=1)
error("Something went wrong with fzero()");
end
end
else
x=linspace(fun(b), fun(a), N);
for l in 1:N
[j,FS,info,out]=fzero(#(j) fun(j)-x(l),[f(a),f(b)]);
y(l)=j;
if(info!=1)
warning("Something went wrong with fzero()");
end
end
end
end
end
There are several mistakes in the typing, but also in the logic
you are declaring a k output but never creating it.
fun(a)=fun(b) is an assignment not a test.
for l in 1:N is NOT the correct way for a for.
you are using l for the cycle and than using i to index y.
in calling fzero the interval where to look for the solution is NOT [f(a),f(b)].
Amendig these problems, I guess your function was supposed to be:
function [k,y,info]=ltrigp(a,b,fun,N)
if(a-b==0)
error('computation cannot take place, a=b');
else
if(fun(a)==fun(b))
error('we have a problem, interval is zero length')
end
if(fun(a)<fun(b))
x=linspace(fun(a), fun(b), N);
for l = 1:N
[j,FS,info,out]=fzero(#(j) fun(j)-x(l),[a,b]);
y(l)=j;
k(l)=x(l);
if(info!=1)
error("Something went wrong with fzero()");
end
end
else
x=linspace(fun(b), fun(a), N);
for l = 1:N
[j,FS,info,out]=fzero(#(j) fun(j)-x(l),[a,b]);
y(l)=j;
k(l)=x(l);
if(info!=1)
warning("Something went wrong with fzero()");
end
end
end
end
end
and work like this:
a=1;
b=4;
N=10;
[k,y,info]=ltrigp(a,b,#exp,N)
k =
Columns 1 through 8:
2.7183 8.4827 14.2471 20.0116 25.7760 31.5404 37.3049 43.0693
Columns 9 and 10:
48.8337 54.5982
y =
Columns 1 through 8:
1.0000 2.1380 2.6566 2.9963 3.2494 3.4513 3.6191 3.7628
Columns 9 and 10:
3.8884 4.0000
info = 1
Related
I'm currently learning about recursion, it's pretty hard to understand. I found a very common example for it:
function factorial(N)
local Value
if N == 0 then
Value = 1
else
Value = N * factorial(N - 1)
end
return Value
end
print(factorial(3))
N == 0 is the base case. But when i changed it into N == 1, the result is still remains the same. (it will print 6).
Is using the base case important? (will it break or something?)
What's the difference between using N == 0 (base case) and N == 1?
That's just a coincidence, since 1 * 1 = 1, so it ends up working either way.
But consider the edge-case where N = 0, if you check for N == 1, then you'd go into the else branch and calculate 0 * factorial(-1), which would lead to an endless loop.
The same would happen in both cases if you just called factorial(-1) directly, which is why you should either check for > 0 instead (effectively treating every negative value as 0 and returning 1, or add another if condition and raise an error when N is negative.
EDIT: As pointed out in another answer, your implementation is not tail-recursive, meaning it accumulates memory for every recursive functioncall until it finishes or runs out of memory.
You can make the function tail-recursive, which allows Lua to treat it pretty much like a normal loop that could run as long as it takes to calculate its result:
local function factorial(n, acc)
acc = acc or 1
if n <= 0 then
return acc
else
return factorial(n-1, acc*n)
end
return Value
end
print(factorial(3))
Note though, that in the case of factorial, it would take you way longer to run out of stack memory than to overflow Luas number data type at around 21!, so making it tail-recursive is really just a matter of training yourself to write better code.
As the above answer and comments have pointed out, it is essential to have a base-case in a recursive function; otherwise, one ends up with an infinite loop.
Also, in the case of your factorial function, it is probably more efficient to use a helper function to perform the recursion, so as to take advantage of Lua's tail-call optimizations. Since Lua conveniently allows for local functions, you can define a helper within the scope of your factorial function.
Note that this example is not meant to handle the factorials of negative numbers.
-- Requires: n is an integer greater than or equal to 0.
-- Effects : returns the factorial of n.
function fact(n)
-- Local function that will actually perform the recursion.
local function fact_helper(n, i)
-- This is the base case.
if (i == 1) then
return n
end
-- Take advantage of tail calls.
return fact_helper(n * i, i - 1)
end
-- Check for edge cases, such as fact(0) and fact(1).
if ((n == 0) or (n == 1)) then
return 1
end
return fact_helper(n, n - 1)
end
I'm new to Julia.
I mainly program in python.
In python,
if you want to iterate over a large set of values,
it is typical to construct a so-called generator to save memory usage.
Here is one example code:
def generator(N):
for i in range(N):
yield i
I wonder if there is anything alike in Julia.
After reading julia manual,
#task macro seems to have the same (or similar) functionality as generator in python.
However,
after some experiments,
the memory usage seems to be larger than usual array in julia.
I use #time in IJulia to see the memory usage.
Here is my sample code:
[Update]: Add the code for generator method
(The generator method)
function generator(N::Int)
for i in 1:N
produce(i)
end
end
(generator version)
function fun_gener()
sum = 0
g = #task generator(100000)
for i in g
sum += i
end
sum
end
#time fun_gener()
elapsed time: 0.420731828 seconds (6507600 bytes allocated)
(array version)
function fun_arry()
sum = 0
c = [1:100000]
for i in c
sum += i
end
sum
end
#time fun_arry()
elapsed time: 0.000629629 seconds (800144 bytes allocated)
Could anyone tell me why #task will require more space in this case?
And if I want to save memory usage as dealing with a large set of values,
what can I do?
I recommend the "tricked out iterators" blogpost by Carl Vogel, which discusses julia's iterator protocol, tasks and co-routines in some detail.
See also task-aka-coroutines in the julia docs.
In this case you should use the Range type (which defines an iterator protocol):
julia> function fun_arry()
sum = 0
c = 1:100000 # remove the brackets, makes this a Range
for i in c
sum += i
end
sum
end
fun_arry (generic function with 1 method)
julia> fun_arry() # warm up
5000050000
julia> #time fun_arry()
elapsed time: 8.965e-6 seconds (192 bytes allocated)
5000050000
Faster and less memory allocated (just like xrange in python 2).
A snippet from the blogpost:
From https://github.com/JuliaLang/julia/blob/master/base/range.jl, here’s how a Range’s iterator protocol is defined:
start(r::Ranges) = 0
next{T}(r::Range{T}, i) = (oftype(T, r.start + i*step(r)), i+1)
next{T}(r::Range1{T}, i) = (oftype(T, r.start + i), i+1)
done(r::Ranges, i) = (length(r) <= i)
Notice that the next method calculates the value of the iterator in state i. This is different from an Array iterator, which just reads the element a[i] from memory.
Iterators that exploit delayed evaluation like this can have important performance benefits. If we want to iterate over the integers 1 to 10,000, iterating over an Array means we have to allocate about 80MB to hold it. A Range only requires 16 bytes; the same size as the range 1 to 100,000 or 1 to 100,000,000.
You can write a generator method (using Tasks):
julia> function generator(n)
for i in 1:n # Note: we're using a Range here!
produce(i)
end
end
generator (generic function with 2 methods)
julia> for x in Task(() -> generator(3))
println(x)
end
1
2
3
Note: if you replace the Range with this, the performance is much poorer (and allocates way more memory):
julia> #time fun_arry()
elapsed time: 0.699122659 seconds (9 MB allocated)
5000050000
This question was asked (and answered) quite a while ago. Since this question is ranked high on google searches, I'd like to mention that both the question and answer are outdated.
Nowadays, I'd suggest checking out https://github.com/BenLauwens/ResumableFunctions.jl for a Julia library with a macro that implements Python-like yield generators.
using ResumableFunctions
#resumable function fibonnaci(n::Int) :: Int
a = 0
b = 1
for i in 1:n-1
#yield a
a, b = b, a+b
end
a
end
for fib in fibonnaci(10)
println(fib)
end
Since its scope is much more limited than full coroutines, it is also an order of magnitude more efficient than pushing values into a channel since it can compile the generator into a FSM. (Channels have replaced the old produce() function mentioned in the question and previous answers).
With that said, I'd still suggest pushing into a channel as your first approach if performance isn't an issue, because resumablefunctions can sometimes be finicky when compiling your function and can occasionally hit some worst-case behaviour. In particular, because it is a macro that compiles to an FSM rather than a function, you currently need to annotate the types of all variables in the Resumablefunction to get good performance, unlike vanilla Julia functions where this is handled by JIT when the function is first called.
I think that Task has been superseded by Channel(). The usage in terms of Ben Lauwens's Fibonacci generator is:
fibonacci(n) = Channel(ctype=Int) do c
a = 1
b = 1
for i in 1:n
push!(c, a)
a, b = b, a + b
end
end
it can be used using
for a in fibonacci(10)
println(a)
end
1
1
2
3
5
8
13
21
34
55
Within my daily work, I have got to maximize a particular function making use of fminsearch; the code is:
clc
clear all
close all
f = #(x,c,k) -(x(2)/c)^3*(((exp(-(x(1)/c)^k)-exp(-(x(2)/c)^k))/((x(2)/c)^k-(x(1)/c)^k))-exp(-(x(3)/c)^k))^2;
c = 10.1;
k = 2.3;
X = fminsearch(#(x) f(x,c,k),[4,10,20]);
It works fine, as I expect, but not the issue is coming up: I need to bound x within certain limits, as:
4 < x(1) < 5
10 < x(2) < 15
20 < x(3) < 30
To achieve the proper results, I should use the optimization toolbox, that I unfortunately cannot hand.
Is there any way to get the same analysis by making use of only fminsearch?
Well, not using fminsearch directly, but if you are willing to download fminsearchbnd from the file exchange, then yes. fminsearchbnd does a bound constrained minimization of a general objective function, as an overlay on fminsearch. It calls fminsearch for you, applying bounds to the problem.
Essentially the idea is to transform your problem for you, in a way that your objective function sees as if it is solving a constrained problem. It is totally transparent. You call fminsearchbnd with a function, a starting point in the parameter space, and a set of lower and upper bounds.
For example, minimizing the rosenbrock function returns a minimum at [1,1] by fminsearch. But if we apply purely lower bounds on the problem of 2 for each variable, then fminsearchbnd finds the bound constrained solution at [2,4].
rosen = #(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2;
fminsearch(rosen,[3 3]) % unconstrained
ans =
1.0000 1.0000
fminsearchbnd(rosen,[3 3],[2 2],[]) % constrained
ans =
2.0000 4.0000
If you have no constraints on a variable, then supply -inf or inf as the corresponding bound.
fminsearchbnd(rosen,[3 3],[-inf 2],[])
ans =
1.4137 2
Andrey has the right idea, and the smoother way of providing a penalty isn't hard: just add the distance to the equation.
To keep using the anonymous function:
f = #(x,c,k, Xmin, Xmax) -(x(2)/c)^3*(((exp(-(x(1)/c)^k)-exp(-(x(2)/c)^k))/((x(2)/c)^k-(x(1)/c)^k))-exp(-(x(3)/c)^k))^2 ...
+ (x< Xmin)*(Xmin' - x' + 10000) + (x>Xmax)*(x' - Xmax' + 10000) ;
The most naive way to bound x, would be giving a huge penalty for any x that is not in the range.
For example:
function res = f(x,c,k)
if x(1)>5 || x(1)<4
penalty = 1000000000000;
else
penalty = 0;
end
res = penalty - (x(2)/c)^3*(((exp(-(x(1)/c)^k)-exp(-(x(2)/c)^k))/((x(2)/c)^k-(x(1)/c)^k))-exp(-(x(3)/c)^k))^2;
end
You can improve this approach, by giving the penalty in a smoother way.
I am learning MatLab on my own, and I have this assignment in my book which I don't quite understand. Basically I am writing a function that will calculate sine through the use of Taylor series. My code is as follows so far:
function y = sine_series(x,n);
%SINE_SERIES: computes sin(x) from series expansion
% x may be entered as a vector to allow for multiple calculations simultaneously
if n <= 0
error('Input must be positive')
end
j = length(x);
k = [1:n];
y = ones(j,1);
for i = 1:j
y(i) = sum((-1).^(k-1).*(x(i).^(2*k -1))./(factorial(2*k-1)));
end
The book is now asking me to include an optional output err which will calculate the difference between sin(x) and y. The book hints that I may use nargout to accomplish this, but there are no examples in the book on how to use this, and reading the MatLab help on the subject did not make my any wiser.
If anyone can please help me understand this, I would really appreciate it!
The call to nargout checks for the number of output arguments a function is called with. Depending on the size of nargout you can assign entries to the output argument varargout. For your code this would look like:
function [y varargout]= sine_series(x,n);
%SINE_SERIES: computes sin(x) from series expansion
% x may be entered as a vector to allow for multiple calculations simultaneously
if n <= 0
error('Input must be positive')
end
j = length(x);
k = [1:n];
y = ones(j,1);
for i = 1:j
y(i) = sum((-1).^(k-1).*(x(i).^(2*k -1))./(factorial(2*k-1)));
end
if nargout ==2
varargout{1} = sin(x)'-y;
end
Compare the output of
[y] = sine_series(rand(1,10),3)
and
[y err] = sine_series(rand(1,10),3)
to see the difference.
I am a complete beginner at programming and I'm having trouble with implementing the error function for my homework assignment. My erf(x) works fine for values of x from 0 to 2.0 but doesn't work for higher values as it should. The table for the proper values is here.
function y = erf (z)
konst = 2/(pi^0.5);
vsota=0;
n=0;
while n <= 500;
vsota = vsota + ((-1)^n)*(z^(2*n+1))/(factorial(n)*(2*n+1));
n=n+1;
end
y=konst*vsota;
end
Please help me stackoverflow, you're my only hope!
Maybe octave is having trouble evaluating factorial() of large numbers. I got good results using n <= 170 in Python.