Посчитать определитель 'вручную'

From
Stanislav Shwartsman (2:400/520)
To
Vladislav Terehov
Date
2002-10-04T08:04:35Z
Area
RU.ALGORITHMS
Hello Vladislav!

04 Oct 02 00:23, you wrote to me:

 VT>>> Существует ли что-нибудь более изящное, чем банальный пеpебоp
 VT>>> всех возможных пpеобpазований?
 SS>>  Это называется метод Гаусса - приведение матрицы к треугольному
 SS>> виду.

 VT> *Алгоpитм (или исходняк на чём угодно) в студию плз.*

 VT> Да,  важное условие, пpиведение к тpеугольному виду должно пpоисходить
 VT> не абы как, а так, чтобы это было похоже на pешение вpучную (нужны все
 VT> пpомежуточные pезультаты). Т.е в алгоpитме должен пpисутсвовать некий
 VT> оценщик кpасивости очеpедного пpеобpазования. Да?

   А книжку почитать ?
   В библиотеке давно последний раз был ?

   Ладно, максимальную оптимизированность и красоту не гарантирую.
   Главное, что работает ! ;)

/************************** service public members ***************************/

bool TMatrix :: triangle()
{
   unsigned int i, j, row, d=min(rows, cols);

   for (row=0; row < d; row++)
   {
    if (rindex[row][row] == 0)  /* change pivot if need */
    {
        for (i=row; i<rows; i++)
            if (rindex[i][row] != 0) break;

        if (i == row) return false;
        swaprows(i, row);
    }

    /* triangulation */
    for(i = row+1; i<rows; i++) {
            double scalar = rindex[i][row] / rindex[row][row];
            for(j=0; j<cols; j++) rindex[i][j] -= rindex[row][j] * scalar;
        }
   }

   return true;
}

bool TMatrix :: triangle_with_scp_pivoting()
{
   for (unsigned int row=0, d=min(rows, cols); row<d; row++)
   {
        /* scaling & pivoting */
    if(do_row_scaling(row) == false ||
        do_maximum_column_pivoting(row) == false) return false;

    /* triangulation */
    for(unsigned int i = row+1; i<rows; i++)
    {
        double scalar = rindex[i][row] / rindex[row][row];
        for(unsigned int j=0; j<cols; j++)
            rindex[i][j] -= rindex[row][j]*scalar;
        }
   }

   return true;
}

bool TMatrix :: do_maximum_column_pivoting(unsigned int row)
{
   unsigned int j = row;
   double big = 0;

   /* find maximum column pivot */
   for (unsigned int i = row; i<rows; i++) {
    if (fabs(rindex[i][row]) > big) {
        big = fabs(rindex[i][row]);
        j = i;
    }
   }

   if (big == 0) return false;
   swaprows(j, row);
   return true;
}

bool TMatrix :: do_row_scaling(unsigned int row)
{
   double big = 0;
   unsigned int i, d = min(rows, cols);

   /* find row biggest element */
   for (i=0; i<d; i++) {
    if (fabs(rindex[row][i]) > big) big = fabs(rindex[row][i]);
   }

   if (big == 0) return false;

   /* and scale ... */
   for (i=0; i<cols; i++) rindex[row][i] /= big;
   return true;
}

    E-mail: gate@fidonet.org.il
    Voice Phones: 972-4-8330554 (home), 972-5-4481073 (cell)

Bye !
Stanislav     (AKA Night's Man)                        [Team Technion]
---
 * Origin: Gate From Another World ... From Haifa, Israel (2:400/520)