Understanding the parameter passing issue in programming languages - parameter-passing

I am trying to find out exactly what are the parameter passing methods. What they do, what are their differences... I have the following subprogram:
subprogram p(x)
a[1] = 6;
element = 2;
x = x + 3;
end
a is an array and has only two elements.
a[1] = 1
a[2] = 2
element = 1
we call the subprogram as follows:
p(a[element])
Then what would be the results if the subprogram uses "pass by value", "pass by result", "pass by value-result", "pass by reference", or "pass by name" methods.
I am really confused. Thanks in advance.

The language affects the scope of the variables and how they are bound at the time the function is invoked or the function is defined. However, it is likely safe to assume static, lexical scoping rules apply.
Pass By Value: change only explicitly named variables.
a[1] = 6
a[2] = 2
element = 2
Pass By Reference: change explicitly named variables and stuff passed in.
a[1] = 9
a[2] = 2
element = 2
Pass By Result: change explicitly named variables and stuff passed in.
a[1] = 9
a[2] = 2
element = 2
Pass By Value-Result: change explicitly named variables and stuff passed in.
a[1] = 9
a[2] = 2
element = 2
Pass By Name: change explicitly named variables and stuff passed in.
a[1] = 6
a[2] = 5
element = 2

Related

Uppercase in name of a function in Julia

I am fairly new to Julia and got confused with the following code. After a function LucasTree is defined, it is used again as lt. Does Julia have some kind of role where I can recall a function using the uppercase abbreviation? If so, where can I find a nice reference for this feature?
function LucasTree(;γ = 2.0,
β = 0.95,
α = 0.9,
σ = 0.1,
grid_size = 100)
ϕ = LogNormal(0.0, σ)
shocks = rand(ϕ, 500)
# build a grid with mass around stationary distribution
ssd = σ / sqrt(1 - α^2)
grid_min, grid_max = exp(-4ssd), exp(4ssd)
grid = range(grid_min, grid_max, length = grid_size)
# set h(y) = β * int u'(G(y,z)) G(y,z) ϕ(dz)
h = similar(grid)
for (i, y) in enumerate(grid)
h[i] = β * mean((y^α .* shocks).^(1 - γ))
end
return (γ = γ, β = β, α = α, σ = σ, ϕ = ϕ, grid = grid, shocks = shocks, h = h)
end
function lucas_operator(lt, f)
# unpack input
#unpack grid, α, β, h = lt
z = lt.shocks
Af = LinearInterpolation(grid, f, extrapolation_bc=Line())
Tf = [ h[i] + β * mean(Af.(grid[i]^α .* z)) for i in 1:length(grid) ]
return Tf
end
No, this does not exist. It would be too nonunique to be practical, and moreover function names in Julia by convention should be entirely lowercase (structs/types can be CamelCase, but not functions, with the possible exception of constructors*).
In any case, all that is happening here in the code you have posted is that the function lucas_operator takes two arguments, lt and f, which can then be used within that lucas_operator function. These could in principle be anything, and regardless of what they are named outside the scope of the function, they will be named lt and f within the scope of the function. So for example:
function example(foo, bar)
return foo(2*bar)
end
if you then call
example(somereallylongfunctionname, somevariable)
then that will return the equivalent of
somereallylongfunctionname(2*somevariable)
or similarly
example(SomeImproperlyCapitalizedFunction, somevariable)
# equivalent to SomeImproperlyCapitalizedFunction(2*somevariable)
in either case, regardless of its name outside the scope of the example function, the first argument passed to the function will be known as foo within the function.
* Aside about constructors: that would be a function that is used to construct a custom type. This doesn't quite do that, but it does return an instance of a NamedTuple which then seems to be treated somewhat like a type/struct in the subsequent code, so perhaps it could be counted as a constructor.

Schwefel function trying to find global minimum with three variables, but I am receiving a error from function

