Replies: 11 comments
-
A quick follow-up: I see that if I set check_for_nan to |
Beta Was this translation helpful? Give feedback.
-
You could write your own atomic function that computes pow(x, y); see In fact, this is a good way to experiment with the design of a better computation. |
Beta Was this translation helpful? Give feedback.
-
It might easier to do what you want using conditional expressions and a discrete function that returns the integer part of an AD value; see You would compute the result two ways:
Then, using the discrete function and a conditonal expression, you could choose pow_int when the AD value was equal to its integer part, otherwise use the log method. |
Beta Was this translation helpful? Give feedback.
-
Thanks Brad. Those options make sense. It looks like the |
Beta Was this translation helpful? Give feedback.
-
You are correct, one could only have a finite number of integer cases that would with conditional expressions. Perhaps you can make an atomic function that works for you. I would start with just function values, then add first order forward mode. Otherwise, I do not know how soon I will be able to look into extending pow as you suggest above. |
Beta Was this translation helpful? Give feedback.
-
My testing indicates that pow(x, y) for x < 0 and y integer works; see PowTestEight in It is only the case where x = 0 and y is a positive integer that is a problem ? |
Beta Was this translation helpful? Give feedback.
-
I have added an example that may solve your problem. Please take a look at |
Beta Was this translation helpful? Give feedback.
-
Thanks for all of this! I'm thinking of the case where x and y are both variables. I modified your PowTestEight in https://github.com/perrydv/CppADtests/blob/main/PowTestEight_modified.cpp |
Beta Was this translation helpful? Give feedback.
-
I see the problem. In the representation |
Beta Was this translation helpful? Give feedback.
-
As an aside, you may find it useful, for small test cases, to use
would should the operation. You need to use the include directory |
Beta Was this translation helpful? Give feedback.
-
I recently did some improvement to the pow function; see discussion #93 |
Beta Was this translation helpful? Give feedback.
-
Per Brad's email of two days ago, I'm starting a GitHub Discussion instead of using the mailing list to ask my question.
I get that handling of pow(x, y) is tricky because the calculations are not well defined if x < 0 and y is not an integer. CppAD provides pow(x, y) valid for x > 0 and pow_int(x, y) valid for any x when y is a constant integer.
I have use cases where CppAD taping is done by generic functions that call a lot of other functions that are themselves code-generated from end-user specifications. These are then used in many different ways.
What I would ideally like to have happen for pow(x, y), if both x and y are variables and x < 0, is that derivatives with respect to x are valid if y is integer-valued, NaN otherwise, and derivatives with respect to y are NaN. That would allow a user to get valid derivatives if only those with respect to x are sought and y is integer-valued, and to (correctly) get a NaN if invalid derivatives are sought. The current behavior is to abort.
If I follow, the implementation in pow_op.hpp is defined as having three outputs, the first two of which are internal (log(x) and y * log(x) in 0th order) for potential use in higher-order sweeps. If I make y a dynamic parameter, at least I can change its value via new_dynamic. If y has integer value and x <= 0, there are still NaNs from log(x) in the two internal outputs of pow_op, but they don't seem to propagate to cause a problem, as far as my small tests went. But in my generic use case, what I really need is for y to be a variable without triggering aborts based on particular values during sweeps.
Is there a good way to do this? Thanks for any ideas.
Beta Was this translation helpful? Give feedback.
All reactions