Gistrec

Обратная задача 2

Oct 16th, 2019
230
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.79 KB | None | 0 0
  1. #include <iostream>
  2. #include <cassert>
  3. #include <fstream>
  4. #include <vector>
  5. #include <cmath>
  6. #include <random>
  7.  
  8.  
  9. using namespace std;
  10.  
  11. #define M_PI 3.1415926
  12. #define EPS  0.0000001
  13.  
  14. struct Point3d {
  15.     double x;
  16.     double y;
  17.     double z;
  18. };
  19.  
  20. struct Range {
  21.     Point3d start;
  22.     Point3d end;
  23. };
  24.  
  25. Range source; // Источник
  26. vector<Range>  receivers;  // Приёмники
  27. vector<double> potentials; // Разность потенциалов измеренное на каждом приёмнике
  28.  
  29. double calculatedSigma = 0.01;
  30. vector<double> calculatedPotential;
  31.  
  32. constexpr double goldenSigma = 0.1;
  33. constexpr double goldenI = 1;
  34.  
  35.  
  36.  
  37.  
  38. double distance(Point3d first, Point3d second) {
  39.     return sqrt(pow(first.x - second.x, 2) +
  40.                 pow(first.y - second.y, 2) +
  41.                 pow(first.z - second.z, 2));
  42. }
  43.  
  44. void calculateNextPotentials() {
  45.     // Генерация синтетический данных
  46.     for (size_t i = 0; i < receivers.size(); i++) {
  47.         double U = goldenI / (2 * M_PI * calculatedSigma) * ((1 / distance(source.end, receivers[i].start) - 1 / distance(source.start, receivers[i].start)) -
  48.             (1 / distance(source.end, receivers[i].end) - 1 / distance(source.start, receivers[i].end)));
  49.         calculatedPotential[i] = U;
  50.         //std::cout << "calculatedPotential[" << i << "] = " << U << std::endl;
  51.     }
  52. }
  53.  
  54. // Минимизируемый функционал
  55. //TODOOOOOOOOOO
  56. double getF() {
  57.     double F = 0;
  58.  
  59.     for (size_t i = 0; i < receivers.size(); i++) {
  60.         F += 1 / potentials[i] * pow(potentials[i] - calculatedPotential[i], 2);
  61.     }
  62.  
  63.     return F;
  64. }
  65.  
  66. int main() {
  67.     std::random_device dev;
  68.     std::mt19937 rng(dev());
  69.     std::uniform_int_distribution<std::mt19937::result_type> dist(90, 110);
  70.  
  71.     ifstream input("example1.txt");
  72.     assert(input.is_open() && "Error while opening file");
  73.  
  74.     size_t sourcesCount;
  75.     size_t receiversCount;
  76.  
  77.     input >> sourcesCount;
  78.     input >> receiversCount;
  79.  
  80.     calculatedPotential.resize(receiversCount);
  81.  
  82.     // Считываем источник
  83.     input >> source.start.x >> source.start.y >> source.start.z;
  84.     input >> source.end.x >> source.end.y >> source.end.z;
  85.  
  86.     // Считываем приёмники
  87.     for (size_t i = 0; i < receiversCount; i++) {
  88.         Range receiver;
  89.  
  90.         input >> receiver.start.x >> receiver.start.y >> receiver.start.z;
  91.         input >> receiver.end.x >> receiver.end.y >> receiver.end.z;
  92.  
  93.         receivers.emplace_back(receiver);
  94.     }
  95.  
  96.  
  97.     // Считываем разность потенциалов на каждом приёмнике
  98.     for (size_t i = 0; i < receiversCount; i++) {
  99.         double potential;
  100.         input >> potential;
  101.  
  102.         double noise = (dist(rng) / 100.0);
  103.         potential *= noise;
  104.  
  105.         potentials.emplace_back(potential);
  106.     }
  107.  
  108.     vector<double> diff(receivers.size(), 0);
  109.     calculateNextPotentials();
  110.  
  111.     std::cout << calculatedSigma << " " << getF() << endl;
  112.     // ---------------------- //
  113.     double prevSigma = calculatedSigma;
  114.     do {
  115.         prevSigma = calculatedSigma;
  116.  
  117.         double elemA = 0; // Элемент СЛАУ
  118.         double elemB = 0; // Правая часть уравнения
  119.         for (size_t i = 0; i < receivers.size(); i++) {
  120.             diff[i] = -goldenI / (2 * M_PI * pow(calculatedSigma,2)) * ((1 / distance(source.end, receivers[i].start) - 1 / distance(source.start, receivers[i].start)) -
  121.                 (1 / distance(source.end, receivers[i].end) - 1 / distance(source.start, receivers[i].end)));
  122.  
  123.             elemA += pow((1 / potentials[i]) * diff[i], 2);
  124.             elemB -= pow(1 / potentials[i], 2) * diff[i] * (calculatedPotential[i] - potentials[i]);
  125.         }
  126.         double deltaSigma = elemB / elemA;
  127.         calculatedSigma += deltaSigma;
  128.  
  129.         // Пересчитываем potenrial
  130.         calculateNextPotentials();
  131.  
  132.         std::cout << calculatedSigma << " " << getF() << std::endl;
  133.     } while (abs(prevSigma - calculatedSigma) > EPS);
  134.  
  135.     system("pause");
  136.     return 0;
  137. }
Comments
  • User was banned
Add Comment
Please, Sign In to add comment