0 / 0 / 1
Регистрация: 03.05.2014
Сообщений: 10
1

Решение СЛАУ методом вращения

06.05.2015, 16:57. Показов 7422. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток, товарищи.
Имеется задание:
Кликните здесь для просмотра всего текста
дано интегральное уравнение:

U(x) + I ( K(x,s)U(s)ds= f(x) ( I - определённый интеграл от произведения функций K и U, взятый по переменной s в пределах от a до b).

Интеграл заменяется формулой приближённого интегрирования ( в моём случае формула правых прямоугольников). Получается такая сумма:

Ui+ (сумма по j от 1 до n)(K(xi,xj*Uj)=f(xi),
где: i=1...n, {xi} - сетка на отрезке [a,b];

Получается СЛАУ, которую нужно решить определённым способом (в моём случае - методом вращения).

Суть метода:
Кликните здесь для просмотра всего текста
Решение СЛАУ методом вращения
Решение СЛАУ методом вращения
Решение СЛАУ методом вращения
Решение СЛАУ методом вращения


Что я сделал:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#define _USE_MATH_DEFINES
#include <iostream>
#include <stdlib.h>
#include <conio.h>
#include <locale.h>
#include <math.h>
double a;
double b;
const int n=5; 
double *X=new double[n+1];
double eps=0.001;
 
using namespace std;
double functionF(double x){return sin(x);}
double functionU(double x){return sin(x);}
double functionK(double x, double s){return 1;}
 
 
 
int main(){setlocale(LC_ALL, ".ACP");
a=0;
b=2*(M_PI);
double h=(b-a)/(n-1);
double *f=new double[n];
double **K=new double*[n];
double **hi=new double*[n];
 
for(int i=0;i<n;i++)
    K[i]=new double[n]; //а это сама матрица коэффициентов
for(int i=0;i<n;i++)
    hi[i]=new double[n]; //матрица вращения: на главной диагонали единицы, остальные элементы нули, на
                         //нужные места ставим cos, sin, -sin, cos
 
 
for(int i=0;i<n;i++){
    X[i]=a+h*i;}
 
for(int i=0;i<n;i++)
    f[i]=functionF(X[i]); //правая часть
 
for(int i=0;i<n;i++)
    for(int j=0;j<n;j++){if(i==j)
        K[i][j]=1+h*functionK(X[i],X[j]); //U(x_1) с единичным коэф-том входит только в первое уравнение. 
    else                                  //во всех остальных уравнениях у него нулевой коэф-т. 
        K[i][j]=h*functionK(X[i],X[j]);}  //а у элементов на диагонали коэф-т = 1+K(x_i, x_j); что-то я не понимаю, верно ли у меня тут записано,
//что первый столбец, кроме первого элемента, должен быть нулевым?
        
cout<<"\n";
 
cout<<"\n";
for(int i=0;i<n;i++)
    printf("f[%d]=%.3f ", i, f[i]);
int p = 1;
 
while (p<5) { //пробное условие для теста
 
 
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) {
            if (i == j)
                hi[i][j] = 1;
            else hi[i][j] = 0;
        }
 
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
     double fi = atan(K[i][j]/(K[i][j]*K[i][j]+K[j][j]*K[j][j]));
     double cosfi = cos(fi), sinfi = sin(fi);
     hi[i][j]=cosfi;
     hi[j][j]=cosfi;
     hi[i][j]=-sinfi;
     hi[j][i]=sinfi;
 
     f[i]=f[i]*cosfi+f[j]*sinfi;
 
     K[i][i]=cosfi*K[i][i]+sinfi*K[i][j];
     K[j][j]=-sinfi*K[j][i]+cosfi*K[j][j];
     K[i][j]=cosfi*K[j][i]+sinfi*K[j][j];}}
     
 
 printf("\nСледующее приближение:\n");
  for (int i = 0; i < n; i++){
      for (int j = 0; j < n; j++){printf("K[%d][%d]=%.2f  ", i,j, K[i][j]);}cout<<"\n";} ;p++;}
  
cout<<"\n";
system("pause"); 
return 0;
}


В чём проблема:
Кликните здесь для просмотра всего текста
Даже если задать программе сделать 500 итераций, то поддиагональные элементы не зануляются, хотя это должно иметь место. Возможно у меня где-то ошибка в создании матрицы вращения и перемножения соответствующих элементов матрицы коэф-тов и правой части. Третьи сутки в неё пялюсь, взгляд затуманенный.

Чего хочу:
Кликните здесь для просмотра всего текста
Или конструктивных предложений по доработке,или посильной от Вас помощи.


P.S. Перерыл кучу ссылок в интернете, находятся либо поиск собственных чисел методом вращения, либо мне хотят подсунуть метод Якоби, выдавая его за вращение, хотя это совершенно разные вещи.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.05.2015, 16:57
Ответы с готовыми решениями:

Решение СЛАУ методом Якоби
Решить СЛАУ методом Якоби. Вывести значения решения, график зависимости нормы невязки от номера...

