//----------------------------------------------------------------------------------------------
        //           Cuda  Френель из k1 в k2
        //----------------------------------------------------------------------------------------------
        public static ZComplexDescriptor Fr_CUDA(ZComplexDescriptor zarray, double lambda, double d, double dx)
        {
            int nx = zarray.width;
            int ny = zarray.height;
            ZComplexDescriptor resultArray = new ZComplexDescriptor(nx, ny);

            Complex[] Array_с2x = FurieN.fexp2(lambda, d, nx, dx);                       // Умножение на экспоненту
            Complex[] Array_с2y = FurieN.fexp2(lambda, d, ny, dx);

            for (int j = 0; j < ny; j++)
            {
                for (int i = 0; i < nx; i++)
                {
                    resultArray.array[i, j] = zarray.array[i, j] * Array_с2x[i] * Array_с2y[j];
                }
            }

            //Array_с2 = FurieN.fexp2(lambda, d, ny, dx);
            //for (int i = 0; i < nx; i++)
            //    for (int j = 0; j < ny; j++) resultArray.array[i, j] = resultArray.array[i, j] * Array_с2[j];

            ComplexNumber[] Cud_array  = ComplexMatrix.ToArrayByRows(resultArray);      // Из двухмерного в одномерный ->  Массив комплексных (Struct)чисел [nx*ny]
            ComplexNumber[] Cud_array1 = CUDA_FFT.CudaFFT(Cud_array, nx, ny);           // БПФ

            int k = 0;

            for (int i = 0; i < nx; i++)                                                // Из одномерного в двухмерный
            {
                for (int j = 0; j < ny; j++)
                {
                    resultArray.array[i, j] = Complex.FromPolarCoordinates(Cud_array1[k].Real, Cud_array1[k].Imaginary);  // Преобразование из одномерного в [ , ]
                    k++;
                }
            }


            double[] phase_y = FurieN.fexp1(lambda, d, ny, dx);                           // Умножение на экспоненту
            double[] phase_x = FurieN.fexp1(lambda, d, nx, dx);

            for (int i = 0; i < nx; i++)
            {
                for (int j = 0; j < ny; j++)
                {
                    resultArray.array[i, j] = Complex.FromPolarCoordinates(resultArray.array[i, j].Magnitude, resultArray.array[i, j].Phase + phase_y[j] + phase_x[i]);
                }
            }

            //  phase = FurieN.fexp1(lambda, d, nx, dx);
            //  for (int j = 0; j < ny; j++)
            //      for (int i = 0; i < nx; i++)
            //      { resultArray.array[i, j] = Complex.FromPolarCoordinates(resultArray.array[i, j].Magnitude, resultArray.array[i, j].Phase + phase[i]); }

            return(resultArray);
        }
        public static void Conv_D(int k3, int k4, int k5, ProgressBar progressBar1) // Корреляция двух вещественных массивов
        {
            k3--; k4--; k5--;                                                       // Массив 1 ->  0

            //MessageBox.Show("k3= " + k3 + " - k4= " + k4 + " = k5= " + k5);

            if (Form1.zArrayDescriptor[k3] == null)
            {
                MessageBox.Show("Mul_C zComplex[" + k3 + "] == NULL"); return;
            }
            if (Form1.zArrayDescriptor[k4] == null)
            {
                MessageBox.Show("Mul_C zComplex[" + k4 + "] == NULL"); return;
            }

            int nx = Form1.zArrayDescriptor[k3].width;
            int ny = Form1.zArrayDescriptor[k3].height;

            int nx1 = Form1.zArrayDescriptor[k4].width;
            int ny1 = Form1.zArrayDescriptor[k4].height;

            if ((nx != nx1) || (ny != ny1))
            {
                MessageBox.Show("Mul_C Размеры массивов не согласованы"); return;
            }


            progressBar1.Visible = true;
            progressBar1.Minimum = 1;
            progressBar1.Maximum = 3;
            progressBar1.Value   = 1;
            progressBar1.Step    = 1;


            ZArrayDescriptor b = new ZArrayDescriptor(ny, nx);

            for (int i = 0; i < nx; i++)                                    // Транспонирование первого массива
            {
                for (int j = 0; j < ny; j++)
                {
                    b.array[j, i] = Form1.zArrayDescriptor[k3].array[i, j];
                }
            }
            progressBar1.PerformStep();                             // ------------------------------------ 1 шаг

            ZComplexDescriptor zCmpl1 = new ZComplexDescriptor(b);  // Конструктор для заполнения реальной части и мнимой части = 0
            ZComplexDescriptor zCmpl2 = new ZComplexDescriptor(Form1.zArrayDescriptor[k4]);

            zCmpl1 = FurieN.BPF2(zCmpl1); progressBar1.PerformStep();       // ------------------------------------ 2 шаг
            zCmpl2 = FurieN.BPF2(zCmpl2); progressBar1.PerformStep();       // ------------------------------------ 3 шаг

            ZComplexDescriptor a = new ZComplexDescriptor(nx, nx);          // Результирующая матрица (ny x nx)*(nx * ny) = (nx x nx)

            progressBar1.Maximum = nx;
            progressBar1.Value   = 1;

            Complex s0 = new Complex(0, 0);

            for (int i = 0; i < nx; i++)
            {
                for (int j = 0; j < nx; j++)
                {
                    Complex s = s0;
                    for (int y = 0; y < ny; y++)
                    {
                        s += zCmpl1.array[y, j] * zCmpl2.array[i, y];     // Строка на столбец
                    }
                    a.array[i, j] = s;
                }
                progressBar1.PerformStep();
            }
            progressBar1.Value = 1;

            a = FurieN.BPF2(a);                                             // ------------------------------------ 5 шаг
            Form1.zArrayDescriptor[k5] = Furie.zAmplituda(a);


            VisualRegImage(k5);
        }