Is there a way of manipulating a global variable you use as an argument for a function in lua? - function

I'm trying to write some code into a function so that it can be easily reused whereby a global value is increased.
The issue is that there are several different globals that can be manipulated, and I need the function to be able to handle each one.
I thought I could simply put the global variable into the argument in the function but it doesn't seem to work. Probably because lua creates a copy of the global variable it takes.
Is there a way to make sure that the global variable it manipulates is not just a copy?
I have already tried to make sure that all the relevant variables remain local, but the problem is that they are all in a loop, and so need to remain outside the loop to be able to increment properly.
Right now I have to write a separate function for each case of incrementation which is a little unweildy, if bareable.
Right now I have to do something like this
foo_time_1 = 0
foo_time_2 = 0
function foo_time_1(var)
foo_time_1 += 2
if foo_time < 2 then
sfx(02)
end
end
function foo_time_2(var)
if foo_time_2 < 2 then
sfx(02)
end
end
This allows the code to run as intended, but Ideally I would like the code to look something like this:
foo_time = 0
foo_time_2 = 0
function foo_time_manipulator(global_var, len, sfx)
global_var += 2
if global_var < len then
play(sfx)
end
end
//so I can write
foo_time_manipulator(foo_time, 2, 02)
foo_time_manupulator(foo_time_2, 3, 02)
The problem with that is that the global variable doesn't change and so the sound effect loops continuously as every frame the function is re-read and it see that the global varaible remains at the value it was used as an argument, rather than the updated variable.
Sorry if this question has been poorly worded, it's a little difficult to articulate.
Is there any way in lua to be able to manipulate a global variable that is used as an argument?
A good qualifier may be that this code is being looped, and so requires an outside variable to act as a counter.

You can try this:
function foo_time_manipulator(global_var_name, len, six)
local global_var = _G[global_var_name]
global_var = global_var + 2
if global_var < len then
play(sfx)
end
end
and use it like this
foo_time_manipulator("foo_time", 2, 02)
foo_time_manupulator("foo_time_2", 3, 02)

Related

How do I set a function to a variable in MATLAB

As a homework assignment, I'm writing a code that uses the bisection method to calculate the root of a function with one variable within a range. I created a user function that does the calculations, but one of the inputs of the function is supposed to be "fun" which is supposed to be set equal to the function.
Here is my code, before I go on:
function [ Ts ] = BisectionRoot( fun,a,b,TolMax )
%This function finds the value of Ts by finding the root of a given function within a given range to a given
%tolerance, using the Bisection Method.
Fa = fun(a);
Fb = fun(b);
if Fa * Fb > 0
disp('Error: The function has no roots in between the given bounds')
else
xNS = (a + b)/2;
toli = abs((b-a)/2);
FxNS = fun(xns);
if FxNS == 0
Ts = xNS;
break
end
if toli , TolMax
Ts = xNS;
break
end
if fun(a) * FxNS < 0
b = xNS;
else
a = xNS;
end
end
Ts
end
The input arguments are defined by our teacher, so I can't mess with them. We're supposed to set those variables in the command window before running the function. That way, we can use the program later on for other things. (Even though I think fzero() can be used to do this)
My problem is that I'm not sure how to set fun to something, and then use that in a way that I can do fun(a) or fun(b). In our book they do something they call defining f(x) as an anonymous function. They do this for an example problem:
F = # (x) 8-4.5*(x-sin(x))
But when I try doing that, I get the error, Error: Unexpected MATLAB operator.
If you guys want to try running the program to test your solutions before posting (hopefully my program works!) you can use these variables from an example in the book:
fun = 8 - 4.5*(x - sin(x))
a = 2
b = 3
TolMax = .001
The answer the get in the book for using those is 2.430664.
I'm sure the answer to this is incredibly easy and straightforward, but for some reason, I can't find a way to do it! Thank you for your help.
To get you going, it looks like your example is missing some syntax. Instead of either of these (from your question):
fun = 8 - 4.5*(x - sin(x)) % Missing function handle declaration symbol "#"
F = # (x) 8-4.5*(x-sin9(x)) %Unless you have defined it, there is no function "sin9"
Use
fun = #(x) 8 - 4.5*(x - sin(x))
Then you would call your function like this:
fun = #(x) 8 - 4.5*(x - sin(x));
a = 2;
b = 3;
TolMax = .001;
root = BisectionRoot( fun,a,b,TolMax );
To debug (which you will need to do), use the debugger.
The command dbstop if error stops execution and opens the file at the point of the problem, letting you examine the variable values and function stack.
Clicking on the "-" marks in the editor creates a break point, forcing the function to pause execution at that point, again so that you can examine the contents. Note that you can step through the code line by line using the debug buttons at the top of the editor.
dbquit quits debug mode
dbclear all clears all break points

Calling function with changing input parameters in a loop Matlab

I have caught myself in a issue, I know its not that difficult but I couldnt figure out how to implement it. I have an m file that looks like
clear;
PVinv.m_SwF=20e3
for m=1:1:70;
PVinv.m_SwF=PVinv.m_SwF+1e3;
Lmin = PVinv.InductanceDimens();
Wa_Ac = PVinv.CoreSizeModel();
PVinv.CoreSelect(Wa_Ac);
[loss_ind_core,loss_ind_copper] = PVinv.InductorLossModel(PVinv.m_L_Selected);
Total_Inductor_Loss=loss_ind_core+loss_ind_copper
plot(PVinv.m_SwF,Total_Inductor_Loss,'--gs');
hold on
xlim([10e3 90e3])
set(gca,'XTickLabel',{'10';'20';'30';'40';'50';'60';'70';'80';'90'})
grid on
xlabel('Switching Frequency [kHz]');
ylabel('Power loss [W]');
end
And the function that is of interest is CoreSelect(Wa_Ac)
function obj = CoreSelect(obj, WaAc)
obj.m_Core_Available= obj.m_Core_List(i);
obj.m_L_Selected.m_Core = obj.m_Core_Available;
end
I want to change the value of i from obj.m_Core_List(1) to obj.m_Core_List(27) within that for loop of main m file. How can I get the value of the function coreselect when I call it in main m file
For eg for m=1 to 70 I want the function to take the value of i=1 then execute till plot command and then same with but i=2 and so on
Any suggestion would be really helpful
I'm not sure I understand your question perfectly, but I think you want to pass an index i to the CoreSelect function, and loop i from 1 to 27 outside of the function. Try this:
function obj = CoreSelect(obj, WaAc, i)
...
end
for i=1:27,
PVInv.CoreSelect(WaAc,i);
end

Matlab: Abort function call with Strg+C but KEEP return value

I have a function in matlab with something like this:
function [ out ] = myFunc(arg1, arg2)
times = [];
for i = 1:arg1
tic
% do some long calculations
times = [times; toc];
end
% Return
out = times;
end
I want to abort the running function now but keep the values of times which are currently already taken. How to do it? When I press strg+c, I simply loose it because it's only a local function variable which is deleted when the function leaves the scope...
Thanks!
Simplest solution would be to turn it from a function to a script, where times would no longer be a local variable.
The more elegant solution would be to save the times variable to a .mat file within the loop. Depending on the time per iteration, you could do this on every loop, or once every ten loops, etc.
Couldn't you use persistent variables to solve your problem, e.g.
function [ out ] = myFunc(arg1, arg2)
persistent times
if nargin == 0
out = times;
return;
end;
times = [];
for i = 1:arg1
tic
% do some long calculations
times = [times; toc];
end
% Return
out = times;
end
I'm not sure whether persistent variables are cleared upon Ctrl-C, but I don't think it should be the case. What this should do: if you supply arguments, it will run as before. When you omit all arguments however, the last value of times should be returned.
onCleanup functions still fire in the presence of CTRL-C, however I don't think that's really going to help because it will be hard for you to connect the value you want to the onCleanup function handle (there are some tricky variable lifetime issues here). You may have more luck using a MATLAB handle object to track your value. For example
x = containers.Map(); x('Value') = [];
myFcn(x); % updates x('Value')
% CTRL-C
x('Value') % contains latest value
Another possible solution is to use the assignin function to send the data to your workspace on each iteration. e.g.
function [ out ] = myFunc(arg1, arg2)
times = [];
for i = 1:arg1
tic
% do some long calculations
times = [times; toc];
% copy the variable to the base workspace
assignin('base', 'thelasttimes', times)
end
% Return
out = times;
end

