| 1882 | } |
| 1883 | |
| 1884 | bool Engine::attemptToMergeVariables( unsigned x1, unsigned x2 ) |
| 1885 | { |
| 1886 | /* |
| 1887 | First, we need to ensure that the variables are both non-basic. |
| 1888 | */ |
| 1889 | |
| 1890 | unsigned n = _tableau->getN(); |
| 1891 | unsigned m = _tableau->getM(); |
| 1892 | |
| 1893 | if ( _tableau->isBasic( x1 ) ) |
| 1894 | { |
| 1895 | TableauRow x1Row( n - m ); |
| 1896 | _tableau->getTableauRow( _tableau->variableToIndex( x1 ), &x1Row ); |
| 1897 | |
| 1898 | bool found = false; |
| 1899 | double bestCoefficient = 0.0; |
| 1900 | unsigned nonBasic = 0; |
| 1901 | for ( unsigned i = 0; i < n - m; ++i ) |
| 1902 | { |
| 1903 | if ( x1Row._row[i]._var != x2 ) |
| 1904 | { |
| 1905 | double contender = FloatUtils::abs( x1Row._row[i]._coefficient ); |
| 1906 | if ( FloatUtils::gt( contender, bestCoefficient ) ) |
| 1907 | { |
| 1908 | found = true; |
| 1909 | nonBasic = x1Row._row[i]._var; |
| 1910 | bestCoefficient = contender; |
| 1911 | } |
| 1912 | } |
| 1913 | } |
| 1914 | |
| 1915 | if ( !found ) |
| 1916 | return false; |
| 1917 | |
| 1918 | _tableau->setEnteringVariableIndex( _tableau->variableToIndex( nonBasic ) ); |
| 1919 | _tableau->setLeavingVariableIndex( _tableau->variableToIndex( x1 ) ); |
| 1920 | |
| 1921 | // Make sure the change column and pivot row are up-to-date - strategies |
| 1922 | // such as projected steepest edge need these for their internal updates. |
| 1923 | _tableau->computeChangeColumn(); |
| 1924 | _tableau->computePivotRow(); |
| 1925 | |
| 1926 | _activeEntryStrategy->prePivotHook( _tableau, false ); |
| 1927 | _tableau->performDegeneratePivot(); |
| 1928 | _activeEntryStrategy->postPivotHook( _tableau, false ); |
| 1929 | } |
| 1930 | |
| 1931 | if ( _tableau->isBasic( x2 ) ) |
| 1932 | { |
| 1933 | TableauRow x2Row( n - m ); |
| 1934 | _tableau->getTableauRow( _tableau->variableToIndex( x2 ), &x2Row ); |
| 1935 | |
| 1936 | bool found = false; |
| 1937 | double bestCoefficient = 0.0; |
| 1938 | unsigned nonBasic = 0; |
| 1939 | for ( unsigned i = 0; i < n - m; ++i ) |
| 1940 | { |
| 1941 | if ( x2Row._row[i]._var != x1 ) |
nothing calls this directly
no test coverage detected