I have some expressions containing nested sums, looking like this:
and I want to substitute one of the summation indices(such as i369) for something else.
But the problem is, sometimes maxima seems to re-define the whole sum every time expr is called. So, every time I call second(expr) maxima tells me some new index names, instead of i369:
So when I call subst, nothing happens because it sees:
How to stop this from happening?
Thanks for the additional information. The changing indices are the result of sumexpand being true, and test3 is a product of summations, and it's getting resimplified according to sumexpand every time it is evaluated. The sumexpand transformation assigns new indices every time it processes a summation, so that's how you're getting different indices each time you evaluate test3.
I think the clearest way forward is to only enable sumexpand when you need to process a summation, and otherwise leave it disabled. Something like block([sumexpand: true], <whatever operations here>) enables sumexpand for the duration of the block and then restores the previous value. Something like that works for global flags in general.
As an aside, bear in mind that function definitions are always global. When you write f(x) := block(g(y) := ..., ...), the function g is not local to f; instead f and g are both globally defined. You can supply lambda expression to scanmap instead of a named function, or just pull the would-be local function out and define it outside of simplify_expr_for_extract.
Related
I'm using SPSS and hoping to create a new variable that houses the sum of a group of previous variables. The catch is: if any of the variables are recorded as "9" then I need to leave them out.
Is there a command that makes this relatively easy? I had thought of doing DO IF, but it seems like that would get extremely tedious with 6 variables as I'd have to code each possible instance unless I'm mistaken. If there is an easier way that I just haven't been able to find, I would be forever grateful!
This is what I'm thinking would need to be done, but could absolutely be wrong:
DO IF (var1<=4 AND var2<=4 AND var3<=4 AND var4<=4 AND var5<=4 AND var6<=4).
COMPUTE newvar=SUM(var1,var2,var3,var4,var5,var6).
ELSE IF (var1<=4 AND var2<=4 AND var3<=4 AND var4<=4 AND var5<=4 AND var6=9).
COMPUTE newvar=SUM(var1,var2,var3,var4,var5).
/* And so on and so forth for each possible variation of the sum.
It's not that this didn't work, I'm just checking to see if there's an easier way before committing the time to it.
Here are some ways to make it shorter:
missing values var1 to var6(9).
compute newvar=sum(var1 to var6).
Now if you don't want to just mark value 9 as missing, but to get rid of it all together:
recode var1 to var6(9=sysmis).
compute newvar=sum(var1 to var6).
If you don't want to change anything in the data, you can go:
missing values var1 to var6(9).
compute newvar=sum(var1 to var6).
missing values var1 to var6().
If all those sulutions are problematic for you, here's the classicle loop solution:
compute newvar=0.
do repeat vr=var1 to var6.
if vr<>9 newvar=newvar+vr.
end repeat.
exe.
Here's another solution just for fun:
count nines=var1 to var6(9).
compute newvar=sum(var1 to var6) - nines*9.
Introduction
I'm trying to create custom Google Sheets functions for tabletop rolls and rules, and I ran into what appears to be a technical limitation on part of Google Sheets new Named Functions feature, but I'm hoping to be wrong and hope the community here can recognize a mistake of mine or recommend a sensible workaround1.
For whatever reason, it appears that Google Sheets' new Named Functions do not accept output from other named functions as input.
I have made an example sheet with a demonstration as well as a testing zone that the community is free to mess around with.
The Problem
I am working with two named functions that I have created:
FUNCTION =ROLL_D10(count)
count: The number of dice rolls you want to roll. Default: 1
=ARRAYFORMULA(ROUNDUP(RANDARRAY(IF(AND(ISNUMBER(count),count=INT(count),count>=1),count,1),1)*10,0))
FUNCTION =ROLL_ADVANTAGE(rolls)
rolls: A singular cell or array of cells consisting of numerical rolls.
=IFERROR(LARGE(rolls,1),NA())
The goal is to be able to nest the named functions like so: =ROLL_ADVANTAGE(ROLL_D10(3))
The result should be to retrieve the highest value from a 3d10 roll. To those familiar with tabletop, this would be a double advantage roll.
What appears to be happening is that once created, the nested function will not recalculate unless the cell that contains the nested formula is changed. For example, if I change =ROLL_ADVANTAGE(ROLL_D10(3)) to =ROLL_ADVANTAGE(ROLL_D10(3))&"A", it will recalculate the ROLL_D10 function. It will not recalculate if any other On Change or Every Minute/Every Hour event is triggered.
Tests Performed
I have tested the following methods and achieved the following results. Again I invite users to see the example sheet for live examples.
r = Non-named ROLL_D10 function; R = Named ROLL_D10 function.
a = Non-named ADVANTAGE function; A = Named ADVANTAGE function.
:S = Output posted to the sheet prior to being passed as input.
:ƒ = Output passed directly as formula input.
.n = Non-named function; .N = Named function.
‘⇒’ Output passed from ROLL_D10 to ADVANTAGE function.
Tested Operation
Result
r:S …Raw formula
Success
R:S …Raw formula
Success
a:S …Raw formula
Success
A:S …Raw formula
Success
r:ƒ …Raw formula
Success
R:ƒ …Raw formula
Possibly does not work with ƒ.N ⇒ f.N
a:ƒ …Raw formula
Success
A:ƒ …Raw formula
Success
r:S ⇒ a
Success
r:S ⇒ A
Success
R:S ⇒ a
Success
R:S ⇒ A
Success
r:ƒ ⇒ a
Success
r:ƒ ⇒ A
Success
R:ƒ ⇒ a
Success
R:ƒ ⇒ A
FAILURE
Annotations
I consider a sensible workaround to be avoiding integrating advantage/disadvantage/neutral arguments into the roll functions as this increases complexity and therefore makes it less user-friendly: I do hope to make these functions available generally. If this is the only reasonable option, that is fine, but I would prefer to explore other options first.
In the formula =ROLL_ADVANTAGE(ROLL_D10(3)), the inner function ROLL_D10(3) has a single static parameter 3 that never changes. The function will not recalculate as long as the parameter remains the same. Since ROLL_D10(3) will always return the same result, the outer ROLL_ADVANTAGE() function will also return its cached result instead of recalculating.
This behavior is a side effect of the memoization used by Google Sheets to cache the return values of functions. Its purpose is to improve spreadsheet performance. As long as a function's parameters remain the same, it will return the cached result without recalculating it.
The standard recipe to make the function recalculate is to add a dummy parameter that does get changed. The signature becomes ROLL_D10(count, dummy). Then modify the formula to make the dummy parameter refer to a value that gets updated with new values every now and then, such as cell A1, like this:
=ROLL_ADVANTAGE(ROLL_D10(3, A1))
Your named function does not need to actually use the dummy parameter — its mere presence is enough to avoid the memoization effect. The named function will get called every time the value in cell A1 changes, which is not a perfect solution, but it is usually good enough for most needs. You can increment the value in cell A1 manually, or use =now() there to easily force recalculation from time to time.
Setup by running sadd a b c
When I execute this code against the set a
keystoclear1 has a single value of "b" in it.
keystoclear2 as both values in it.
local keystoclear = unpack(redis.call('smembers', KEYS[1]))
redis.call('sadd', 'keystoclear1', keystoclear)
redis.call('sadd', 'keystoclear2', unpack(redis.call('smembers', KEYS[1])))
I am by no means a lua expert, so I could just have some strange behavior here, but I would like to know what is causing it.
I tested this on both the windows and linux version of redis, with redis-cli and the stackexchange.redis client. Same behavior in all cases. This is a trivial example, I actually would like to store the results of the unpack because I need to perform several operations with it.
UPDATE: I understand the issue.
table.unpack() only returns the first element
Lua always adjusts the number of results from a function to the circumstances of the call. When we call a function as a statement, Lua discards all of its results. When we use a call as an expression, Lua keeps only the first result. We get all results only when the call is the last (or the only) expression in a list of expressions.
This case is slightly different from the one you referenced in your update. In this case unpack (may) return several elements, but you only store one and discard the rest. You can get other elements if you use local keytoclear1, keytoclear2 = ..., but it's much easier to store the table itself and unpack it as needed:
local keystoclear = redis.call('smembers', KEYS[1])
redis.call('sadd', 'keystoclear1', unpack(keystoclear))
As long as unpack is the last parameter, you'll get all the elements that are present in the table being unpacked.
I've been playing around with genetic programming for some time and started wondering how to implement looping constructs.
In the case of for loops I can think of 3 parameters:
start: starting value of counter
end: counter upper limit
expression: the expression to execute while counter < end
Now the tricky part is the expression because it generates the same value in every iteration unless counter is somehow injected into it. So I could allow the symbol for counter to be present in the expressions but then how do I prevent it from appearing outside of for loops?
Another problem is using the result of the expression. I could have a for loop which sums the results, another one that multiplies them together but that's limiting and doesn't seem right. I would like a general solution, not one for every operator.
So does anyone know a good method to implement loops in genetic programming?
Well, that's tricky. Genetic programming (the original Koza-style GP) is best suited for functional-style programming, i.e. there is no internal execution state and every node is a function that returns (and maybe takes) values, like lisp. That is a problem when the node is some loop - it is not clear what the node should return.
You could also design your loop node as a binary node. One parameter is a boolean expression that will be called before every loop and if true is returned, the loop will be executed. The second parameter would be the loop expression.
The problem you already mentioned, that there is no way of changing the loop expression. You can solve this by introducing a concept of some internal state or variables. But that leaves you with another problems like the need to define the number of variables. A variable can be realized e.g. by a tuple of functions - a setter (one argument, no return value, or it can return the argument) and getter (no arguments, returns the value of the variable).
Regarding the way of handling the loop result processing, you could step from GP to strongly typed GP or STGP for short. It is essentialy a GP with types. Your loop could then be effectively a function that returns a list of values (e.g. numbers) and you could have other functions that take such lists and calculate other values...
There is another GP algorithm (my favourite), called Grammatical Evolution (or GE) which uses context-free grammar to generate the programs. It can be used to encode type information like in STGP. You could also define the grammar in a way that classical c-like for and while loops can be generated. Some extensions to it, like Dynamically Defined Functions, could be used to implement variables dynamically.
If there is anything unclear, just comment on the answer and I'll try to clarify it.
The issue with zegkjan's answer is that there is more than one way to skin a cat.
Theres actually a simpler, and at times, better solution to creating GP datastructures than koza trees, instead using stacks.
This method is called Stack Based Genetic Programming, which is quite old (1993). This method of genetic programming removes trees entirely, you have a instruction list, and a data stack (where your functional and terminal set remain the same). You iterate through your instruction list, pushing values to the data stack, and pulling values to consume them, and returning a new value/values to the stack given your instruction. For example, consider the following genetic program.
0: PUSH TERMINAL X
1: PUSH TERMINAL X
2: MULTIPLY (A,B)
Iterating through this program will give you:
step1: DATASTACK X
step2: DATASTACK X, X
step3: DATASTACK X^2
Once you have executed all program list statements, you then just take off the number of elements from the stack that you care about (you can get multiple values out of the GP program this way). This ends up being a fast and extremely flexible method (memory locality, number of parameters doesn't matter, nor number of elements returned) you can implement fairly quickly.
To loop in this method, you can create a separate stack, an execution stack, where new special operators are used to push and pop multiple statements from the execution stack at once to be executed afterwards.
Additionally you can simply include a jump statement to move backwards in your program list, make a loop statement, or have a separate stack holding loop information. With this a genetic program could theoretically develop its own for loop.
0: PUSH TERMINAL X
1: START_LOOP 2
2: PUSH TERMINAL X
3: MULTIPLY (A, B)
4: DECREMENT_LOOP_NOT_ZERO
step1: DATASTACK X
LOOPSTACK
step2: DATASTACK X
LOOPSTACK [1,2]
step3: DATASTACK X, X
LOOPSTACK [1,2]
step4: DATASTACK X^2
LOOPSTACK [1,2]
step5: DATASTACK X^2
LOOPSTACK [1,1]
step6: DATASTACK X^2, X
LOOPSTACK [1,1]
step7: DATASTACK X^3
LOOPSTACK [1,1]
step8: DATASTACK X^3
LOOPSTACK [1,0]
Note however, with any method, it may be difficult for a GP program to actually evolve a member that has a loop, and even if it does, its likely that such a mechanism would result in a poor fitness evaluation at the start, likely removing it from the population any way. To fix this type of problem (potentially good innovations dying early due to poor early fitness), you'll need to include the concepts of demes in your genetic program to isolate genetically disparate populations.
Is there a safe way to ask if a single assignment variable in OZ is bound or not?
Using an unassigned data flow variable in a way that requires the value will cause the program to wait until a value is assigned. In a sequential environment, this means the the program hangs. Assigning a different value to a variable will cause the program to fail. So both ways "tell" me if the variable was bound but not in a safe way.
I'm looking for some function "Bound" where
local X Y=1 Xbound YBound in
Xbound={Bound? X}
Ybound={Bound? Y}
end
gives false and true for Xbound and Ybound respectively.
My use case involves processing a list where values are added incrementally with the last value always being unbound. I want to use the last bound item (the one before unbound one.) And I'm trying to work in the OZ paradigm with the least concepts added (so no mutable variables or exceptions.)
You can check whether a variable is bound with the function IsDet.
See here: http://mozart.github.io/mozart-v1/doc-1.4.0/base/node4.html (also works in Mozart 1.3.0)
A word of caution: if you are using multiple threads, this opens the door for race conditions.