Constraint that excludes constants that are not (part of) coefficients #713
-
I'm trying to figure out how to implement a constraint that excludes any constants that are not a coefficient, and not part of any coefficient. Basic example: I searched through previous discussions about custom losses, which allow to do a lot of cool things but I haven't found a solution for the above yet. At first, I thought node.constant would be helpful, but as I understand this would also be True for a, b and c in the example above. So how to differentiate between a b c, and d in this example? |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 1 reply
-
Just giving this a nudge, which I hope is ok. |
Beta Was this translation helpful? Give feedback.
-
Sorry for the late reply @GoldenGoldy. This constraint sounds a bit tricky but it is certainly doable. Have a look at https://symbolicml.org/DynamicExpressions.jl/dev/examples/base_operations/ to learn how to write custom constraints. For your problem I suppose I would have some check like: num_constants_under_multiply = sum(tree) do node
is_mul = node.degree == 2 && node.op == 1 # Assuming * was passed as first operator
if is_mul
left = node.l
right = node.r
left_is_constant = left.degree == 0 && left.constant
right_is_constant = right.degree == 0 && right.constant
return left_is_constant + right_is_constant
else
return 0
end
end This will count how many times num_constants = count(tree) do node
node.degree == 0 && node.constant
end And I guess if And then you would include this in a custom loss and add some penalty term for a violation. Hope this helps! |
Beta Was this translation helpful? Give feedback.
-
@MilesCranmer Thanks for the detailed reply! |
Beta Was this translation helpful? Give feedback.
-
Cool. I guess the one other thing it doesn't take into account is that you could still have things like num_constants_under_multiply = count(tree) do node
is_mul = node.degree == 2 && node.op == 1 # Assuming * was passed as first operator
if is_mul && node.l.degree == 0 && node.l.constant
return any(subnode -> subnode.degree == 0 && !subnode.constant, node.r)
elseif is_mul && node.r.degree == 0 && node.r.constant
return any(subnode -> subnode.degree == 0 && !subnode.constant, node.l)
else
return false
end
end Basically the |
Beta Was this translation helpful? Give feedback.
Sorry for the late reply @GoldenGoldy. This constraint sounds a bit tricky but it is certainly doable. Have a look at https://symbolicml.org/DynamicExpressions.jl/dev/examples/base_operations/ to learn how to write custom constraints. For your problem I suppose I would have some check like: