PyORBIT-Collaboration / py-orbit

Core of Py-ORBIT code
MIT License
25 stars 38 forks source link

Fixed a rounding issue that is causing the inverse to fail to be created under certain circumstances #52

Closed khilde closed 3 years ago

khilde commented 3 years ago

The formula for creating the x axis of the functions inverse is such that for the very last point rounding errors can cause the last value to not be set to the max Y value of the function being inverted. This can cause a check later on to see if the inverses max X value is greater than the original functions Max Y value to fail. This is resolved by simply setting the final x value of the functions inverse to the orginal functions Max Y value. This is completely consistent with formula for calculating the x value of the inverse but avoids potential rounding/precious errors.

Formula: double xx =getMinY() +i*(getMaxY()-getMinY())/(size-1) when i =size -1 the formula should give: xx = getMaxY() but due to precision loss/rounding this isn't always the case which causes the check: if(f_inv->getMaxX() > getMaxY()) to evaluate to true and the function inverse to fail to be constructed

khilde commented 3 years ago

Looking at my fix it might be better to change the for loop to just go to size-2 instead of size-1. Then add the last point xx=getMaxY() after the for loop. This would avoid having to check an if statement numerous times.

shishlo commented 3 years ago

Kevin, I agree, but doing if inside the cycle is unnecessary. We only need the precise last number, right? for(int i = 0; i < size-1; i++){ double xx = getMinY() + i*(getMaxY() - getMinY())/(size - 1);
f_inv->add(xx,0.); } f_inv->add(getMaxY(),0.);

khilde commented 3 years ago

Andrei, I agree with your comment that is what I was trying to say in my follow up comment. I have made this change. I did not know this would update in the pull request.