Interpret line of Q code - kdb

Trying to understand what this function does:
yr:{ yr:.z.T+1000*x; -1 string .z.Z; while[(.z.T < yr); ZZ,::.z.Z]}
I understand .z.Z gets the datetime, and that execution is from right to left. what is ZZ? What is .z.T?
Essentially, what does the line accomplish?

Here :: means assign the value on the right to the global variable on
the left
ZZ is a global variable
ZZ,::.z.Z is shorthand for ZZ::ZZ,.z.Z
So it appends the latest time to the global variable ZZ.
e.g.
q)f:{ZZ,::2}
q)f[]
q)ZZ
,2
q)f[]
q)ZZ
2 2
.z.T is the time.

.z.T is the current time in the time datatype; the underlying number in times is milliseconds since midnight, so adding 1000*x gives a time x seconds in the future.
-1 string .z.Z prints the current datetime to stdout.
while[(.z.T < yr); ..] loops as long as the current time is less than yr (x seconds in the future).
ZZ,::.z.Z appends the current datetime to a global variable named ZZ.
some additional notes:
the datetime datatype is in general deprecated in favor of timestamp.
the parentheses around the test condition are redundant.
the second : is also redundant, but for more interesting reasons: ,: (like all of the two-argument "writeback" functions (x+:1, y-:2, etc.)) always modifies either a global or a local variable, depending on whether a local of that name exists in the function.
proof:
q)delete from`.;
q){ZZ:(); yr:.z.T+1000*x; -1 string .z.Z; while[(.z.T < yr); ZZ,::.z.Z]}1
2014.04.30T18:26:24.592
q)ZZ
'ZZ
q)
the ZZ being modified inside the while loop in that version of the function was the local variable declared in the first statement, not a global one as one might assume given the presence of a :: in the modification statement.
anyway, if you want to do it like this, it should at the very least be rewritten to yr:{ yr:.z.T+1000*x; -1 string .z.Z; while[.z.T < yr; ZZ,:.z.Z]}.

There is a nicer rewrite of this to make it much more idiomatic. It takes advantage of the overload of \ to iterate. Check out http://code.kx.com/q/ref/adverbs/#converge-iterate
The current function you have, takes the current time (.z.T) and adds x number of seconds (it multiplies by 1000 to make it milliseconds). This becomes your bound, and then as long as the current time is less than that, you append .z.Z (the datetime marker) to a global list ZZ.
The version below will do the same with a couple advantages:you avoid using a global and you write more idiomatic code
f2:{{.z.Z}\[{y; .z.T<x}.z.T+1e3*x; .z.Z]}
While your condition {y; .z.T<x}.z.T+1e3*x is true, your loop will continue to iterate. Note that we make sure to pass in the time limit from outside, so that it is not revaluated it each time, additionally we need a dummy parameter y, as it will try to apply this condition to the result of our iteration, but we don't really want that, since that is .z.Z. Each time it iterates it will evaluate .z.Z returning the datetime. Since you are using \ and not / you will get the entire list generated.
q)f2:{{.z.Z}\[{y; .z.T<x}.z.T+1e3*x; .z.Z]}
q)f2 1
2014.04.30T17:40:23.357 2014.04.30T17:40:23.357 .......
That being said, if you're looking to generate a sequence of datetime values, from now to now+x, this is not the best way to do that, since your .z.Z stamp will reflect the time it takes your machine to actually evaluate that.
CORRECTION:
I did not correctly explain the reason our condition testing lambda is {y; .z.T<x}.z.T+1e3*x. You want to make sure your .z.T+1e3*x is only evaluated at the start, so you do not want your bound to be inside the function. Additionally, if you were to leave out the y param, then {z.T<x}.z.T+1e3*x would immediately evaluate to false, and your iteration would return a type error as it tries to apply your iteration result to 0b at each cycle of the loop. By keeping y and just not using it, we make sure to delay this evaluation and create a lambda that correctly tests our bound.

What This Function is doing:
This function accepts one parameter(should be int) and add those many seconds to current time(lets say it future time). Then it starts a loop from current time to future time and in every iteration, append current date and time to global list(referred by variable ZZ).
How to Call: yr[2]
Explanation:
yr:.z.T+1000*x
.z.T give you current local time.
1000 is equivalent to 1 seconds. So it is adding x seconds to current time and storing it in variable yr. ( : means assignment (=))
ZZ,::.z.Z
:: is used to assign something to global variable. So ZZ is a
global variable which is list (like array).
, is used to append. Above statement is equivalent to ZZ : ZZ , .z.Z
.z.Z gives current local date and time.
while[(.z.T < yr);...]
This is a condition for the loop. So it takes the current time(.z.T)
and check whether it is lesser than future time that was calculated
in first statement.
Loop will end once current time =yr(future time).
Finally you'll have global list which you can access using variable
ZZ.

Related

Call a function every X seconds when activated - Scala

I have a variable which is going to help me check if 10 seconds has passed.
private val currTime: Long = System.currentTimeMillis()
private val time: Long = 10000
I want something where, if a function foo is called, it will reset currTime to be the current time. That's the easy part which I can do. The tough part, and part 2 of this, is that if currTime at any point exceeds time, I want to change a boolean (say isHappy) from true to false - this can be in a function called bar.
I come from C#, so i'm not sure how to do this - typically we'd use a dispatcher timer but i have no idea how to achieve this is Scala.
I've seen scheduler examples and fixed interval examples, but this is more of a moving target... a condition that can be met at any time.
In simpler terms, it's like having 2 ints. Int A and Int B. When the sum of A and B is over 10, a function is triggered. A and B are forever changing in different functions in that class. How can we create a trigger?

`[~,ui] = Unique(Day)` what is this doing?

When looking at Matlab code I have stumbled upon the following line of code:
[~,ui] = Unique(Day)
(Where Day is the vector containing a numeric value of day like so: 1,2,3, etc.)
What is it doing? I have noticed that it creates some kind of unique identifiers for the numeric value of the day (i.e. for 1 to 31) as well as a variable called Volume. What is Volume?
[~,ui] = Unique(Day) evaluates the function Unique with input argument Day.
This function has 2 outputs, and if you want to use both, you would write
[a,b]=Unique(Day). However, if you need only second output, you can put ~ instead of the first argument. So, your first output will not be saved.
It is impossible to answer, what Volume means, because you didn't provide the code of the function Unique.

clearer explanation of function level scope for recursion

This is an example from the book 'Matlab for Neuroscientists'. I don't understand the order in which, or why, g gets assigned a new value after each recursion. Nor do I understand why "factorial2" is included in the final line of code.
here is a link to the text
Basically, I am asking for someone to re-word the authors explanation (circled in red) of how the function works, as if they were explaining the concept and processes to a 5-year old. I'm brand new to programming. I thought I understood how this worked from reading another book, but now this authors explanation is causing nothing but confusion. Many thanks to anyone who can help!!
A recursive method works by breaking a larger problem into smaller problems each time the method is called. This allows you to break what would be a difficult problem; a factorial summation, into a series of smaller problems.
Each recursive function has 2 parts:
1) The base case: The lowest value that we care about evaluating. Usually this goes to zero or one.
if (num == 1)
out = 1;
end
2) The general case: The general case is what we are going to call until we reach the base case. We call the function again, but this time with 1 less than the previous function started with. This allows us to work our way towards the base case.
out = num + factorial(num-1);
This statement means that we are going to firstly call the function with 1 less than what this function with; we started with three, the next call starts with two, the call after that starts with 1 (Which triggers our base case!)
Once our base case is reached, the methods "recurse-out". This means they bounce backwards, back into the function that called it, bringing all the data from the functions below it!It is at this point that our summation actually occurs.
Once the original function is reached, we have our final summation.
For example, let's say you want the summation of the first 3 integers.
The first recursive call is passed the number 3.
function [out] = factorial(num)
%//Base case
if (num == 1)
out = 1;
end
%//General case
out = num + factorial(num-1);
Walking through the function calls:
factorial(3); //Initial function call
//Becomes..
factorial(1) + factorial(2) + factorial(3) = returned value
This gives us a result of 6!

MATLAB Beginner recursive functions

Just having a little difficulty with the syntax of matlab functions;
function f = fact(x)
if x == 1
return
else
f = 1 - x*(fact(x-1))
end
end
When calling this function in the command window with the argument 10 I receive the error
Undefined function 'fact' for input arguments of type 'double'.
Error in recursion (line 6)
f = 1 - x*(fact(x-1))
I've had a look around and solutions for the first revolve around the pathing of the m-file which doesn't seem to be a problem as other files in the same directory run fine,
The second I'm not sure why the error in line 6 occurs, my guess is it has something to do with the variable and function names.
As a side question, are both these end statements necessary?
Thanks!
The most obvious error is your function filename. You have a function called fact defined in your code but you named your file recursion. Make sure that both your function name and the filename are both called fact.
If you were to name your file as recursion, then make the function name defined in your code as fact, this is what would happen if you tried calling your code:
>> f = recursion(10);
Undefined function 'fact' for input arguments of type 'double'.
Error in recursion (line 6)
f = 1 - x*(fact(x-1));
... look familiar?
As such make sure your filename and your function name are named the same. In fact, in the MATLAB editor, it should automatically give you an error saying that both of these are not the same.
There is also another error in your code. The base case is not defined properly. Always remember when you are writing recursive algorithms is that eventually the function is going to return... and that's when you hit the base case. We can see here that it is when x = 1. When x = 1, you're supposed to assign something to f which is the output. You are simply exiting the function, and so when x becomes 1, your code will spit out an error saying that f was not assigned when the function finishes. As such, you need to figure out what your base case is. I'm going to assume that your base case (when x = 1) is going to equal 0. You will obviously need to change this as I don't know what your code is actually computing. Basically, you need to do this:
function f = fact(x)
if x == 1
f = 0; %// Base case needs to change according to your specs
else
f = 1 - x*(fact(x-1))
end
end
When I do this, I get the following output when x = 10
>> f = fact(10);
f =
1334961
I don't get an error when I run this code now. Also, check to see if you have any variables named fact in your workspace. When this happens, you are in fact shadowing over your function with a variable, so it is actually trying to access the variable called fact instead. As such, try clearing your workspace by doing clear all;, then try this code again.
One warning
If you were to specify x to be 0 or negative, this function will never stop. As such, you need to provide some check and perform the proper action when this happens. Also, you need to make sure that you specify what type of inputs are accepted for x. Judging from the context, x are positive integers only. As what #Glen_b has noted, should you provide any number that isn't a positive integer, this function will never stop as x will never equal 1 down the recursion pipeline.
To answer your optional question
The first end statement is required to end the if statement. The second end statement isn't required, but it's good practice anyway. However, if you have multiple functions defined inside your function file, then yes it is most definitely required to properly signify that the end of that function is defined there. However, you don't need it if you're only writing one function per file, but I would recommend keeping it there as it's good practice.

Matlab: recursive algorithm to return the run count easily without profiler?

I would like to get the number of iterations that the recursive mlfnonneg requires. Currently, I use profiler for this but it would be more useful to get the number as a return value from the function. Is there any easy way to get it?
I measure the running time of a function like this
h=#() mlfnonneg(lb,ub,mlfBinCor,method);
tElapsed=timeit(h);
and now the function mlfnonneg should return the number of iterations. I have considered adding a ticker that the function always returns but I don't know how to get the return value after using timeit. How to get the running time and the running count of the recursive algorithm elegantly?
You can always add an optional return value to a function which you can use as a counter. Something like this:
[... count] = f(...)
% Do stuff here
if <some condition>
% Recurse
[... count] = f(...);
count = count + 1;
else
% Terminal condition
count = 1;
end
You should just call your function one more time to get the count. This should not be a significant problem, since timeit actually performs multiple calls to your function to get an average metric.
I don't know if this is an option for you - but you could create a global variable IT_COUNT that you declare both at the top level, and inside your function.
Before calling timeit() you set the variable to zero; inside the routine you increment it for every loop. When the function returns you print out the result - and there is your answer.
It does depend on you being able to modify the code to mlfnonneg to include the counter. I don't see an easy way around that, but maybe others have a better idea.
update inspired by Luis Mendo's (now deleted) answer that basically says the same thing, a bit more information.
In your mlfnonneg routine, add the following two lines (in a place where they are executed "once per iteration"):
global IT_COUNT;
if numel(IT_COUNT)==0, IT_COUNT = 1; else IT_COUNT = IT_COUNT + 1; end
This ensures that if you forget to create the variable at the top level, the code will not crash (you will thank me in the future, when you re-use this code and don't remember that you need a global variable...)
At the top level, add
global IT_COUNT
IT_COUNT = 0;
Then run your timeit() routine; finally use
fprintf(1, "The number of iterations was %d\n", IT_COUNT);
to get the answer you were looking for.