matematykaszkolna.pl
Wielomiany Czebyszowa ortogonalizacja Mariusz: using System; using System.Globalization; using System.Numerics; using ExtendedNumerics; namespace NamespaceName { public class ClassName { public static void Main(string[] args) { int n; BigRational[,] T,U; BigRational sum; int error; char esc; do { Console.WriteLine("Podaj stopień macierzy"); int.TryParse(Console.ReadLine(),out n); T = new BigRational[n+1,n+1]; U = new BigRational[n,n]; ModifiedGramSchmidt(n,T); for(int i=0;i<=n;i++) { sum = 0; for(int j=0; j<=i;j++) sum += T[j,i]; for(int j=0; j<=i;j++) T[j,i] /= (BigRational)sum; } for(int j=0;j<U.GetLength(1);j++) for(int i=0;i<U.GetLength(0);i++) { U[i,j] = (i+1)*T[i+1,j+1]; U[i,j] /= (j+1); } Console.WriteLine("Macierz współczynników wielomianów Czebyszowa I rodzaju"); PrintMatrix(T); Console.WriteLine("Macierz współczynników wielomianów Czebyszowa II rodzaju"); PrintMatrix(U); Inverse(T,out error); if(error == 0) { Console.WriteLine("Macierz odwrotna do macierzy współczynników wielomianów Czebyszowa I rodzaju"); PrintMatrix(T); } esc = (char)Console.ReadKey().Key; } while(esc != (char)ConsoleKey.Escape); } public static void PrintMatrix(BigRational[,] A) { NumberFormatInfo nfi = new NumberFormatInfo(); nfi.NumberDecimalDigits = 12; nfi.NumberGroupSeparator = ""; for(int i=0;i<A.GetLength(0);i++) { for(int j=0;j<A.GetLength(1);j++) { Console.Write("{0} , ",A[i,j].GetImproperFraction()); } Console.WriteLine(); } Console.WriteLine(); } public static BigRational InnerProduct(int m, int n,BigRational[] P,BigRational[] Q) { BigRational sum = BigRational.Zero; BigRational prod = BigRational.One; BigRational[] C = new BigRational[n + m + 1]; for(int i = 0;i < C.Length;i++) C[i] = BigRational.Zero; for(int i = 0;i <= m;i++) { for(int j = 0; j <= n;j++) { C[i + j] += P[i]*Q[j]; } } for(int k = 0;k <= m + n;k += 2) { sum += C[k] * prod; prod *= (BigRational)(k + 1)/(k + 2); } return sum; } public static BigRational[] GetColumn(BigRational[,] A,int j) { BigRational[] temp = new BigRational[A.GetLength(1)]; for(int k = 0;k < A.GetLength(1);k++) { temp[k] = A[k,j]; } return temp; } public static void Inverse(BigRational[,] A,out int error) { if(A.GetLength(0) != A.GetLength(1)) { error = 2; return; } error = 0; int n = A.GetLength(0); int k; BigRational maxA,d,e; int[] M = new int[n]; for(int i = 0;i < n;i++) { maxA = 0; k = i; for(int j = i;j < n;j++) { d = A[j,i]; if(BigRational.Abs(maxA) < BigRational.Abs(d)) { maxA = d; k = j; } } if(maxA == BigRational.Zero) { error = 1; return; } M[i] = k; A[k,i] = 1; for(int j=0;j < n;j++) { d = (BigRational)A[k,j]/maxA; A[k,j] = A[i,j]; A[i,j] = d; } for(int j = 0;j<n;j++) if(j != i) { d = A[j,i]; A[j,i] = 0; for(int l = 0;l < n;l++) { e = d * A[i,l]; A[j,l] −= e; } } } for(int i = n−1;i >= 0;i−−) { k = M[i]; if(k != i) for(int j = 0;j < n;j++) { d = A[j,i]; A[j,i] = A[j,k]; A[j,k] = d; } } } public static void ModifiedGramSchmidt(int n, BigRational[,] Q) { /* for j = 1:n vj = xj; end for for j = 1:n qj = vj / ||vj||2 for k = j + 1:n vk = vk − (qjTvk)*qj end for end for */ BigRational[] Qj = new BigRational[n+1]; BigRational[] Qk = new BigRational[n+1]; for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) Q[i,j] = (i==j?1:0); for(int j = 0;j <= n;j++) { Qj = GetColumn(Q,j); BigRational invnorm = BigRational.One/(InnerProduct(j,j,Qj,Qj)); for(int k = j+1;k <= n;k++) { Qk = GetColumn(Q,k); BigRational w = invnorm*InnerProduct(j,k,Qj,Qk); for(int i = k;i >= 0;i−−) { Q[i,k] −= w*Q[i,j] ; } } } } } } Tutaj zmodyfikowałem nieco iloczyn skalarny aby uniknąć konieczności korzystania z liczb niewymiernych Użyłem tutaj zmodyfikowanej metody ortogonalizacji Grama−Schmidta Ciekawe jak ją zastąpić np metodą odbić Householdera Dość kosztowny czasowo jest też iloczyn skalarny czy nie dałoby się go jakoś przyśpieszyć ? Skompilowałem ze źródeł znalezionych na githubie klasę BigRational do dll
11 gru 02:34
X:
21 gru 10:40