I have been researching a solution to a problem that I just can not seem to avoid, and have yet to find a solution.
In brief, I am trying to calculate unique probabilities that lead to a "1 or 0" for more than one variable, but all in one cell.
Here is my working code line that represents the probability of just one variable:
=sum(if(randbetween(1,100) > subtotal(1,L23), 0, 1))
What I am trying to figure out is how to repeat this function times x, but with it yielding a different randbetween number each time, all in one cell.
As my x variable can represent 10 different independent variables at this time, and stem over 30 specific formula lengths for each IV, utilizing the preset workaround would lead me to creating hundreds of cells of data. I obviously do not want that clutter.
If code worked the way I wanted it to, the best formula-esque way I would describe what I wanted to happen is this:
=sum(repeatuniqueformula(sum(if(randbetween(1,100) > subtotal(1,L23), 0, 1)), x))
Simplified, relevant question gathered from a problem by problem analysis:
How to replicate a function in the function line that allows for the randbetween to recalculate each time.
Sub-information: If you simply multiply the function by lets say 6, it will multiply the answer of the randbetween function without recalculating.
=sum(if(randbetween(1,100) > subtotal(1,L23), 0, 1)*6)
Alternatively, I could do a workaround and create other cells with individual randbetween functions, but that causes a lot of manual work due to having to adjust the number of times a function in a line is repeated.
=sum(if(Q2 > subtotal(1,L15), 0, 1),if(Q3 > subtotal(1,L15), 0, 1),if(Q4 > subtotal(1,L15), 0, 1),if(Q5 > subtotal(1,L15), 0, 1),if(Q6 > subtotal(1,L15), 0, 1),if(Q7 > subtotal(1,L15), 0, 1),if(Q8 > subtotal(1,L15), 0, 1))
The alternative is both cluttery and takes a lot of effort to maintain, as changing the number of "x" will change the amount of
if(Q2 > subtotal(1,L15), 0, 1)
I would need.
In order to get what you want to happen (=sum(repeatuniqueformula(sum(if(randbetween(1,100) > subtotal(1,L23), 0, 1)), x))) you will have to create a custom function by using Google Apps Script, but x should be replaced by number or by a reference to a cell having a value or formula that returns that value.
References
https://developers.google.com/apps-script/guides/sheets
https://developers.google.com/apps-script/guides/sheets/functions
Related
Say I have two variables a and b. I would like to define the following relation/constraint between them:
a = 1, b % 12 = 1 or b % 12 = 0
a = 2, b % 12 = 0
Some solutions are
a = 1, b = 1
a = 1, b = 12
a = 2, b = 12
I'm currently modelling this in a straightforward way (and adding an extra condition on top):
rhs = Or(
And(a == 1, Or(b % 12 == 1, b % 12 == 0)),
And(a == 2, Or(b % 12 == 0))
)
lhs = And(b > 10)
solver.add(Implies(lhs, rhs))
However, this becomes very slow as I increase the number of variables and constraints.
Is there a better way to model this? Maybe a function? But I would like to allow search to run "in both directions", i.e. given a value of b, we should be able to identify a value of a, and vice versa.
Based on your comment, it looks like the use of integers is unnecessarily complicating your constraints.
If you need to stick to "numbers" for some other reason, then I'd recommend asserting 0 <= b and b < 12 globally (to represent all 12 notes), which can help the solver reduce the search space. However, division/modulus are always hard for SMT solvers, but perhaps you do not need them at all: In fact, I'd recommend not using numbers to represent notes in the first place. Instead use an enumeration:
Note, (A, B, C) = EnumSort('Note', ('A', 'B', 'C'))
(I've only written the first three above; you can add the remaining 9.)
This very clearly communicates to the solver that you're dealing with a finite collection of distinct items. You should also consider representing octave as some enum-type, or at least restrict it to be in some small range that covers the first 6-7 octaves which I assume you're interested in.
You can read more about enums in z3 here: https://ericpony.github.io/z3py-tutorial/advanced-examples.htm (Scroll down to the part that talks about "enumerations.")
You haven't told us how octaves/notes constrain each other in your system; but it should be easy to capture them using regular functions that take octaves and return possible notes. You should post actual code that people can run so they can see what the bottle-necks can be.
Let's say I have 12 non-empty cells:
A
B
C
D
E
F
G
H
I
J
K
L
I usually use the following formula:
=IF(COUNTIF(A:A,"<>")=12,"OK","ERROR")
But if there are 8 non-empty cells I also want it to be OK, so I change it to:
=IF(COUNTIF(A:A,"<>")=12,"OK",IF(COUNTIF(A:A,"<>")=8,"OK","ERROR"))
I need to add more IF functions for all numbers multiple of 4, as they are all OK.
Is there any way to already warn a formula that whenever it is a multiple of 4, such as 4, 8, 12, 16, 20, 24 and so on, return the value OK?
According to the tip given by the user #Calculuswhiz in this comment → OK if the number of non-empty cells is a multiple of number 4, a simple way to solve the problem is to work with the MOD function, which returns the result of the module operator, the rest of a division operation.
Then, when the remainder is equal to 0, it is automatically noted that the number is a multiple of which it is trying to divide, in which case the formula that solves the problem would be as follows:
=IF(MOD(COUNTIF(A:A,"<>"),4)=0,"OK","ERROR")
I would like to know if it is possible to bound the range of values of a universally quantified variable in Z3.
For example, let's assume that I have a variable of type Real called "time" which is used to model the time in the system.
Let's say that I have an assertion which says that the value of some unary function "func1" shall always be between 1 and 100. The function takes the input the time variable. Expressed in Z3, I have encoded the property as following:
ForAll(time, And(func1(time) >= 1, func1(time) <= 100))
Please note that I explicitly need the time variable to be universally quantified, because I want the Z3 go give me unsat if I inject property of following type:
Exists(time, func1(time) == 101)
As far as my understanding goes for Z3, all the constants have mathematical (theoretical) and not computer (practical) implementation i.e. their values are not bound (unfortunately I cannot point to the resource where I have read this at the moment). Assume that with time I model time in my systems, and according to the system constrains it cannot run for more than x hours, which I can use and say that value of time is between 0 and x*60'*60 to give the maximum execution time in seconds. I know that I can assert the allowed values for time with the following assertion:
And(time >= 0, time <= x*60*60)
but will it affect the universal quantification given in 1?
Consequently, this should lead to a situation where if property 2 is injected and for value of time I specify x*60*60 + 1, it should not be unset since the ForAll is valid only for the values of time.
but will it affect the universal quantification given in 1)?
Note that
ForAll(time, And(func1(time) >= 1, func1(time) <= 100))
treats the variable "time" as bound. The formula has the same meaning as:
ForAll(xx, And(func1(xx) >= 1, func1(xx) <= 100))
When you assert the above, the meaning is that any instantiation of xx holds (is asserted). In particular, you can instantiate the quantified variable with the free variable "time" and in particular, you can instantiate with x*60*60+1 producing the assertion:
And(func1(x*60*60+1) >= 1, func1(x*60*60+1) <= 100)
Suppose you wanted to say that
And(func1(xx) >= 1, func1(xx) <= 100))
holds for every value xx between 0 and x*60*60, then you can write:
ForAll(xx, Implies(And(xx >= 0, xx <= x*60*60), And(func1(xx) >= 1, func1(xx) <= 100)))
(unfortunately I cannot point to the resource where I have read this at the moment).
Reasonable logic text books or foundations of computer science books should explain this in depth. Z3 supports a standard first-order many-sorted logic (with background theories).
This question already has answers here:
Lua for loop reduce i? Weird behavior [duplicate]
(3 answers)
Closed 7 years ago.
im trying this in lua:
for i = 1, 10,1 do
print(i)
i = i+2
end
I would expect the following output:
1,4,7,10
However, it seems like i is getting not affected, so it gives me:
1,2,3,4,5,6,7,8,9,10
Can someone tell my a bit about the background concept and what is the right way to modify the counter variable?
As Colonel Thirty Two said, there is no way to modify a loop variable in Lua. Or rather more to the point, the loop counter in Lua is hidden from you. The variable i in your case is merely a copy of the counter's current value. So changing it does nothing; it will be overwritten by the actual hidden counter every time the loop cycles.
When you write a for loop in Lua, it always means exactly what it says. This is good, since it makes it abundantly clear when you're doing looping over a fixed sequence (whether a count or a set of data) and when you're doing something more complicated.
for is for fixed loops; if you want dynamic looping, you must use a while loop. That way, the reader of the code is aware that looping is not fixed; that it's under your control.
When using a Numeric for loop, you can change the increment by the third value, in your example you set it to 1.
To see what I mean:
for i = 1,10,3 do
print(i)
end
However this isn't always a practical solution, because often times you'll only want to modify the loop variable under specific conditions. When you wish to do this, you can use a while loop (or if you want your code to run at least once, a repeat loop):
local i = 1
while i < 10 do
print(i)
i = i + 1
end
Using a while loop you have full control over the condition, and any variables (be they global or upvalues).
All answers / comments so far only suggested while loops; here's two more ways of working around this problem:
If you always have the same step size, which just isn't 1, you can explicitly give the step size as in for i =start,end,stepdo … end, e.g. for i = 1, 10, 3 do … or for i = 10, 1, -1 do …. If you need varying step sizes, that won't work.
A "problem" with while-loops is that you always have to manually increment your counter and forgetting this in a sub-branch easily leads to infinite loops. I've seen the following pattern a few times:
local diff = 0
for i = 1, n do
i = i+diff
if i > n then break end
-- code here
-- and to change i for the next round, do something like
if some_condition then
diff = diff + 1 -- skip 1 forward
end
end
This way, you cannot forget incrementing i, and you still have the adjusted i available in your code. The deltas are also kept in a separate variable, so scanning this for bugs is relatively easy. (i autoincrements so must work, any assignment to i below the loop body's first line is an error, check whether you are/n't assigning diff, check branches, …)
I work with SPSS and have difficulty finding/generating a syntax for counting cases.
I have about 120 cases and five variables. I need to know the count /proportion of cases where just one, more than one, or all of the cases have a value of 1 (dichotomous variable). Then I need to compute a new variable that shows the number / proportion of cases which include all of the aforementioned cases (also dichotomous).
For example case number one: var1=1, var2=1, var3=1, var4=0, var5=0 --> newvariable=1.
Case number two: var1=0, var2=0, var3=0, var4=0, var5=0 --> newvariable=1.
And so on...
Can anybody help me with a syntax?
Help would much appreciated!
Here we can use the sum of the variables to determine your conditions. So using a scratch variable that is the sum, we can see if it is equal to 1, more than 1 or 5 in your example.
compute #sum = SUM(var1 to var5).
compute just_one = (#sum = 1).
compute more_one = (#sum > 1).
compute all_one = (#sum = 5).
Similarly, all_one could be computed using the ANY command to evaluate if any zeroes exist, i.e. compute all_one = ANY(0,var1 to var5).. These code snippets assume that var1 to var5 are contiguous in the data frame, if not they just need to be replaced with var1,var2,var3,var4,var5 in all given instances.
You could read up on the logical function ANY in the Command Syntax Reference manual, if you negated a test for ANY with "0", then that is effectively a test for all "1"s. Use of the COUNT command would be another approach.