Specify whever a lua parameter should be a copy or a reference

I'm wondering if there is a way to specify if the parameters of a lua function should be copied or just referenced. Color is an object representing a color.
For example, with this code
function editColor(col)
col.r = 0
print(tostring(col.r))
end
color = Color(255, 0, 0)
print(tostring(color.r))
editColor(color)
print(tostring(color.r))
Makes the output
255
0
0
So col is a "reference" to color, but this code:
function editColor(col)
col = Color(0, 0, 0)
print(tostring(col.r))
end
color = Color(255, 0, 0)
print(tostring(color.r))
editColor(color)
print(tostring(color.r))
Makes this output
255
0
255
So here the color is copied.
Is there a way to force a parameter to be copied or referenced? Just like the & operator in C++?
No, parameters in Lua are always passed by value (mirror). All variables are references however. In your second example in editColor you're overriding what the variable col refers to, but it's only for that scope. You'll need to change things around, maybe instead of passing in a variable to be reassigned, have the function return something and do your reassignment outside. Good luck.
This will do what you want. Put the variable that you want to pass by reference into a table. You can use a table to pass anything by ref, not just a string.
-- function that you want to pass the string
-- to byref.
local function next_level( w )
w.xml = w.xml .. '<next\>'
end
-- Some top level function that you want to use to accumulate text
function top_level()
local w = {xml = '<top>'} -- This creates a table with one entry called "xml".
-- You can call the entry whatever you'd like, just be
-- consistant in the other functions.
next_level(w)
w.xml = w.xml .. '</top>'
return w.xml
end
--output: <top><next\></top>
Lua is a bad language. Suffer its simplicity when you need to do something just a little complex.

Passing variables into a function in Lua

I'm new to Lua, so (naturally) I got stuck at the first thing I tried to program. I'm working with an example script provided with the Corona Developer package. Here's a simplified version of the function (irrelevant material removed) I'm trying to call:
function new( imageSet, slideBackground, top, bottom )
function g:jumpToImage(num)
print(num)
local i = 0
print("jumpToImage")
print("#images", #images)
for i = 1, #images do
if i < num then
images[i].x = -screenW*.5;
elseif i > num then
images[i].x = screenW*1.5 + pad
else
images[i].x = screenW*.5 - pad
end
end
imgNum = num
initImage(imgNum)
end
end
If I try to call that function like this:
local test = slideView.new( myImages )
test.jumpToImage(2)
I get this error:
attempt to compare number with nil
at line 225. It would seem that "num" is not getting passed into the function. Why is this?
Where are you declaring g? You're adding a method to g, which doesn't exist (as a local). Then you're never returning g either. But most likely those were just copying errors or something. The real error is probably the notation that you're using to call test:jumpToImage.
You declare g:jumpToImage(num). That colon there means that the first argument should be treated as self. So really, your function is g.jumpToImage(self, num)
Later, you call it as test.jumpToImage(2). That makes the actual arguments of self be 2 and num be nil. What you want to do is test:jumpToImage(2). The colon there makes the expression expand to test.jumpToImage(test, 2)
Take a look at this page for an explanation of Lua's : syntax.