Skip to content

Conversation

@meiyasan
Copy link

This Pull request:

Hi @hageboeck ; This is a followup on my previous PR #20524 aiming to improve polynomial implementation. I just implemented your suggestions and deprecating internal fRoot property from polynomial header and defined it in each of the Find*Root methods .

Changes or fixes:

Removed fProp, added const property to public Find*Root methods.
Feel free to as necessary.

Checklist:

  • tested changes locally
  • updated the docs (if necessary)

Tests:

I ran the ROOT battery of tests with couple of issues.

cmake -DCMAKE_BUILD_TYPE=Debug -Dtesting=ON -Droottest=ON -Dmathmore=ON ../polynomial-patch
make -j8
ctest -j8

Regarding the Polynomial class modifications, my use case output remains unchanged. (I use polynomials to compute digital filtering, biquad, etc..) I also paid attention in particular to those related to polynomials: gtest-hist-hist-testTProfile2Poly, etc..

@meiyasan meiyasan requested a review from lmoneta as a code owner November 26, 2025 15:14
@meiyasan
Copy link
Author

sorry @hageboeck, I failed to put you as reviewer and cannot adjust.

@hageboeck hageboeck self-assigned this Nov 26, 2025
Copy link
Member

@hageboeck hageboeck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, thanks for the PR!

Please see a few comments inline. Could you also update the commit message along the lines of replacing "property" by "member" or similar?

More or less, one could use:

Allow for using several methods of Polynomial.h in const context.

- Remove the fRoots member. It doesn't serve any purpose, because it is cleared before every root computation.
- Return polynomial roots by value
- Mark affected methods const

n--;
}

std::vector< std::complex < double > > fRoots;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the intention, but maybe we should not use the f for "field" in this context, since it's not any more a field of the class.

@hageboeck
Copy link
Member

@meiyasan one more thing:
After committing (or staging in git), you can already run git clang-format, so your changes are auto-formatted. Otherwise, the formatting check in the CI will fail and you will have to do it anyway. 😄

- Remove unused `fRoots` data member (it was cleared before each root
  computation and provided no persistent state).
- Return polynomial roots by value instead of via internal storage.
- Mark the affected query/utility methods as `const` to make the class
  usable in const contexts.
- Apply clang-format to the modified sections.
@meiyasan meiyasan force-pushed the polynomial-with-const branch from 475b4c2 to ea56fb6 Compare November 26, 2025 16:08
@meiyasan meiyasan force-pushed the polynomial-with-const branch from edb49cb to 5dfb494 Compare November 26, 2025 16:29
@meiyasan
Copy link
Author

thanks! I just ran the formatter against the previous commit; removed the extra const you recommended & also renamed fRoots into roots (additionally, in GetRealRoots, I renamed roots into real_roots to avoid conflicts).

git clang-format b9d0ae5b4ee84d6d09fd9045c302b829c44edde8 -- math/mathmore/inc/Math/Polynomial.h     math/mathmore/src/Polynomial.cxx

@hageboeck
Copy link
Member

hageboeck commented Nov 26, 2025

thanks! I just ran the formatter against the previous commit; removed the extra const you recommended & also renamed fRoots into roots (additionally, in GetRealRoots, I renamed roots into real_roots to avoid conflicts).

Hello, sounds good! There must have been a small error in git, though:

  • I don't see fRoots being renamed.
  • We don't allow merge commits in PRs to ROOT. You will have to remove the two commits that merge master in your branch. That should be OK, because nobody will work on the same files. Once the merge commits are removed, you can apply the edits referring to fRoots, and then possibly git clang-format HEAD~ or git clang-format <root-project>/master, where you insert the name of the remote that points to root-project.

Copy link
Member

@vepadulano vepadulano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! A few comments with suggestions for minor improvements.

Comment on lines 257 to 258
fRoots.clear();
fRoots.reserve(n);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fRoots.clear();
fRoots.reserve(n);

These are not needed now

Comment on lines +238 to +244
std::vector<std::complex<double>> fRoots = FindRoots();
std::vector<double> roots;
roots.reserve(fOrder);
for (unsigned int i = 0; i < fOrder; ++i) {
if (fRoots[i].imag() == 0)
roots.push_back(fRoots[i].real());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick, consider the following perhaps a bit more idiomatic code

auto roots = FindRoots();
std::vector<double> realRoots;
realRoots.reserve(roots.size());
for (const auto &r: roots)
   if (r.imag() == 0)
      realRoots.push_back(r.real());

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I look at this twice, I see the for loop is stopping after fOrder iterations. Although it's not clear from the code whether the vector returned by FindRoots will have a size greater (or even smaller which would be UB!) than fOrder

Copy link
Author

@meiyasan meiyasan Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well.. I agree the historical implementation sounds risky; what do you think about comparing double and strict 0 integers, shouldn't we implement an epsilon limit ?
additionally, considering we are removing std::vector::reverse() in other cases, we could also drop realRoots.reserve(roots.size()); here.

here would be my preference for simplicity purpose.

auto roots = FindRoots();
std::vector<double> realRoots;
for (const auto &r: roots)
   if (std::abs(r.imag()) < std::numeric_limits<double>::epsilon())
      realRoots.push_back(r.real());

@meiyasan meiyasan closed this Nov 27, 2025
@meiyasan meiyasan deleted the polynomial-with-const branch November 27, 2025 01:49
@meiyasan meiyasan mentioned this pull request Nov 27, 2025
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants