Lua: Is decreasing iterator from inside of loop possible? - lua

array={}
size=10
math.randomseed(os.time())
for i=1,size do
array[i]=math.random(size)
if(i>1) then
for j=1,i do
if array[j]==array[i] then
i=i-1
break
end
end
end
end
for i=1,size do
print(array[i])
end
The code above was meant to generate an array of random numbers from 1 to 'size' avoiding repeating values. I tried to achieve that by repeating top level 'for' loop once more if newly generated value was present before somewhere in array - by decreasing its iterator. Somehow it doesn't work. Why?
Is modifying iterator value from inside of loop not possible?
Example output with repeating values in array:
>lua5.1 "pairsss.lua"
2
1
10
6
5
2
5
7
7
4
>Exit code: 0

The solution to your problem is to shuffle the array, like Random iteration to fill a table in Lua.
To answer your question, from Lua 5.1 reference manual:
§2.4.5 – For Statement
All three control expressions are evaluated only once, before the loop starts. They must all result in numbers.
That means, no matter how you change the value of i inside the for loop, it doesn't affect how the iteration is done.

You can use a set instead of an array, as done by the author of question Randomize numbers in Lua with no repeats. As one of the answers points out, as your set gets closer in size to your range of randome numbers (say, you have random numbers 1 to 100 and your set is size 50) it will be more and more difficult to find a number that hasn't already been picked. You can see that for a set of size 50 and picking a random # from 1 to 100, then by the time you have the set half full, you have a 25-50 % chance of finding the random pick is already in use in your set. In that case, shuffling is the way to go, as explained in one of the answers to that post (Randomize numbers in Lua with no repeats).

Related

How to determine if a number has a decimal point, or float?

Good afternoon. I'm constructing a binary module for a platform that uses lua for developers, and I'm accomplishing this by successive division from this video to get the remainder as an alternative, however, I am at a roadblock here to detect a decimal point.
My goal is to detect a number that has a decimal point and use successive division like the video to index into a table and loop through, for my binary module. I've tried to check if ceiling a number (that's a float) would equal rounding it + .5, this works, however, it isn't a long term solution IMO.
for _, value in pairs({4.2, 4.1, 4.9, 5}) do --> loops through a table containing numbers.
if math.ceil(value) == math.round(value+.5) then --> checks if a number ceils and equals?
local b = script:SetAttribute(tostring('Remainder'), value) --> prints on first 3 elements.
else
print('no remainder') --> prints on last element of table, '5'.
end
end
I have also tried dividing in a loop, wasn't a good way.
I've searched up some of my problems on here, google, or lua websites, none had what I was looking for, or were simply not suitable for my codebase. So, how would I accomplish checking if a number has a decimal or a remainder?
Use modulo/remainder division(%) . What that does is it checks and gives you the remainder. For instance 20%6 would give you "2" as the answer since 20÷6 = 3 remainder 2.

Fortran entries of array change seemingly at random

I have been working with a FORTRAN program. I have noticed seemingly random changes in a 1D matrix I'm working with. It is a matrix of 4000 integers. Values are added to the matrix one by one, starting with index 1 and iterating by 1 for each added value. The matrix does not get fully "filled", currently only 100 values are placed into the matrix. So one would expect that the first 100 entries of the matrix will be non-zero (all added values are non-zero) and the remaining 3900 entries will be 0. However, several of the entries of the matrix end up being large negative numbers, but I'm certain that no portion of my code touches these entries.
What could be causing this issue? I'm sorry but I can't post the code for you all to work with.
The code has several other large matrices, taking up a total of ~100 MB of space. Could this potentially be a memory issue?
Thanks!
You have to initialize your array, otherwise it will almost always contain garbage. This would do it:
array = 0.0e0 ! real array
or
array = 0.0e0 ! double precision
or
array = 0 ! integer
A "matrix" is two-dimensional; your array is one-dimensional.
Things do not change unless you ask them to change.
FORTRAN does not initialize variables other than (as I recall) in a labeled COMMON. As such, they are guaranteed to start out with garbage values. Try initializing your data with a DATA statement. If you have to initialize a labeled COMMON, you will have to supply a BLOCK DATA subprogram.