I am writing a Schwefel function with three variables x1, x2 and x3 with x (-400,400), I am trying to find the global minimum of a Schwefel function. Can anybody tell me what's wrong with the function code.
function output = objective_function(in)
x1 = in(1);
x2 = in(2);
x3 = in(3);
output=(-x1.*sin(sqrt(mod(x1)))+(-x2.*sin(sqrt(mod(x2)))+(-x3.*sin(sqrt(mod(x3)));
ouput=[F1 F2];
Current Problems:
1: Mismatched delimiters in line:
output=(-x1.*sin(sqrt(mod(x1)))+(-x2.*sin(sqrt(mod(x2)))+(-x3.*sin(sqrt(mod(x3)));
2: Modulus requires a second argument. The second argument inputted into the mod() function needs to be the divisor. The modulus can only return the remainder if it knows the number being divided (dividend) and the number that is dividing (divisor). Calling the mod() function can follow the form:
mod(dividend,divisor);
Aside:
mod() is often used accidentally in replace of abs()
Modulus → mod() : Returns the remainder after division.
Example: mod(10,3) = 1 → 10/3 = 3 with remainder 1
Absolute → abs(): Returns the absolute/magnitude of the number.
Example: abs(-10) = 10 or abs(1 + 1i) = 1.4142
3: Variables F1 and F2 are not defined or initialized before being used. The variable called ouput may be a typo.
ouput=[F1 F2];
Playground Script:
Not sure what the function is supposed to exactly do but here is a script that you can modify to meet your needs. This gets rid of the errors but might need to be reconfigured to suit your exact functionality and output equation.
in = [1 2 3];
[output] = objective_function(in);
function [output] = objective_function(in)
x1 = in(1);
x2 = in(2);
x3 = in(3);
%Splitting into terms will help with debugging bracket balancing issues%
Divisor = 2;
Term_1 = (-x1.*sin(sqrt(mod(x1,Divisor))));
Term_2 = (-x2.*sin(sqrt(mod(x2,Divisor))));
Term_3 = (-x3.*sin(sqrt(mod(x3,Divisor))));
output = Term_1 + Term_2 + Term_3;
end
Ran using MATLAB R2019b

Julia scoping: why does this function modify a global variable?

I'm a relative newcomer to Julia, and so far I am a fan of it. But coming from years of R programming, some scoping rules leave me perplexed.
Let's take this function. This behaves exactly as I would expect.
function foo1(x)
y = x
t = 1
while t < 1000
t += 1
y += 1
end
return 42
end
var = 0;
foo1(var)
# 42
var
# 0
But when doing something similar on an array, it acts as a mutating function (modifies it argument in the global scope!)
function foo2(x)
y = x
t = 1
while t < 1000
t += 1
y[1] += 1
end
return 42
end
var = zeros(1);
foo2(var)
# 42
var
# 999.0
I realize I can fix this by changing the first line to y = copy(x) , but what is the reason for such a (dangerous?) behaviour in the first place?
I would write an answer to this, but I think John Myles White has already done it better than I ever could so I'll just link to his blogpost:
https://www.juliabloggers.com/values-vs-bindings-the-map-is-not-the-territory-3/
In short x = 1 and x[1] = 1 are very different operations. The first one is assignment—i.e. changing a binding of the variable x—while the second is a syntactic sugar for calling the setindex! function, which, in the case of arrays, assigns to a location in the array. Assignment only changes which variables refer to which objects and never modifies any objects. Mutation only modifies objects and never changes which variables refer to which objects. This answer has a bit more detail about the distinction: Creating copies in Julia with = operator.

How to define a function with a parameter in it in Octave?

I am trying to define a function with a predefined variable, and Octave says that the variable was not defined. I am trying to run the following code in Octave,
q = 5;
function w = tointegrate(x)
w = 2 * q * sin(x);
endfunction
[ans, ier, nfun, err] = quad("tointegrate", -10*q, 10*q);
ans
Octave gives the error
error: 'q' undefined near line 3 column 10
error: quad: evaluation of user-supplied function failed
How to fix this error?
You are expecting 'commandline functions' in octave to have lexical scope, but this is simply not the case.
If all of this was inside a function, and you defined a nested function, it would work as you expect. But 'commandline functions' like this are treated as if they are in their own file, and have no knowledge of the workspace in which they've been defined.
In this particular case, since your function is effectively a one-liner, you can get the effect you want by making it a function handle instead, which 'does' capture the local workspace. I.e. this will work
q = 5;
tointegrate = #(x) 2 * q * sin(x);
[ans, ier, nfun, err] = quad("tointegrate",-10 *q ,10*q);
Note, however, that 'q' will have the value it had at the time it was captured. I.e. if you update q dynamically, its value will not be updated in the function handle.
Otherwise, for more complex functions, the solution is really to pass it as a parameter (or to access it as a global etc).
You can solve this by having q be a parameter to the function, then creating an anonymous function to call quad, like so:
function w = tointegrate(x, q)
w = 2 * q * sin(x);
endfunction
q = 5;
[ans, ier, nfun, err] = quad(#(x)tointegrate(x,q), -10*q, 10*q);
ans

Is it possible to know the name of the variable that provides the value in a function call in Octave?

Say that myFunction has been invoked from somewhere like this
...
myFunction (b);
...
Now, in the definition of myFunction, can I obtain the name of the variable in the call?
function myFunction (a)
...
inputVble = whoscalling; % this will result in "b"
...
May be it can be done if b is a global variable?
Note: this is not like in a couple other questions, where you want to know the name of the input argument, i.e. a.
function ret = doit (a, b)
inputname (1)
inputname (2)
ret = a + b;
endfunction
x = 4;
y = 5;
doit (x, y)
returns
ans = x
ans = y
ans = 9
But I want to mention that in my opinion, making a function somewhat dependent on the function names is bad style and shouldn't be done even if it's possible.
EDIT: I think the main reasonable use for inputname is inside a display routine for #classes. For example http://hg.savannah.gnu.org/hgweb/octave/file/51a1d1164449/examples/code/%40polynomial/display.m
function display (p)
...
fprintf ("%s =", inputname (1));
Or inside celldisp:
octave:2> a = {"huhu", pi}
a =
{
[1,1] = huhu
[1,2] = 3.1416
}
octave:3> celldisp (a)
a{1} =
huhu
a{2} =
3.1416