Вот мой код MATLAB, который вычисляет френелевскую дифракцию. И я хочу реализовать тот же код в C++.
clc;clear all;close all;
N=512;
M=512;
lambda=632e-9;
X = 12.1e-6;
k=2*pi/lambda;
z0 = (N*X^2)/lambda;
a = (exp(j*k*z0)/(j*lambda))
hX=(exp(j*k*z0)/(j*lambda))*exp(j*pi/(z0*lambda)*X^2*[0:N-1].^2);
hY=(exp(j*k*z0)/(j*lambda))*exp(j*pi/(z0*lambda)*X^2*[0:M-1].^2);
h = hX.'*hY;
figure; imshow(real(h), []);
И хотя я пытаюсь реализовать тот же код в C++, я попробовал это:
int main (){
std::complex<double> com_two(0,1);
double mycomplex = 1;
double pi = 3.1415926535897;
double N = 512;
double M = 512;
double lambda = 632e-9;
double X = 12.1e-6;
double k = (2*pi)/lambda;
double z0=(N*pow(X,2))/lambda;
//std::complex<double> hx; // Both definitions don't work
//double hy;
/*for (int j=0; j < N; j++){
hy = (exp(mycomplex*k*z0) / (mycomplex*lambda))*exp(mycomplex*pi/(z0*lambda)*pow(X,2)*pow(j,2));
cout << hy <<endl;
}*/
system("pause");
return 0;
}
Но дело в том, что, хотя вычисления, выполняющие значения hx и hy, возвращают комплексные значения.
Итак, как мне определить "mycomplex", как i, j, как в коде MATLAB. Также я нашел несколько оспариваний, таких как std::complex<double> complex;
Но я думаю, что это не сработает. По-моему, мне нужно получить значения hx и hy как сложные числа. Но я не смог найти правильное решение.
Я буду очень рад, если кто-то поможет в этом.
проблема - это не сложное число, а расчеты, которые вы выполняете. Сначала вы делаете разные вещи в Matlab alg (версия, которую вы показали как минимум) и в C++. Вот как вы должны поместить этот код в C++.
#include <cstdlib>
#include <iostream>
#include <complex>
using namespace std;
/*
*
*/
int main(int argc, char** argv) {
double pi = 3.1415926535897;
double N = 512;
double M = 512;
double lambda = 632e-9;
double X = 12.1e-6;
double k = (2 * pi) / lambda;
double z0 = (N * pow(X, 2)) / lambda;
std::complex<double> hx, hy; // Both definitions don't work
//double hy;
int j = 1;
//for (int j=0; j < N; j++){
hy = (exp(j*k*z0) / (j*lambda))*exp(j*pi/(z0*lambda)*pow(X,2)*pow(j,2));
cout << hy <<endl;
//}
system("pause");
return 0;
}
теперь проблема в вашей lambda = 632e-9
которая близка к нулю, тогда k очень большая k = (2 * pi)/lambda;
как обратное к чему-то, что приближается к 0, а в свою очередь
exp(j*k*z0)
очень большой, и это
(exp(j*k*z0) / (j*lambda))
даже больше. Тогда это
(exp(j*k*z0) / (j*lambda))*exp(j*pi/(z0*lambda)
является огромным, а остаточный фактор pow(X,2)*pow(j,2))
имеет смысл. Тогда
cout << hy <<endl;
будет печатать (inf,0)
даже для лямбда = 0,0001; (как насчет 632e-9!).
Однако вы можете распечатать его, если вы используете достаточно маленькое значение j
для поглощения огромного значения k
в exp (j
также находится в знаменателе, но правило l'Hopital гарантирует, что это будет меньше).
Как следует из ваших комментариев (а не вашего кода), вам нужно, чтобы j
было комплексным числом z = 1i. Тогда решение должно измениться
double j =1;
в
std::complex<double> j(0,1);
РЕШЕНИЕ:
int main(int argc, char** argv) {
double pi = 3.1415926535897;
double N = 512;
double M = 512;
double lambda = 0.00001;//632e-9;
double X = 12.1e-6;
double k = (2 * pi) / lambda;
double z0 = (N * pow(X, 2)) / lambda;
std::complex<double> hx, hy;
std::complex<double> j(0,1);
hy = (exp(j*k*z0) / (j*lambda))*exp(j*pi/(z0*lambda)*pow(X,2)*pow(j,2));
cout << hy <<endl;
return 0;
}
j
мнимо 1 в Matlab. Здесь - это действительно положительное число. Это главная ошибка.
Я изменил несколько строк в вашем коде, и он дает результаты, отличные от 1 # INF
1) Измените mycomplex
от double
до std::complex<double>
и назначьте (0,1)
чтобы сделать его мнимым 1. Фактически com_two
имеет тот же тип и значение, которые вам нужны для mycomplex
и вы не используете его.
2) Удалите комментарии. Измените тип hy
из double
в std::complex<double>
. Удалите неиспользуемую декларацию hx
.
3) Мой компилятор обнаруживает ошибку в pow(j,2)
из-за двусмысленности, поэтому я ее исправил.
#include <iostream>
#include <complex>
using namespace std;
int main (){
complex<double> mycomplex(0,1);
double pi = 3.1415926535897;
double N = 512;
double M = 512;
double lambda = 632e-9;
double X = 12.1e-6;
double k = (2*pi)/lambda;
double z0=(N*pow(X,2))/lambda;
complex<double> hy;
for (int j=0; j < N; j++){
hy = (exp(mycomplex*k*z0) / (mycomplex*lambda))*exp(mycomplex*pi/(z0*lambda)*pow(X,2)*pow((double)j,2));
cout << hy <<endl;
}
system("pause");
return 0;
}
1)
. Это на самом деле то, что OP хочет сделать код похожим на Matlab, где j
является мнимым 1.