How can I generate unique random numbers in quick succession?

I have a function that is called three times in quick succession, and it needs to generate a pseudorandom integer between 1 and 6 on each pass. However I can't manage to get enough entropy out of the function.
I've tried seeding math.randomseed() with all of the following, but there's never enough variation to affect the outcome.
os.time()
tonumber(tostring(os.time()):reverse():sub(1,6))
socket.gettime() * 1000
I've also tried this snippet, but every time my application runs, it generates the same pattern of numbers in the same order. I need different(ish) numbers every time my application runs.
Any suggestions?
Bah, I needed another zero when multiplying socket.gettime(). Multiplied by 10000 there is sufficient distance between the numbers to give me a good enough seed.

Trying to implement an 8 point 1D DCT-II in labview; can only put one value in my output array

I am trying to implement a 1D DCT type II filter in Labview. The formula for this can be seen here
As you can see xk = the sum of a sum function involving an iteration of n.
As far as I know the nested for loop should handle the function with the shift registers keeping a running total of the output. My problem lies with the output the the matrix xk. There is either only one output to the matrix or each output over-writes the last output due to no indexig. trying to put the matrix inside the for loop results in an error between the shift register and the matrix:
You have connected two terminals of different types.
The source is a double and the sink is a 1D array of double
Anyone know how I can index the output to the array?
I believe this should work. Please check the math.
the inner for-loop will run either 8 times, or however many elements are in the array xn. LabVIEW uses whichever number is smaller to determine the iteration count. So if xn is empty, the for loop wont run at all. If it's 20, the for loop will run 8 times.
Regardless, the outer loop will always run 8 times, so xk will have 8 elements total.
Also, shift registers that do not initialize a value at the beginning of a for or while loop can cause problems, unless you mean to do that. The value stored in the shift register after running the first time could be a problem the second time you go to run it.

Please help on using SPSS to add scales of Likert-type

Since the last post is closed due to unclear expression, here is a edited one.
There are in total 20 items from 5 Likert-type scale questions from a questionnaire. I need to add the 20 items from 5 separate questions to create a total scale. I already got the data.
The question is just like the picture above. How can I run the command to add the 20 items from 5 separate questions? What is the command?
Is it something like Transform > Compute variable. Enter a variable name, specify which items to add up, and hey presto (e.g. "V1+V2+V3" etc)?
You can do exactly as you suggested, using the Transform -> Compute variable... function. Simply type in the name of your new scale in the Target variable box and the addition you want in the Numeric variable box.
You will see that the following SPSS syntax command is run:
COMPUTE total=v1 + v2 + v3 + v4.
EXECUTE.
If any of the variables has a missing value, the simply adding them will result in a missing value as well. If you don't want to impute for missing values, using the MEAN command in syntax works well. Also, if the variables are contiguous in the data file, you can make the syntax much more readable by using the TO modifier.
COMPUTE myscore=MEAN(variable1 TO variable5)*5.
The resulting value provides an efficient expected value.
However, it seems like the problem in this case is that the data entry process has dummy coded all of the items, producing 20 separate variables instead of 5, where each block of 4 variables has a value of 0 or 1 but represents the values 1 to 4. In this case, you can use the following syntax:
COMPUTE mycounter=1.
COMPUTE myscore=0.
EXECUTE.
DO REPEAT a=variable1 TO variable20.
COMPUTE myscore=myscore+mycounter*a.
COMPUTE mycounter=mycounter+1.
IF (mycounter=5) mycounter=1.
END REPEAT.
EXECUTE.
Note that the variables from variable1 to variable20 must have each set of dummy codes from the original items clustered together in ascending order.

Resources