Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: improve the lexico-minimum finder in LemkeAlgorithm. #4295

Conversation

ShoYamanishi
Copy link
Contributor

The following issues in btLemkeAlgorithm::findLexicographicMinimum() are addressed in this commit.

Logic Issues

  • The z_0 column located at A(,2dim), is used for lexico-minimum test, which should not be used.
  • If the check on the 1st column 'q' produces multiple minimums due to degeneracy,
    and if it contains z_0, the tie must be broken in favor of z_0 and return,
    which is not performed in the original.

Efficiency Issues

  • The 1st part to construct 'Rows' is unnecessary.
  • The 2nd part has three nested loops with brute-force search, which is inefficient.

Description of the Fix
The improved version performs the lexico-minimum test column-by-column
from the left-most column of (-B^{-1}q:B^{-1}).
If the test finds a single row, it returns it.
If the test finds multiple rows and if they contain z_0, it returns z_0.
Otherwise, it moves on to the next column.
Please see 2.2.2 "Pivot Step" of
K. Murty, "Linear Complementarity, Linear and Nonlinear Programming" Heldermann Verlag, Berlin, 1998
for the algorithm details.

Test Results
Some performance tests are done and non-negligible improvement was observed.
Please see https://github.com/ShoYamanishi/AppleNumericalComputing/tree/main/14_lcp for the test details.

The following issues in btLemkeAlgorithm::findLexicographicMinimum() are addressed in this commit.

- The z_0 column located at A(*,2*dim), is used for lexico minimum test, which should not be used.
- If the check on the 1st column 'q' produces multiple minimums due to generacy,
  and if it contains z_0, the tie must be broken in favor of z_0 and return,
  which is not performed in the original.

- The 1st part to construct 'Rows' is unnecessary.
- The 2nd part has three nested loops with brute-force search, which is inefficient.

The improved version performs the lexico minimum test column-by-column
from the left-most column of (-B^{-1}q:B^{-1}).
If the test finds a single row, it returns it.
If the test finds multiple rows and if they contain z_0, it returns z_0.
Otherwise, it moves on to the next column.
Please see  2.2.2 "Pivot Step" of
    K. Murty, "Linear Complementarity, Linear and Nonlinear Programming" Heldermann Verlag, Berlin, 1998
for the algorithm details.

Some performance tests are done and non-negligible improvment was observed.
Please see https://github.com/ShoYamanishi/AppleNumericalComputing/tree/main/14_lcp for the test details.
@erwincoumans
Copy link
Member

Thanks a lot for sharing the improvements and the test cases. Let's merge it. Also, your Lemke implementation seems to perform well! By default, we use an iterative constraint solver in Bullet, and for joints we typically use reduced coordinates (Featherstone articulated body algorithm), so the Lemke implementation hasn't received much attention.

@erwincoumans erwincoumans merged commit dad061f into bulletphysics:master Sep 2, 2022
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.

None yet

2 participants