Member 13246365 Ответов: 2

Ошибка умножения в матрицах, если я делаю это в цикле


Это моя функция

void clear_up(MatrixXd A, int dim)  //to set all initial values of the matrix to 0
{
    for(int i=0;i<dim;i++)
    {   for(int j=0;j<dim;j++)
        {   A(i,j)=0;   }   }
}

int sumrow(MatrixXd A,int row, int dim)   //adding up elements of a particular row
{
    int sum=0;
    for(int i=0;i<dim;i++)
    {
        sum=sum+A(row,i);
    }
    return sum;
}

MatrixXd generate_B(MatrixXd A, int dim)  //A is a symmetric matrix with diagonal elements 0 and other elements either 0 or 1
{
    cout<<"A \n"<<A<<"\n";
    MatrixXd B(dim,dim), inter1(dim,dim),   inter2(dim,dim),    D(dim,dim);
    clear_up(B,dim);    clear_up(inter1,dim);    clear_up(inter2,dim);  clear_up(D,dim);
    for(int i=0;i<dim;i++)
    {
        for(int j=0;j<dim;j++)
        {
            if(i==j)
            {
                D(i,j)= 1/sqrt(sumrow(A,i,dim));     //D is thus a diagonal matrix
            }
            else    {   D(i,j) = 0;     }
        }
    }
    cout<<"D \n"<<D<<"\n";
    for(int a=0;a<dim;a++)
    {
        for(int b=0;b<dim;b++)
        {
            for(int c=0;c<dim;c++)
            {
                inter1(a,b)+= A(a,c)*D(c,b);    //inter1 = A*D
            }
        }
    }
    cout<<"inter1 \n"<<inter1<<"\n";
    for(int x=0;x<dim;x++)
    {
        for(int y=0;y<dim;y++)
        {
            for(int z=0;z<dim;z++)
            {
                inter2(x,y)+= D(x,z)*inter1(z,y);   //inter2 = D*A*D
            }
        }
    }
    cout<<"inter2 \n"<<inter2<<"\n";
    for(int X=0; X<dim; X++)
    {   for(int Y=0; Y<dim; Y++)
        {   if(X==Y)    {   B(X,Y) = 1 - inter2(X,Y);   }
            else    {   B(X,Y) = 0 - inter2(X,Y);   }
        }       //B = I - D*A*D (I = identity matrix)
    }
    cout<<"B \n"<<B<<"\n";
    clear_up(inter1,dim);   clear_up(inter2,dim);   clear_up(D,dim);
    return B;
}


A-симметричная матрица с диагональными элементами 0 и недиагональными элементами 0 или 1. математически B должна быть симметричной матрицей с диагональными элементами 1, что и происходит за 1 итерацию. Однако, когда я запускаю его в цикле, некоторые матрицы симметричны, а некоторые нет. В чем может быть причина?

Что я уже пробовал:

Попробовал разбить его на разные функции. Также попробовал очистить ненужные значения.

ZurdoDev

Отладьте свой код и выясните, что не так.

2 Ответов

Рейтинг:
2

Patrice T

Цитата:
Однако, когда я запускаю его в цикле, некоторые матрицы симметричны, а некоторые нет. В чем может быть причина?

Серьезно ? вы даже не осмелились привести пример проблемы.
Минимум - это пример с последовательностью вызова для воспроизведения проблемы.

Существует инструмент, который позволяет вам видеть, что делает ваш код, его имя-отладчик. Освоение отладчика не является обязательным, оно обязательно для любого программиста, без исключения.
Это также отличный инструмент обучения, потому что он показывает вам реальность, и вы можете увидеть, какие ожидания соответствуют реальности.
Когда вы не понимаете, что делает ваш код или почему он делает то, что делает, ответ таков: отладчик.
Используйте отладчик, чтобы увидеть, что делает ваш код. Просто установите точку останова и посмотрите, как работает ваш код, отладчик позволяет вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения, это невероятный инструмент обучения.

Отладчик-Википедия, свободная энциклопедия[^]
Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010-YouTube[^]
Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
В отладчике нет никакой магии, он не находит ошибок, он просто помогает вам. Когда код не делает того, что ожидается, вы близки к ошибке.


Рейтинг:
1

OriginalGriff

Цитата:
Компиляция не означает, что ваш код верен! :смеяться:
Подумайте о процессе разработки как о написании письма: успешная компиляция означает, что вы написали письмо на правильном языке - например, на английском, а не на немецком, - а не то, что письмо содержало сообщение, которое вы хотели отправить.

Итак, теперь вы входите во вторую стадию разработки (на самом деле это четвертая или пятая, но к более ранним стадиям вы придете позже): тестирование и отладка.

Начните с рассмотрения того, что он делает и чем это отличается от того, что вы хотели. Это важно, потому что это дает вам информацию о том, почему он это делает. Например, если программа предназначена для того, чтобы позволить пользователю ввести число, а он удваивает его и печатает ответ, то если ввод / вывод был таким:
Input   Expected output    Actual output
  1            2                 1
  2            4                 4
  3            6                 9
  4            8                16
Тогда совершенно очевидно, что проблема заключается в бите, который удваивает его-он не прибавляет себя к себе или умножает его на 2, он умножает его на себя и возвращает квадрат входного сигнала.
Таким образом, вы можете посмотреть на код, и очевидно, что он где-то здесь:
private int Double(int value)
   {
   return value * value;
   }

Как только у вас появится идея, что может пойти не так, начните использовать отладчик, чтобы выяснить, почему. Поставить точку останова на строке:
cout<<"A \n"<<A<<"\n";

и запустите свое приложение. Подумайте о том, что должна делать каждая строка кода перед ее выполнением, и сравните это с тем, что она на самом деле делала, когда вы использовали кнопку "шаг вперед" для выполнения каждой строки по очереди. Он сделал то, что вы ожидали? Если да, то переходите к следующей строке.
Если нет, то почему? Чем это отличается?

Это навык, и его стоит развивать, поскольку он помогает вам как в реальном мире, так и в развитии. И, как и все навыки, он совершенствуется только при использовании!

Да, я, наверное, мог бы сказать вам, в чем "проблема" - но сделать это самому несложно, и при этом вы узнаете что-то действительно стоящее!