In [1]:
using Dates
include("printmat.jl")
Out[1]:
The basic approach to define a function with the name fn
is
function fn(x,b)
...(some code)
return y
end
Once you have defined a function, you can use it (call on it) by, for instance, y1 = fn(2,1)
. This will generate a y1
variable (not a y
variable) in the workspace. Inside the function, x
is then 2 and b
is 1. Clearly, if x1=2 and b1=1
, you get the same result by calling as y1 = fn(x1,b1)
.
In [2]:
function fn1(x,b) #x and b are the inputs
c = 0.5 #c is only "seen" inside the function
y = b*(x-1.1)^2 - c
return y #this is the output
end
y1 = fn1(2,1)
printlnPs("result from fn1(2,1): ",y1)
In [3]:
function fn2(x,b=1) #b=1 is the default in case we call as fn2(x)
y = b*(x-1.1)^2 - 0.5
return y
end
printlnPs("result from fn2(2,1) and fn2(2): ",fn2(2,1),fn2(2))
In [4]:
x1 = [1,1.5]
b1 = [2,2]
println("\nresult from fn2.(x1,2): ")
printmat(fn2.(x1,2))
println("\nresult from fn2.(x1,b1): ")
printmat(fn2.(x1,b1))
In [5]:
function fn301(x,b)
y = x + sum(b)
return y
end
x1 = [1,1.5]
b1 = [10,20,30]
println("result from fn301.(x1,Ref(b1)):")
printmat(fn301.(x1,Ref(b1)))
We can also use short forms of a function as in the cell below.
The first version (fn3
) is just a single expression. It could span several lines. The second version (fn3b
) is a sequence of expressions (a "compound expression") separated by semicolons (;). The last expression is the function output.
In [6]:
fn3(x,b) = b*(x-1.1)^2 - 0.5 #short form of a function
fn3b(x,b) = (c = 0.5;b*(x-1.1)^2 - c) #this works too. Notice the ;
printlnPs("result from fn3(1.5,1) and fn3b(1.5,1): ",fn3(1.5,1),fn3b(1.5,1))
You can also define functions that take keyword arguments like in
fn(x;b,c)
Notice the semi-colon (;). You can also specify default values as fn(x;b=1,c=0.5)
In this case, you call on the function by fn(x,c=3,b=2)
or just fn(x)
if you want to use the default values. This helps remembering/interpreting what the arguments represent. When calling on the function, you can pass the keyword arguments in any order and you can use comma (,) instead of semi-colon (;).
In [7]:
function fn4(x;b=1,c=0.5)
y = b*(x-1.1)^2 - c
return y
end
printlnPs("result from fn4(1,c=3,b=2): ",fn4(1,c=3,b=2))
In [8]:
function fn5(a,x...;b=1) #a is traditional input, x... captures several inputs; b=1 is a keyword input
n = length(x)
y = zeros(n)
for i = 1:n
y[i] = a + x[i]*b
end
return y
end
y = fn5(-9,1,2,b=10)
println("result from fn5(-9,1,2,b=10): ")
printmat(y)
A function can produce a "tuple" like (y1,y2,y3)
as output.
In case you only want the first two outputs, call as (y1,y2,) = fn(x)
.
Instead, if you only want the second and third outputs, call as (_,y2,y3) = fn(x)
You can also extract the second output as y2 = fn(x)[2]
If Y1
is an already existing array, then (Y1[3],y2,) = fn(x)
will change element 3 of Y1
(and also assign a value to y2
).
In [9]:
function fn11(x,b=1)
y1 = b*(x-1.1)^2 - 0.5
y2 = b*x
y3 = 3
return y1, y2, y3
end
(y1,y2,) = fn11(1,2)
printlnPs("The first 2 outputs from fn11(1,2): ",y1,y2)
y2 = fn11(1,2)[2] #grab the second output
printlnPs("\nThe result from calling fn11(1,2)[2]: ",y2)
Y1 = zeros(5) #create an array
(Y1[3],y2,) = fn11(1,2) #put result in existing array
printlnPs("\nY1 array after calling fn11(1,2): ",Y1)
In [10]:
function fn12(x,b=1)
y1 = b*(x-1.1)^2 - 0.5
y2 = b*x
y3 = 3
y = (a=y1,b=y2,c=y3) #named tuple
return y
end
y1 = fn12(1,2)
printlnPs("from fn12(1,2): ",y1.a,y1.b) #y1.a to get "element" a of the output y1
In [11]:
function fn13(x,b=1)
y1 = b*(x-1.1)^2 - 0.5
y2 = b*x
y3 = 3
y = Dict("a"=>y1,"b"=>y2,"c"=>y3) #dictionary
return y
end
y1 = fn13(1,2)
printlnPs("from fn13(1,2): ",y1["a"],y1["b"]) #y1["a"] to get "element" a of the output y1
...can be tricky, because you get an array (same dimension as the input) of tuples instead of a tuple of arrays (which is probably what you want).
One way around this is to reshuffle the output to get a tuple of arrays.
Alternatively, you could loop over the function calls or write the function in such a way that it directly handles array inputs (without the dot). The latter is done in fn14()
.
In [12]:
y = fn11.([1,1.5],2)
println("y, a 2-element vector of tuples (3 elements in each):")
printmat(y)
(y1,y2,y3) = ntuple(i->getindex.(y,i),3) #split up into 3 vectors
println("\nthe vectors y1 and y2:")
printmat([y1 y2])
In [13]:
function fn14(x,b=1) #x can be an array
y1 = b*(x.-1.1).^2 .- 0.5
y2 = b*x
y3 = 3
return y1, y2, y3
end
(y1,y2,) = fn14(x1,2) #function written to handle arrays
println("result from fn14(x1,2): ")
printmat([y1 y2])
In [14]:
"""
fn101(x,b=1)
Calculate `b*(x-1.1)^2 - 0.5`.
# Arguments
- `x::Number`: an important number
- `b::Number`: another number
"""
function fn101(x,b=1)
y = b*(x-1.1)^2 - 0.5
return y
end
Out[14]:
In [15]:
? fn101
Out[15]:
In [16]:
function fn201(f,a,b) #f is a function, could also write f::Function
y = f(a) + b
return y
end
#here f is the cos function
printlnPs("result from fn201(cos,3.145,10): ",fn201(cos,3.145,10))
#here f is z->mod(z,2), an anonymous function
printlnPs("\nresult from fn201(z->mod(z,2),3.145,10):",fn201(z->mod(z,2),3.145,10))
In [ ]: