Форум программистов, компьютерный форум, киберфорум
Java для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.62/29: Рейтинг темы: голосов - 29, средняя оценка - 4.62
0 / 0 / 0
Регистрация: 11.10.2012
Сообщений: 34
1

Метод Крылова (нахождение собственных значений матрицы)

07.06.2014, 07:31. Просмотров 5488. Ответов 3
Метки нет (Все метки)

Народ, вот ниже приведен исходник на С++ метода Крылова, который находит собственные значения матрицы размерностью 4х4. Беда в том, что надо перевести на Java, очень срочно! помогите


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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#include <iostream>
#include <math.h>
//Объявим прототипы процедур и функций
void dispArr (float **Arr, int i, int j, char t[7]);
float** arrMult (float **Arr, float **ArrO, int m, int n, int q);
float** treugArr (float **Arr, int n);
float* gSolve (float **Arr, int n);
float halfDiv(float *P, float eps);
float* urDiv (float *P, float a, int n);
float urTest4 (float a, float b, float *P);
 
float** arrMult (float **Arr, float **ArrO, int m, int n, int q) //Функция перемножения матриц
{
    float **MultArr;
    //Динамически создаем матрицу - результат произведения
    MultArr = new float*[m];
    for (int i=0; i<m; i++) 
    { 
        MultArr[i] = new float[q]; 
    };
    //Вычисляем произведение матриц
    for (int i=0; i<m; i++)
        for (int j=0; j<q; j++)
        {
            MultArr[i][j] = 0;
            for (int k=0; k<n; k++)
                MultArr[i][j] += Arr[i][k]*ArrO[k][j];
        }
    return MultArr;
}
 
float** treugArr (float **Arr, int n) //Приведение матрицы к треугольному виду
{
    //Приводим матрицу A к треугольному виду
    for (int i=0; i<n; i++)
    {
        //Обнуляем необходимые элементы
        for (int j=i+1; j<n; j++)
        {
            float koeff = Arr[j][i]/Arr[i][i]; //Коэффициент, на который будем домножать строку
            for (int k=0; k<n+1; k++)
                Arr[j][k]=Arr[j][k]-Arr[i][k]*koeff;
        }
    }
    return Arr;
}
 
float* gSolve (float **Arr, int n) //Нахождение переменных в матрице, приведенной к треугольному виду
{
    float *X;
    X = new float[n];
    //Расчет неизвестных:
    X[3] = Arr[3][4]/Arr[3][3];
    X[2] = (Arr[2][4] - Arr[2][3]*X[3])/Arr[2][2];
    X[1] = (Arr[1][4] - Arr[1][2]*X[2] - Arr[1][3]*X[3])/Arr[1][1];
    X[0] = (Arr[0][4] - Arr[0][1]*X[1] - Arr[0][2]*X[2] - Arr[0][3]*X[3])/Arr[0][0];
    
    return X;
}
 
float halfDiv(float *P, float eps) //Метод половинного деления
{
    float a=0, b=0, prec;
    
    do {
        a--; b++;
    } while (urTest4(a, b, P) > 0);
    std::cout << "Исходный отрезок для нахождения корней: ";
    std::cout << "[" << a << "," << b << "]\n";
    do
    {
        prec = b - a;
        float cent = (a+b)/2;
        if (urTest4(a, cent, P) < 0) b=cent;
        else a=cent;
    } while (prec>eps);
    
    return a;
}
 
float* urDiv (float *P, float a, int n) //Деление уравнения
{
    P[n]=0;
    for (int i=n-1; i>=0; i--)
    {
        if (i+1 == n)
            P[i]=-P[i]+a;
        else
            P[i]=-P[i]+P[i+1]*a;
    }
    for (int i=0; i<n; i++)
        if (i+1 == n)
            P[i] = -1;
        else
            P[i] = -P[i+1];
 
    return P; 
}
 
float urTest4 (float a, float b, float *P) //Проверка знаков на концах отрезка
{
    float r1 = P[4]*pow(a, 4) - P[3]*pow(a, 3) - P[2]*pow(a,2) - P[1]*a - P[0];
    float r2 = P[4]*pow(b, 4) - P[3]*pow(b, 3) - P[2]*pow(b,2) - P[1]*b - P[0];
    
    return r1*r2;
}
 
void dispArr (float **Arr, int si, int sj, char t[7]) //Процедура отображения матрицы
{
    std::cout << "------------------------------ \n";
    for (int i=0; i<si; i++)
    {
        for (int j=0; j<sj; j++)
            printf(t, Arr[i][j]);
        std::cout << "\n";
    }
    std::cout << "------------------------------ \n";
    
}
 
int main (int argc, const char * argv[])
{
 
    FILE *file;
    float kf, eps, a;
    float **A, **B, **C, **mC, **c0, *P, *lambda, **tmpArr;
    int ni, nj, i, j;
    //Открываем файл для чтения исходных данных
    file = fopen("/Volumes/Macintosh HD/Users/nick_ny/Study/Chisl_method/Lab4_Krylov/Lab4_Krylov/input.txt", "r");
    //Считываем из файла размерность массивов Ni x Nj
    fscanf(file, "%d", &ni); fscanf(file, "%d", &nj);
    //Создаем динамические массивы
    A = new float*[ni]; B = new float*[ni]; C = new float*[ni];
 
    for (int i=0; i<ni; i++) 
    { 
        A[i] = new float[nj]; 
        B[i] = new float[nj]; 
        C[i] = new float[nj];
    };
    
    //Считываем массив B:
    for (i=0; i<ni; i++)
        for (j=0; j<nj; j++)
            fscanf(file, "%f ", &B[i][j]);
    //Считываем массив C:
    for (i=0; i<ni; i++)
        for (j=0; j<nj; j++)
            fscanf(file, "%f ", &C[i][j]);
    //Считываем число k:
    fscanf(file, "%f", &kf);
    //Считываем желаемую точность
    fscanf(file, "%f", &eps);
    fclose(file);
    //Формируем массив A, с которым будем работать (A = B + kC):
    for (i=0; i<ni; i++)
        for (j=0; j<nj; j++)
        { 
            A[i][j] = B[i][j] + kf*C[i][j];
        }
    std::cout << "Исходная матрица A:\n";
    dispArr(A, ni, nj, "%5.2f ");
//Блок нахождения значений C(0), C(1), C(2), C(3), C(4)
    //Создадим массив который будет хранить эти значения
    mC = new float*[ni];
    for (int i=0; i<ni; i++) 
        mC[i] = new float[ni+1];
    //В этом массиве за C(0) примем (1, 1, 1, 1)
    for (int i=0; i<ni; i++) 
        mC[i][0] = 1;
    //Создадим массив c0, который будет хранить текущее значение C(1), C(2), C(3), C(4)
    c0 = new float*[ni];
    for (int i=0; i<ni; i++) 
        c0[i] = new float[1];
    //Перейдем к нахождению C(1), C(2), C(3), C(4)
    for (int i=0; i<ni; i++)
    {
        //Заполним массив c0 текущим значением - C(i)
        for (int j=0; j<ni; j++)
            c0[j][0]=mC[j][i];
        //Для нахождения C(i+1) умножим массив A на с0
        tmpArr = arrMult(A, c0, ni, nj, 1);
        //Занесем полученные данные в массив mC
        for (int j=0; j<ni; j++)
            mC[j][i+1]=tmpArr[j][0];
    }
    std::cout << "   C(0)    C(1)    C(2)    C(3)   C(4) \n";
    dispArr(mC, 4, 5, "%7.3f ");
//Запишем систему уравнений для нахождения P1, P2, P3, P4    
    treugArr(mC, 4);
    P = new float[ni+1];
    P = gSolve(mC, 5);
    P[4] = 1;
//Запишем получившееся уравнение с λ
    std::cout << "Характеристическое уравнение: \n";
    std::cout << P[4] << " λ^4 - (" << P[3] <<") λ^3 - (" << P[2] << ") λ^2 - (" << P[1] << ") λ - (" << P[0] <<") = 0 \n";
    lambda = new float[ni];
//Ищем значения λ методом половинного деления     
    for (int k=4; k>0; k--)
    {
        //Будем решать полученное уравнение методом половинного деления    
        a = halfDiv(P, eps);
        lambda[k-1] = a;
        std::cout << "λ[" << ni+1-k << "]: ";
        printf("%7.3f \n", a);
        //Разделим уравнение на полученный корень, чтобы получить кубическое
        P = urDiv(P, a, k);
        //Запишем результат деления
        if (k-1 > 0) { std::cout << "Уравнение " << k-1 << " степени: \n";
            std::cout << P[4] << " λ^4 - (" << P[3] <<") λ^3 - (" << P[2] << ") λ^2 - (" << P[1] << ") λ - (" << P[0] <<") = 0 \n"; }
    }
//Аккуратно выведем полученные значения λ
    std::cout << "------------------------------ \n";
    std::cout << "Полученные собственные значения: \n";
    for (int i=ni; i>0; i--)
    {
        std::cout << "λ[" << ni-i+1 << "]: " << lambda[i-1] << ";\n";
    }
    std::cout << "------------------------------ \n";
    return 0;
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.06.2014, 07:31
Ответы с готовыми решениями:

Нахождение собственных значений матрицы Хессенбергера
Есть программа, которая приводит квадратную матрицу, заполненную рандомными числами, к матрице...

Нахождение собственных значений и векторов матрицы методом Крылова
Уважаемые товарищи, помогите, пожалуйста. Нужно найти СВ и СЗ матрицы 5х5 методом Крылова, буду...

Метод итераций: нахождение собственных векторов и собственных значений матрицы
Доброго времени суток. метод итерации нахождение собственных векторов и собственных значений...

Необходимо найти множество собственных значений матрицы А методами :Крылова, Фадеева, Данилевского.
Задана матрица A (4х4): n*m 0 -m 0 n n*m n -m...

3
937 / 682 / 228
Регистрация: 28.04.2013
Сообщений: 1,921
07.06.2014, 09:45 2
Лучший ответ Сообщение было отмечено nesteroff как решение

Решение

nesteroff,

Java
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
import java.io.File;
/**
 * Created by Reisal78 cyberforum.ru on 07.06.2014.
 */
public class ChislMethodKrylov {
 
    static float[][] arrMult(float[][] Arr, float[][] ArrO, int m, int n, int q) //Функция перемножения матриц
    {
        float[][] MultArr;
        //Динамически создаем матрицу - результат произведения
        MultArr = new float[m][];
        for (int i = 0; i < m; i++) {
            MultArr[i] = new float[q];
        }
        ;
        //Вычисляем произведение матриц
        for (int i = 0; i < m; i++)
            for (int j = 0; j < q; j++) {
                MultArr[i][j] = 0;
                for (int k = 0; k < n; k++)
                    MultArr[i][j] += Arr[i][k] * ArrO[k][j];
            }
        return MultArr;
    }
 
    static float[][] treugArr(float[][] Arr, int n) //Приведение матрицы к треугольному виду
    {
        //Приводим матрицу A к треугольному виду
        for (int i = 0; i < n; i++) {
            //Обнуляем необходимые элементы
            for (int j = i + 1; j < n; j++) {
                float koeff = Arr[j][i] / Arr[i][i]; //Коэффициент, на который будем домножать строку
                for (int k = 0; k < n + 1; k++)
                    Arr[j][k] = Arr[j][k] - Arr[i][k] * koeff;
            }
        }
        return Arr;
    }
 
    static float[] gSolve(float[][] Arr, int n) //Нахождение переменных в матрице, приведенной к треугольному виду
    {
        float[] X;
        X = new float[n];
        //Расчет неизвестных:
        X[3] = Arr[3][4] / Arr[3][3];
        X[2] = (Arr[2][4] - Arr[2][3] * X[3]) / Arr[2][2];
        X[1] = (Arr[1][4] - Arr[1][2] * X[2] - Arr[1][3] * X[3]) / Arr[1][1];
        X[0] = (Arr[0][4] - Arr[0][1] * X[1] - Arr[0][2] * X[2] - Arr[0][3] * X[3]) / Arr[0][0];
 
        return X;
    }
 
    static float halfDiv(float[] P, float eps) //Метод половинного деления
    {
        float a = 0;
        float b = 0;
        float prec;
 
        do {
            a--;
            b++;
        } while (urTest4(a, b, P) > 0);
        System.out.println("Исходный отрезок для нахождения корней: ");
        System.out.println("[" + a + "," + b + "]\n");
        do {
            prec = b - a;
            float cent = (a + b) / 2;
            if (urTest4(a, cent, P) < 0) b = cent;
            else a = cent;
        } while (prec > eps);
 
        return a;
    }
 
    static float[] urDiv(float[] P, float a, int n) //Деление уравнения
    {
        P[n] = 0;
        for (int i = n - 1; i >= 0; i--) {
            if (i + 1 == n)
                P[i] = -P[i] + a;
            else
                P[i] = -P[i] + P[i + 1] * a;
        }
        for (int i = 0; i < n; i++)
            if (i + 1 == n)
                P[i] = -1;
            else
                P[i] = -P[i + 1];
 
        return P;
    }
 
    static float urTest4(float a, float b, float[] P) //Проверка знаков на концах отрезка
    {
        float r1 = (float) (P[4] * Math.pow(a, 4) - P[3] * Math.pow(a, 3) - P[2] * Math.pow(a, 2) - P[1] * a - P[0]);
        float r2 = (float) (P[4] * Math.pow(b, 4) - P[3] * Math.pow(b, 3) - P[2] * Math.pow(b, 2) - P[1] * b - P[0]);
 
        return r1 * r2;
    }
 
    static void dispArr(float[][] Arr, int si, int sj, String t) //Процедура отображения матрицы
    {
        System.out.println("------------------------------ \n");
        for (int i = 0; i < si; i++) {
            for (int j = 0; j < sj; j++) {
                System.out.printf(t, Arr[i][j]);
            }
            System.out.println("\n");
        }
        System.out.println("------------------------------ \n");
 
    }
 
    public static void main(String[] args) {
        File file;
        float kf, eps, a;
        float[][] A;
        float[][] B;
        float C[][];
        float[][] mC;
        float[][] c0;
        float[] P;
        float[] lambda;
        float[][] tmpArr;
        int ni, nj;
        //Открываем файл для чтения исходных данных
        file = new File("/Volumes/Macintosh HD/Users/nick_ny/Study/Chisl_method/Lab4_Krylov/Lab4_Krylov/input.txt");
        //Считываем из файла размерность массивов Ni x Nj
 
        fscanf(file, "%d", & ni);
        fscanf(file, "%d", & nj);
 
        //Создаем динамические массивы
        A = new float[ni][];
        B = new float[ni][];
        C = new float[ni][];
 
        for (int i = 0; i < ni; i++) {
            A[i] = new float[nj];
            B[i] = new float[nj];
            C[i] = new float[nj];
        }
        ;
 
        //Считываем массив B:
        for (int i = 0; i < ni; i++)
            for (int j = 0; j < nj; j++)
                fscanf(file, "%f ", & B[i][j]);
        //Считываем массив C:
        for (int i = 0; i < ni; i++)
            for (int j = 0; j < nj; j++)
                fscanf(file, "%f ", & C[i][j]);
        //Считываем число k:
        fscanf(file, "%f", & kf);
        //Считываем желаемую точность
        fscanf(file, "%f", & eps);
        fclose(file);
        //Формируем массив A, с которым будем работать (A = B + kC):
        for (int i = 0; i < ni; i++)
            for (int j = 0; j < nj; j++) {
                A[i][j] = B[i][j] + kf * C[i][j];
            }
        System.out.println("Исходная матрица A:\n");
        dispArr(A, ni, nj, "%5.2f ");
        //Блок нахождения значений C(0), C(1), C(2), C(3), C(4)
        //Создадим массив который будет хранить эти значения
        mC = new float[ni][];
        for (int i = 0; i < ni; i++)
            mC[i] = new float[ni + 1];
        //В этом массиве за C(0) примем (1, 1, 1, 1)
        for (int i = 0; i < ni; i++)
            mC[i][0] = 1;
        //Создадим массив c0, который будет хранить текущее значение C(1), C(2), C(3), C(4)
        c0 = new float[ni][];
        for (int i = 0; i < ni; i++)
            c0[i] = new float[1];
        //Перейдем к нахождению C(1), C(2), C(3), C(4)
        for (int i = 0; i < ni; i++) {
            //Заполним массив c0 текущим значением - C(i)
            for (int j = 0; j < ni; j++)
                c0[j][0] = mC[j][i];
            //Для нахождения C(i+1) умножим массив A на с0
            tmpArr = arrMult(A, c0, ni, nj, 1);
            //Занесем полученные данные в массив mC
            for (int j = 0; j < ni; j++)
                mC[j][i + 1] = tmpArr[j][0];
        }
        System.out.println("   C(0)    C(1)    C(2)    C(3)   C(4) \n");
        dispArr(mC, 4, 5, "%7.3f ");
        //Запишем систему уравнений для нахождения P1, P2, P3, P4
        treugArr(mC, 4);
        P = new float[ni + 1];
        P = gSolve(mC, 5);
        P[4] = 1;
        //Запишем получившееся уравнение с λ
        System.out.println("Характеристическое уравнение: \n");
        System.out.println(P[4] + " λ^4 - (" + P[3] + ") λ^3 - (" + P[2] + ") λ^2 - (" + P[1] + ") λ - (" + P[0] + ") = 0 \n");
        lambda = new float[ni];
        //Ищем значения λ методом половинного деления
        for (int k = 4; k > 0; k--) {
            //Будем решать полученное уравнение методом половинного деления
            a = halfDiv(P, eps);
            lambda[k - 1] = a;
            System.out.println("λ[" + (ni + 1 - k) + "]: ");
            System.out.printf("%7.3f \n", a);
            //Разделим уравнение на полученный корень, чтобы получить кубическое
            P = urDiv(P, a, k);
            //Запишем результат деления
            if (k - 1 > 0) {
                System.out.println("Уравнение " + (k - 1) + " степени: \n");
                System.out.println(P[4] + " λ^4 - (" + P[3] + ") λ^3 - (" + P[2] + ") λ^2 - (" + P[1] + ") λ - (" + P[0] + ") = 0 \n");
            }
        }
        //Аккуратно выведем полученные значения λ
        System.out.println("------------------------------ \n");
        System.out.println("Полученные собственные значения: \n");
        for (int i = ni; i > 0; i--) {
            System.out.println("λ[" + (ni - i + 1) + "]: " + lambda[i - 1] + ";\n");
        }
        System.out.println("------------------------------ \n");
    }
}

130, 131, 148, 152, 154, 156, 157 строки исправляйте сами, черт его знает в каком формате у вас данные хранятся в файле.
1
0 / 0 / 0
Регистрация: 05.03.2017
Сообщений: 8
07.10.2018, 16:53 3
Как вы использовали функции C в коде Java? Я что-то понять не могу( fscanf(file, "%d", &ni); fscanf(file, "%d", &nj);
0
Модератор
Эксперт Java
4343 / 2442 / 983
Регистрация: 21.10.2017
Сообщений: 7,567
07.10.2018, 17:45 4

Не по теме:

Conficker_, это домашнее задание

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.10.2018, 17:45

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Вычисление собственных значений и собственных векторов матрицы. Метод скалярных произведений
Курсовая работа!! Задание: &quot;Вычисление собственных значений и собственных векторов матрицы. Метод...

Нахождение собственных значений матрицы
как ее вообще писать? знаю как вычислять самостоятельно,но не на паскале..

Нахождение собственных чисел матрицы, метод Данилевского
Нужно найти собственные числа матрицы n*n.Реализовать метод данилевского. Public: int poryadok; ...

Нахождение собственных значений симметричной матрицы методом бисекции
Доброго времени суток. Подскажите пожалуйста с программой, необходимо найти собственные значения...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.