//Computes the sum of a series.Which series is it,though...
//tip:don't set both compile time flags,though apparently ChatGPT thinks
//i could use a "mixed partial derivative" or smth...
//derivatives not tested..yet.
double FUNC_NAME(double coeff[], double th, double ph, int level) {
double cos_th = cos(th), nsin_th = -sin(th);
double rt2 = 0, zero = 0;
double cosph[MAX_SH_LEVEL + 1] = { 1 };
double sinph[MAX_SH_LEVEL + 1] = { 0 };
double expct[MAX_SH_LEVEL + 1] = { 1 };
double expox[MAX_SH_LEVEL + 1] = { 1 };
#ifdef DERIVATIVE_TH
double dexpct[MAX_SH_LEVEL + 1] = { 0 };
double dexpox[MAX_SH_LEVEL + 1] = { 0 };
#endif
double preve = 1, prevx = 1;
for (int m = 1; m <= level; ++m) {
#ifdef DERIVATIVE_PH
cosph[m] = -m * sin(m * ph);
sinph[m] = m * cos(m * ph);
#else
cosph[m] = cos(m * ph);
sinph[m] = sin(m * ph);
#endif
#ifdef DERIVATIVE_TH
dexpct[m] = preve * nsin_th * m;
dexpox[m] = -prevx * cos_th * m;
#endif
preve = expct[m] = preve * cos_th;
prevx = expox[m] = prevx * nsin_th;
}
double* lpc = lpoly_coeff, * lpn = lpoly_norm, * tc = coeff;
for (int l = 0; l <= level; l++) {
double rest = 0;
for (int i = 0; i < l + 1; i++) {
rest += *(lpc++) * expct[i];
}
zero += *(lpn++) * *tc * rest;
for (int abs_m = 1; abs_m <= l; abs_m++) {
rest = 0;
double E = expox[abs_m];
#ifdef DERIVATIVE_TH
double dE = dexpox[abs_m];
#endif
for (int i = 0; i < l + 1; i++) {
#ifdef DERIVATIVE_TH
rest += *(lpc++) * (expct[i] * dE + dexpct[i] * E);//product rule.annoying here...
#else
rest += *(lpc++) * expct[i] * E;
#endif
}
double nplm = rest * *(lpn++);
rt2 += nplm * (tc[abs_m] * cosph[abs_m] + tc[-abs_m] * sinph[abs_m]);
}
tc += 2 * l + 2;
}
return SQRT_2 * rt2 + zero;
}
#Inconsistency in derivative calculation
75 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.
the derivative functions make completely different results than using numerical methods to compute the derivative
like it isn't a problem with the epsilon in the numerical method,it just converges to a different self-consistent value than the derivative function.
(don't try to find problems about the non-derivative version of the function not doing what it should,because then the derivative version will too,and it would still be consistent)
So are you saying you made this code or ChatGPT did?
But this code can be improved in a number of ways that will make this a lot more testable:
- Remove all the prepocessor bollocks and change them for template boolean flags and
if constexpr - Define the constants inside the scope rather than using global variables, use constants out of
<numbers>header - Don't use a raw style c-arrays, use a span instead where the extent are with the type and are less prone to buffer overflow
- Split the inner logic into it's own functions, this will make the code a lot more readable and easier to comprehend.
The will hopefully become more clear during your refactoring, I have an idea of what it is but really, me telling you won't help, and you really need to know exacty what is going on in this function rather than asking chatgpt
I did.I optimized the hell out of an SH function and then altered it to be its derivative
- yeah,right,thta would be a good method.I didn't know that templates could be used to compile-time modify code when I wrote this.
- which ones?sqrt_2?
- the code REALLY needs performance,and BOFs don't happen here because I checked meticulously that all those iterator iteration matches exactly with how I precomputed the arrays,so here it is fine but yeah next time i'll use less error-prone types.
- the code REALLY needs performance,either I suck at memory management or millions of function calls per 1/60 of asecond costs a lot of time.
The main problem is self-inconsistency,where the problem is that the reported derivatives are not actually the derivatives of the function.Since the macros are very simple(and do not involve change of control flow),it should be easy to see if the derivatives would match.
The problem is that they don't when they should.I checked the simpler d/dph,and it has nothing wrong with it apart from that it is wrong.
The function is also a pure function despite the global coefficient arrays,so there aren't any goofy self-modifying arrays that are actually related to th and ph and so have to be differentiated while I assumed that they are constants.
alr i did some pen and papering
rest = 0;
for (int i = 0; i < l + 1; i++) {
rest += *(lpc++) * expct[i];
}
should be
rest = 0;
for (int i = 0; i < l + 1; i++) {
#ifdef DERIVATIVE_TH
rest += *(lpc++) * dexpct[i];
#else
rest += *(lpc++) * expct[i];
#endif
}
(ignore the indentation
@sand lance
It looks like you may have code formatting errors in your message
Note: Make sure to use back-ticks (`) and not quotes (')
Note: Make sure to specify a highlighting language, e.g. `cpp`, after the back-ticks
Markup
```cpp
int main() {}
```
Result
int main() {}
also zero should hold the value 0 if derivative ph
yayyy now my code obeys conservation of energy!!
(more datapoints not shown)
(this is ofc not equal,because i did not count angular kinetic energy)
(also every time the failsafe in the collision checking function runs,it teleports the object in a direction that's usually mostly up.this gives it free gravitational potential energy)
use dual numbers
kinda
ohh automatic differentiation that's where you're going?
ohh so it's like how you use quaternions for rotation
binomial expansion of dual numbers(well,not quite,as the actually numbers it would be a "monomial expansion" but)
happens to have the same structure as differentiation
alr so every type of complex number i know can be represented as a matrix then
ig i'll use those numbers next time i need differentiation
this time it turned out the two problems were
- constant term not differentiated.remember linearity doesn't mean ignore constants,it means ignore constants if they multiply with exactly one(1) non-constant.otherwise you either remove the term or use the product rule properly in its full form.this is also why newton's law sometimes fails btw.
- initially i made a mistake opposite to (1) where I neglected to use the product rule.so then i used the product rule,but that requires two things for each expression instead of one,so i undid the part where i substituted the original with a derivative,and so another unrelated part happened to get the original while it didn't need a product rule and so got a derivative.
is there a way to automatically simplify any function that boils down to computing a polynomial without any side effects?
like computer function not math function
template<typename T>
class Dual{
T y;
T dy;
public:
Dual(int y, int dy = 0) : y(y), dy(dy) {}
T operator*(const T& other){
return Dual(dy*other.y + y*other.dy);
} //just one example
};
oh yea that's just the product rule
you dont store the formula, you store the values of the function and the derivative
you can implement all derivation rules like this
and everything else is done by the linearity
well at an earlier stage of development i had a different issue where the function was too slow
Dual sin(const Dual& lhs){
return Dual(sin(y), cos(y));
}
(i mean to be fair computing models in run time 60 FPS isn't exactly what one usually does)
so i had to precompute two kinds of coefficients(one for the normalization the other for the associated legendre polynomials,they are called polynomials so they also need coefficients)
and substitute the l poly calculation so i could make optimizations such as not computing (-sin(th)**m was every call to the l poly function and not forgetting trig identities such as sqrt(1-cos2(x))=cos(x) (yes,that is exactly why that array is expox,it stood for Ox which looked like the APL operator for sqrt(1-x*x) iirc)
can i trust the compiler to optimize this down?
idk if they would be optimized as constexpr or smth
so kinda worried about a ton of copying and other unnecessary memory operations
you can just make it constexpr if you want to
c++26 cmath is constexpr
ohh
gcc's was constexpr before
oh yea last time i looked it up because my SQRT_2 wasn't constexpr lol
turns out my settings didn't support it
oh is it still beta?
oh ofc it is
it's not 2026 yet lol
SQRT_2 is a macro
...
wait it already is?
i mean im sure i used the macros SQRT_2 but i cant find it on cppref
yes that will work
mb you defined it lol
nah
wait you can have non-function templates like that?