Решение СЛАУ методом Гаусса
У меня программа для решения слау методом Гаусса с выбором главного элемента по столбцам. Что-то...

Решение СЛАУ методом прогонки
Добрый день,нужно решить СЛАУ методом прогонки,вот СЛАУ и ее решение. коэфф перед х1считается как...

Решение СЛАУ методом Жордана
Решить СЛАУ методом Жордана, Вычислить интегральнок выражение методом Симпсона

5
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
06.05.2015, 18:19 2
Синус косинус для каждого элемента должны вычисляться или один раз на проход? А то у тебя похоже каждый элемент на свой угол вертится.
И убери ты оттуа тригонометрию она там не нужна.
C++
1
2
3
4
     double s1 = K[i][j];
     double c1 =K[i][j]*K[i][j]+K[j][j]*K[j][j];
     double Delta:=sqrt(s1*s1+c1*c1);
     double cosfi = c1/Delta, sinfi = s1/Delta;
И посчитает быстрее, и знак не потеряет. Как минимум замени atan на atan2, а то возможна потеря знака.
И похоже в знаменателе корень потерян.
0
0 / 0 / 1
Регистрация: 03.05.2014
Сообщений: 10
06.05.2015, 18:36  [ТС] 3
Fulcrum_013, для каждых элементов свой угол вычисляется, да.
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
07.05.2015, 03:16 4
atan значит знак теряет. у него выходной диапазон [-pi/2,pi/2], т.е. возврашает угол в одной полуплоскости. пользуй или нормирование или atan2 у него диапазон [-pi,pi]
0
0 / 0 / 1
Регистрация: 03.05.2014
Сообщений: 10
07.05.2015, 13:23  [ТС] 5
upd.
может кто-то попробует помочь с правильным умножением исходной матрицы коэф-тов и вектора правой части на соответствующие значения sin и cos?
0
Работаю
6 / 5 / 0
Регистрация: 30.05.2014
Сообщений: 226
11.09.2019, 13:59 6
мой код, писал под винду в Visual C++ 2008, переменная n количество уравнений и сколько значений X в уравнении:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
                                double l, m, r;
                //создаем матрицу значений A
                double **a=new double*[n+1];
                for(int i=0;i<=n;i++)a[i]=new double[n+1];
                //создаем массив корней X
                double *x=new double[n];
                //заполняем матрицу A
                for(int i=1;i<=n;i++)
                    for(int j=1;j<=n;j++)a[i][j]=System::Convert::ToDouble(dataGridView1->Rows[i-1]->Cells[j-1]->Value);
                //заполняем матрицу A значениями B в нулевой столбец
                for(int i=1;i<=n;i++)a[i][0]=System::Convert::ToDouble(dataGridView1->Rows[i-1]->Cells[n]->Value);
                //решение
                for(int i=1;i<=n-1;i++){
                    for(int k=i+1;k<=n;k++){
                        if(a[i][i]==0 || a[k][i]==0){
                            m=1;l=0;
                        }else{
                            m=sqrt(a[i][i]*a[i][i]+a[k][i]*a[k][i]);
                            l=-a[k][i]/m;m=a[i][i]/m;
                        }
                        for(int j=1;j<=n;j++){
                            r=m*a[i][j]-l*a[k][j];
                            a[k][j]=l*a[i][j]+m*a[k][j];
                            a[i][j]=r;
                        }
                        r=m*a[i][0]-l*a[k][0];
                        a[k][0]=l*a[i][0]+m*a[k][0];
                        a[i][0]=r;
                    }
                }
                for(int i=n;i>=1;i--){
                    m=0;
                    for(int k=0;k<=n-i-1;k++)m=m+a[0][n-k]*a[i][n-k];
                    a[0][i]=(a[i][0]-m)/a[i][i];
                }
                //вводим значение результата, корней X
                for(int j=1;j<=n;j++)x[j-1]=a[0][j];
                dataGridView2->RowCount=n;
                dataGridView2->ColumnCount=2;
                dataGridView2->Columns[0]->Width=30;
                dataGridView2->Columns[1]->Width=100;
                //вывод результата значений корней X
                for(int i=0;i<n;i++){
                    dataGridView2->Rows[i]->Cells[0]->Value="X"+(i+1).ToString();
                    dataGridView2->Rows[i]->Cells[1]->Value=x[i];
                }
0
11.09.2019, 13:59
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.09.2019, 13:59
Помогаю со студенческими работами здесь

Решение СЛАУ методом отражений
Добрый вечер :) Было две темы &quot;Решение СЛАУ методом отражений&quot;, но нет реализации) У меня есть...

Решение СЛАУ методом Якоби
Пытаюсь реализовать метод решения системы линейных уравнений методом Якоби. #include &quot;stdafx.h&quot;...

Решение слау методом релаксации
Доброго времени суток. В качестве исходных данных имеются слау большой размерности (koeff__100.7z)...

Решение СЛАУ методом Гаусса
помогите разобраться!!ВЫдает 85 ошибок!!!! #include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru