Für Vorlesungen, bitte die Webseite verwenden. https://flavigny.de/lecture
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

154 wiersze
4.3KB

  1. // Kompilieren mit:
  2. //
  3. // g++ -I../hdnum/ -o rohrleitungsnetzwerk rohrleitungsnetzwerk.cc
  4. //
  5. // Das setzt voraus, dass ihr Programm in einem Ordner parallel zur
  6. // entpackten HDNum Bibliothek liegt.
  7. #include <iostream>
  8. #include <cstdlib>
  9. #include "hdnum.hh"
  10. // Funktion zum Aufstellen der Matrix
  11. template<class NumberType>
  12. void flussMatrix( hdnum::DenseMatrix<NumberType> &A ) {
  13. int M( A.rowsize() );
  14. int N( A.colsize() );
  15. if(M!=N)
  16. HDNUM_ERROR("Matrix muss quadratisch sein!");
  17. // Numerierung wie auf Zettel 3 nur mit 0 beginnend
  18. // also v_0, ... ,v_(N^2-1)
  19. // der Referenzknoten v_r hat Druck 0
  20. // berechnung der kantenlaenge
  21. int n = floor(sqrt(N+1));
  22. for(int i = 0; i < N; i++) {
  23. int edges = 0;
  24. if ((i+1)%n != 0) { // nicht linker rand
  25. edges++;
  26. if (i-1 >= 0) A(i, i-1) = -1; // falls nicht der referenzknoten
  27. }
  28. if ((i+2)%n != 0) { // nicht rechter rand
  29. edges++;
  30. A(i, i+1) = -1;
  31. }
  32. if (i+n < N) { // nicht unterer rand
  33. edges++;
  34. A(i, i+n) = -1;
  35. }
  36. if (i-n >= -1) { // nicht oberer rand
  37. edges++;
  38. if (i-n >= 0) A(i, i-n) = -1; // falls nicht der referenzknoten
  39. }
  40. A(i, i) = edges;
  41. }
  42. }
  43. // Funktion zur Berechnung der Frobenius-Norm einer Matrix
  44. template<class NumberType>
  45. NumberType frobeniusNorm(const hdnum::DenseMatrix<NumberType> &A) {
  46. // Error checking
  47. int M(A.rowsize());
  48. int N(A.colsize());
  49. if(M!=N)
  50. HDNUM_ERROR("Matrix muss quadratisch sein!");
  51. NumberType result=0.0;
  52. // iteriere ueber alle zeilen und spalten, quadriere die elemente und summiere
  53. for (int i=0; i < N; i++) {
  54. for (int j=0; j < N; j++) {
  55. result += pow(A(i,j), 2);
  56. }
  57. }
  58. // ziehe wurzel aus summe
  59. return sqrt(result);
  60. }
  61. // Funktion zur Berechnung des betragsgroessten Eigenwertes mit Potenzmethode
  62. template<class NumberType>
  63. NumberType maxEigenwert(const hdnum::DenseMatrix<NumberType> &A) {
  64. // Error checking
  65. int M(A.rowsize());
  66. int N(A.colsize());
  67. if(M!=N)
  68. HDNUM_ERROR("Matrix muss quadratisch sein!");
  69. // start vektor
  70. hdnum::Vector<NumberType> r(N);
  71. r[0] = 0;
  72. // work copy
  73. hdnum::Vector<NumberType> r_tmp(N);
  74. // finde vektor mit Ar != 0
  75. for (int i = 0;;i++) {
  76. A.mv(r_tmp, r); // r_tmp = Ar
  77. if (r_tmp.two_norm() > 0) {
  78. // Ar != 0
  79. break;
  80. } else if (i >= 100) {
  81. // breche ab, wenn kein passender startvektor gefunden werden kann
  82. HDNUM_ERROR("Kann keinen Vektor mit Ax != 0 finden. Ist A = 0?");
  83. }
  84. // Ar = 0, modifiziere start vektor
  85. r[i % N] += 1;
  86. }
  87. // fuehre iterationsschritt maximal 10000 mal aus
  88. for (int k=0; k<10000; k++) {
  89. A.mv(r_tmp, r); // r_tmp = Ar
  90. r_tmp /= r_tmp.two_norm(); // normiere r_tmp
  91. if ((r-r_tmp).two_norm() == 0)
  92. // breche ab ab, wenn maximale genauigkeit erreicht wurde
  93. break;
  94. r = r_tmp;
  95. }
  96. // berechne eigenwert mit rayleigh quotient
  97. A.mv(r_tmp, r); // r_tmp = Ar
  98. return (r * r_tmp)/r.two_norm_2();
  99. }
  100. // Hauptprogramm
  101. int main(int argc, char ** argv) {
  102. // Anzahl der Knoten
  103. const int N(10);
  104. std::cout << "Knotenanzahl N: " << N << std::endl;
  105. // Größe der Matrix
  106. const int n(N*N-1);
  107. // Datentyp für die Matrix
  108. typedef double REAL;
  109. // Matrix initialisieren
  110. hdnum::DenseMatrix<REAL> A(n,n);
  111. // Pretty-printing einmal setzen für alle Matrizen
  112. A.scientific(false);
  113. A.width(15);
  114. flussMatrix(A);
  115. if (N<=4)
  116. std::cout << A << std::endl;
  117. // Bei Schwierigkeiten mit Teilaufgabe a) können Sie Teilaufgaben b)
  118. // und c) mit folgender Matrix testen
  119. int size_b = 3;
  120. hdnum::DenseMatrix<REAL> B(size_b,size_b);
  121. for (std::size_t i=0; i<size_b; ++i) {
  122. for (std::size_t j=0; j<size_b; ++j) {
  123. B[i][j] = i+j;
  124. }
  125. }
  126. std::cout << "Zeilen-Summen-Norm: " << A.norm_infty() << std::endl;
  127. std::cout << "Spalten-Summen-Norm: " << A.norm_1() << std::endl;
  128. std::cout << "Frobenius-Norm: " << frobeniusNorm(A) << std::endl;
  129. std::cout << "Maximaler Eigenwert: " << maxEigenwert(A) << std::endl;
  130. return 0;
  131. }