Последовательный и параллельный варианты программы. Теоретическое и практическое ускорение параллельной программы, страница 5

                          if(IMVL_list[CurElem] == k)

                               return IMVL_ELEMENT_CREATED;

                          /* Иначе переходим к следующему элменту */

                          else CurElem = NextElem;

                   }

                }

        }

        return IMVL_EMPTY_ERROR;

}

/***** Создание портрета матрицы *****/

integer IMVL_CreatePortrait()

{

        /* Локальные данные */

        integer CurElem, i;

        /* Номер текущего элемента */

        integer NumElem = 0;

        /* Установим начало размещения портрета */

        IMVL_start_ptr = (byte *)(IMVL_memory+IMVL_end_list*sizeint);

        /* Создадим место под массив указателей на начало строк

           и индексов элементов*/

        IMVL_row_ptr = (integer *)IMVL_start_ptr;

        IMVL_col_ind = (integer *)(IMVL_start_ptr+(IMVL_dim+1)*sizeint);

        /* Первая строка идёт с начала */

        IMVL_row_ptr[0] = NumElem;

        /* Формирование из списка портрета */

        for(i=0 ; i<IMVL_dim ; i++)

        {

             /* Указатель на список строки */

             CurElem = IMVL_list[2*i+1];

             /* Пока не конец списка */

             while(CurElem!=-1)

             {

                 /* Вносим элементы строки */

                 IMVL_col_ind[NumElem] = IMVL_list[CurElem];

                 /* Увеличиваем количество элементов */

                 NumElem++;

                 /* Переходим на следующий элемент */

                 CurElem = IMVL_list[CurElem+1];

             }

             /* Записываем указатель на следующую строку */

             IMVL_row_ptr[i+1] = NumElem;

        }

        /* Переписываем в начало памяти */

        memcpy(IMVL_list,IMVL_row_ptr,(IMVL_dim+NumElem+1)*sizeint);

        /* Настраиваем указатели */

        IMVL_row_ptr = IMVL_list;

        IMVL_col_ind = IMVL_list + IMVL_dim +1;

        /* Определяем начало массива элементов матрицы и обнуляем его */

        IMVL_val = (real *)(IMVL_row_ptr + IMVL_dim + NumElem + 1);

        memset(IMVL_val,0,NumElem*sizereal);

        /* Определяем начало свободной области памяти и

           записываем туда обнулённую диагональ */

        IMVL_start_ptr = (byte *)(IMVL_val + NumElem);

        IMVL_di = (real *)(IMVL_start_ptr);

        memset(IMVL_di,0,IMVL_dim*sizereal);

        IMVL_start_ptr = (byte *)(IMVL_di + IMVL_dim);

        /* Создаём нулевой вектор правой части */

        IMVL_right = (real *)(IMVL_start_ptr);

        IMVL_start_ptr += IMVL_dim * sizereal;

        memset(IMVL_right,0,IMVL_dim * sizereal);

        /* Запомним откуда начинаются рабочие вектора */

        IMVL_next_start = IMVL_start_ptr;

        return IMVL_OK;

}

/***** Добавление элемента в матрицу *****/

integer IMVL_AddElement( integer i,     // строка

                         integer k,     // столбец

                         real value     // значение

                       )

{

        /* Локальные данные */

        integer ind, end;

        /* Проверяем на принадлежность диагонали */

        if(i==k) IMVL_di[i] += value;

        /* Цикл по строке */

        end = IMVL_row_ptr[i+1];

        for(ind=IMVL_row_ptr[i] ; ind<end ; ind++)

        {

            /* Если элемент найден */

            if(IMVL_col_ind[ind] == k)

            {

               /* Добаваляем значение */

               IMVL_val[ind] += value;

               return IMVL_OK;

            }

        }

        return IMVL_ELEMENT_NOT_FOUND;

}

/***** Добавление элемента в вектор правой части *****/

void IMVL_AddElementVector( integer i, real value)

{

     IMVL_right[i] += value;

}

/***** Предобуславливание матрицы *****/

integer IMVL_PreConditioner()

{

        /* Локальные переменные */

        integer i;