

#include <iostream>
#include <memory>
#include <cmath>
#include <complex>
#include <device_launch_parameters.h>
#include <cuda_runtime.h>
#include <cublas_v2.h>
#include <cuComplex.h>

#include "BaseConstVariable.h"
#include "GPURTPC.cuh"

#ifdef __CUDANVCC___


__device__ float GPU_getSigma0dB(CUDASigmaParam param, float theta) {//线性值
	float sigma= param.p1 + param.p2 * exp(-param.p3 * theta) + param.p4 * cos(param.p5 * theta + param.p6);
	return  sigma;
}


__device__ CUDAVectorEllipsoidal GPU_SatelliteAntDirectNormal(float RstX, float RstY, float RstZ,
	float  antXaxisX, float  antXaxisY, float  antXaxisZ,
	float  antYaxisX, float  antYaxisY, float  antYaxisZ,
	float  antZaxisX, float  antZaxisY, float  antZaxisZ,
	float  antDirectX, float  antDirectY, float  antDirectZ
) {
	CUDAVectorEllipsoidal result{ 0,0,-1 };
	float Xst = -1 * RstX; // 卫星 -->  地面
	float Yst = -1 * RstY;
	float Zst = -1 * RstZ;
	float AntXaxisX = antXaxisX;
	float AntXaxisY = antXaxisY;
	float AntXaxisZ = antXaxisZ;
	float AntYaxisX = antYaxisX;
	float AntYaxisY = antYaxisY;
	float AntYaxisZ = antYaxisZ;
	float AntZaxisX = antZaxisX;
	float AntZaxisY = antZaxisY;
	float AntZaxisZ = antZaxisZ;
	// 天线指向在天线坐标系下的值
	float Xant = (Xst * (AntYaxisY * AntZaxisZ - AntYaxisZ * AntZaxisY) + Xst * (AntXaxisZ * AntZaxisY - AntXaxisY * AntZaxisZ) + Xst * (AntXaxisY * AntYaxisZ - AntXaxisZ * AntYaxisY)) / (AntXaxisX * (AntYaxisY * AntZaxisZ - AntZaxisY * AntYaxisZ) - AntYaxisX * (AntXaxisY * AntZaxisZ - AntXaxisZ * AntZaxisY) + AntZaxisX * (AntXaxisY * AntYaxisZ - AntXaxisZ * AntYaxisY));
	float Yant = (Yst * (AntYaxisZ * AntZaxisX - AntYaxisX * AntZaxisZ) + Yst * (AntXaxisX * AntZaxisZ - AntXaxisZ * AntZaxisX) + Yst * (AntYaxisX * AntXaxisZ - AntXaxisX * AntYaxisZ)) / (AntXaxisX * (AntYaxisY * AntZaxisZ - AntZaxisY * AntYaxisZ) - AntYaxisX * (AntXaxisY * AntZaxisZ - AntXaxisZ * AntZaxisY) + AntZaxisX * (AntXaxisY * AntYaxisZ - AntXaxisZ * AntYaxisY));
	float Zant = (Zst * (AntYaxisX * AntZaxisY - AntYaxisY * AntZaxisX) + Zst * (AntXaxisY * AntZaxisX - AntXaxisX * AntZaxisY) + Zst * (AntXaxisX * AntYaxisY - AntYaxisX * AntXaxisY)) / (AntXaxisX * (AntYaxisY * AntZaxisZ - AntZaxisY * AntYaxisZ) - AntYaxisX * (AntXaxisY * AntZaxisZ - AntXaxisZ * AntZaxisY) + AntZaxisX * (AntXaxisY * AntYaxisZ - AntXaxisZ * AntYaxisY));
	// 计算theta 与 phi
	float Norm = sqrtf(Xant * Xant + Yant * Yant + Zant * Zant); // 计算 pho
	float ThetaAnt = acosf(Zant / Norm); // theta 与 Z轴的夹角
	float YsinTheta = Yant / sinf(ThetaAnt);
	float PhiAnt = (YsinTheta / abs(YsinTheta)) * acosf(Xant / (Norm * sinf(ThetaAnt)));
	result.theta = ThetaAnt;
	result.phi = PhiAnt;
	result.pho = Norm;
	return result;
}

__device__ float GPU_BillerInterpAntPattern(float* antpattern,
	float starttheta, float startphi, float dtheta, float dphi,
	long thetapoints, long phipoints,
	float searththeta, float searchphi) {
	float stheta = searththeta;
	float sphi = searchphi;
	if (stheta > 90) {
		return 0;
	}
	else {}


	float pthetaid = (stheta - starttheta) / dtheta;// 
	float pphiid = (sphi - startphi) / dphi;

	long lasttheta = floorf(pthetaid);
	long nextTheta = lasttheta + 1;
	long lastphi = floorf(pphiid);
	long nextPhi = lastphi + 1;
 

	if (lasttheta < 0 || nextTheta < 0 || lastphi < 0 || nextPhi < 0 ||
		lasttheta >= thetapoints || nextTheta >= thetapoints || lastphi >= phipoints || nextPhi >= phipoints)
	{
		return 0;
	}
	else {
		float x = stheta;
		float y = sphi;

		float x1 = lasttheta * dtheta + starttheta;
		float x2 = nextTheta * dtheta + starttheta;
		float y1 = lastphi * dphi + startphi;
		float y2 = nextPhi * dphi + startphi;

		float z11 = antpattern[lasttheta * phipoints + lastphi];
		float z12 = antpattern[lasttheta * phipoints + nextPhi];
		float z21 = antpattern[nextTheta * phipoints + lastphi];
		float z22 = antpattern[nextTheta * phipoints + nextPhi];


		//z11 = powf(10, z11 / 10); // dB-> 线性
		//z12 = powf(10, z12 / 10);
		//z21 = powf(10, z21 / 10);
		//z22 = powf(10, z22 / 10);

		float GainValue = (z11 * (x2 - x) * (y2 - y)
			+ z21 * (x - x1) * (y2 - y)
			+ z12 * (x2 - x) * (y - y1)
			+ z22 * (x - x1) * (y - y1));
		GainValue = GainValue / ((x2 - x1) * (y2 - y1));
		return GainValue;
	}
}

__device__ cuComplex  GPU_calculationEcho(float sigma0, float TransAnt, float ReciveAnt,
	float localangle, float R, float slopeangle, float Pt, float lamda) {
	float amp = Pt * TransAnt * ReciveAnt;
	amp = amp * sigma0;
	amp = amp / (powf(4 * LAMP_CUDA_PI, 2) * powf(R, 4)); // 反射强度
	float phi = (-4 * LAMP_CUDA_PI / lamda) * R;
	cuComplex echophi = make_cuComplex(0, phi);
	cuComplex echophiexp = cuCexpf(echophi);
	cuComplex echo=make_cuComplex(echophiexp.x * amp, echophiexp.y * amp);
	return echo;
}


__global__ void CUDA_SatelliteAntDirectNormal(float* RstX, float* RstY, float* RstZ,
	float  antXaxisX, float  antXaxisY, float  antXaxisZ,
	float  antYaxisX, float  antYaxisY, float  antYaxisZ,
	float  antZaxisX, float  antZaxisY, float  antZaxisZ,
	float  antDirectX, float  antDirectY, float  antDirectZ,
	float* thetaAnt, float* phiAnt
	, long len) {
	long  idx = blockIdx.x * blockDim.x + threadIdx.x;
	if (idx < len) {
		float Xst		= -1 * RstX[idx]; // 卫星 -->  地面
		float Yst		= -1 * RstY[idx];
		float Zst		= -1 * RstZ[idx];
		float AntXaxisX = antXaxisX;
		float AntXaxisY = antXaxisY;
		float AntXaxisZ = antXaxisZ;
		float AntYaxisX = antYaxisX;
		float AntYaxisY = antYaxisY;
		float AntYaxisZ = antYaxisZ;
		float AntZaxisX = antZaxisX;
		float AntZaxisY = antZaxisY;
		float AntZaxisZ = antZaxisZ;

		// 归一化
		float RstNorm		= sqrtf(Xst * Xst + Yst * Yst + Zst * Zst);
		float AntXaxisNorm = sqrtf(AntXaxisX * AntXaxisX + AntXaxisY * AntXaxisY + AntXaxisZ * AntXaxisZ);
		float AntYaxisNorm = sqrtf(AntYaxisX * AntYaxisX + AntYaxisY * AntYaxisY + AntYaxisZ * AntYaxisZ);
		float AntZaxisNorm = sqrtf(AntZaxisX * AntZaxisX + AntZaxisY * AntZaxisY + AntZaxisZ * AntZaxisZ);


		float Rx = Xst / RstNorm;
		float Ry = Yst / RstNorm;
		float Rz = Zst / RstNorm;
		float Xx = AntXaxisX / AntXaxisNorm;
		float Xy = AntXaxisY / AntXaxisNorm;
		float Xz = AntXaxisZ / AntXaxisNorm;
		float Yx = AntYaxisX / AntYaxisNorm;
		float Yy = AntYaxisY / AntYaxisNorm;
		float Yz = AntYaxisZ / AntYaxisNorm;
		float Zx = AntZaxisX / AntZaxisNorm;
		float Zy = AntZaxisY / AntZaxisNorm;
		float Zz = AntZaxisZ / AntZaxisNorm;

		float Xant =	(Rx * Yy * Zz - Rx * Yz * Zy - Ry * Yx * Zz + Ry * Yz * Zx + Rz * Yx * Zy - Rz * Yy * Zx) / (Xx * Yy * Zz - Xx * Yz * Zy - Xy * Yx * Zz + Xy * Yz * Zx + Xz * Yx * Zy - Xz * Yy * Zx);
		float Yant =	-(Rx * Xy * Zz - Rx * Xz * Zy - Ry * Xx * Zz + Ry * Xz * Zx + Rz * Xx * Zy - Rz * Xy * Zx) / (Xx * Yy * Zz - Xx * Yz * Zy - Xy * Yx * Zz + Xy * Yz * Zx + Xz * Yx * Zy - Xz * Yy * Zx);
		float Zant =	(Rx * Xy * Yz - Rx * Xz * Yy - Ry * Xx * Yz + Ry * Xz * Yx + Rz * Xx * Yy - Rz * Xy * Yx) / (Xx * Yy * Zz - Xx * Yz * Zy - Xy * Yx * Zz + Xy * Yz * Zx + Xz * Yx * Zy - Xz * Yy * Zx);
 
		
		// 计算theta 与 phi
		float Norm = sqrtf(Xant * Xant + Yant * Yant + Zant * Zant); // 计算 pho
		float ThetaAnt = acosf(Zant / Norm); // theta 与 Z轴的夹角
		float PhiAnt = atanf(Yant / Xant); // -pi/2 ~pi/2


		if (abs(Yant) < PRECISIONTOLERANCE) { // X轴上
			PhiAnt = 0;
		}
		else if (abs(Xant) < PRECISIONTOLERANCE) { // Y轴上，原点
			if (Yant > 0) {
				PhiAnt = PI / 2;
			}
			else {
				PhiAnt = -PI / 2;
			}
		}
		else if (Xant < 0) {
			if (Yant > 0) {
				PhiAnt = PI + PhiAnt;
			}
			else {
				PhiAnt = -PI+PhiAnt ;
			}
		}
		else {  // Xant>0  X 正轴

		}

		if (isnan(PhiAnt)) {
			printf("V=[%f,%f,%f];norm=%f;thetaAnt=%f;phiAnt=%f;\n", Xant, Yant, Zant,Norm, ThetaAnt, PhiAnt);
		}

		//if (abs(ThetaAnt - 0) < PRECISIONTOLERANCE) {
		//	PhiAnt = 0;
		//}
		//else {}


		thetaAnt[idx] = ThetaAnt*r2d;
		phiAnt[idx] = PhiAnt*r2d;
		//printf("Rst=[%f,%f,%f];AntXaxis = [%f, %f, %f];AntYaxis=[%f,%f,%f];AntZaxis=[%f,%f,%f];phiAnt=%f;thetaAnt=%f;\n", Xst, Yst, Zst
		//	, AntXaxisX, AntXaxisY, AntXaxisZ
		//	, AntYaxisX, AntYaxisY, AntYaxisZ
		//	, AntZaxisX, AntZaxisY, AntZaxisZ
		//	, phiAnt[idx]
		//	, thetaAnt[idx]
		//);
	}
}

__global__ void CUDA_BillerInterpAntPattern(float* antpattern,
	float starttheta, float startphi, float dtheta, float dphi,
	long thetapoints, long phipoints,
	float* searththeta, float* searchphi, float* searchantpattern,
	long len) {
	long  idx = blockIdx.x * blockDim.x + threadIdx.x;
	if (idx < len) {
		float stheta = searththeta[idx];
		float sphi = searchphi[idx];
		float pthetaid = (stheta - starttheta) / dtheta;// 
		float pphiid = (sphi - startphi) / dphi;

		long lasttheta = floorf(pthetaid);
		long nextTheta = lasttheta + 1;
		long lastphi = floorf(pphiid);
		long nextPhi = lastphi + 1;

		if (lasttheta < 0 || nextTheta < 0 || lastphi < 0 || nextPhi < 0 ||
			lasttheta >= thetapoints || nextTheta >= thetapoints || lastphi >= phipoints || nextPhi >= phipoints)
		{
			searchantpattern[idx] = 0;
		}
		else {
			float x = stheta;
			float y = sphi;

			float x1 = lasttheta * dtheta + starttheta;
			float x2 = nextTheta * dtheta + starttheta;
			float y1 = lastphi * dphi + startphi;
			float y2 = nextPhi * dphi + startphi;

			float z11 = antpattern[lasttheta * phipoints + lastphi];
			float z12 = antpattern[lasttheta * phipoints + nextPhi];
			float z21 = antpattern[nextTheta * phipoints + lastphi];
			float z22 = antpattern[nextTheta * phipoints + nextPhi];


			z11 = powf(10, z11 / 10);
			z12 = powf(10, z12 / 10);
			z21 = powf(10, z21 / 10);
			z22 = powf(10, z22 / 10);

			float GainValue = (z11 * (x2 - x) * (y2 - y)
				+ z21 * (x - x1) * (y2 - y)
				+ z12 * (x2 - x) * (y - y1)
				+ z22 * (x - x1) * (y - y1));
			GainValue = GainValue / ((x2 - x1) * (y2 - y1));
			searchantpattern[idx] = GainValue;
		}
	}
}

__global__ void CUDA_calculationEcho(float* sigma0, float* TransAnt, float* ReciveAnt,
	float* localangle, float* R, float* slopeangle,
	float nearRange, float Fs, float Pt, float lamda, long FreqIDmax,
	cuComplex* echoArr, long* FreqID,
	long len) {
	long  idx = blockIdx.x * blockDim.x + threadIdx.x;
	if (idx < len) {
		float r = R[idx];
		float amp = Pt * TransAnt[idx] * ReciveAnt[idx];
		amp = amp * sigma0[idx];
		amp = amp / (powf(4 * LAMP_CUDA_PI, 2) * powf(r, 4)); // 反射强度

		// 处理相位
		float phi = (-4 * LAMP_CUDA_PI / lamda) * r;
		cuComplex echophi = make_cuComplex(0, phi);
		cuComplex echophiexp = cuCexpf(echophi);

		float timeR = 2 * (r - nearRange) / LIGHTSPEED * Fs;
		long timeID = floorf(timeR);
		//if (timeID < 0 || timeID >= FreqIDmax) {
		//	timeID = 0;
		//	amp = 0;
		//}

		cuComplex echo = make_cuComplex(echophiexp.x , echophiexp.y);
		echoArr[idx] = echo;
		FreqID[idx] = timeID;
	}
}


__global__ void CUDA_AntPatternInterpGain(float* anttheta, float* antphi, float* gain,
	float* antpattern, float starttheta, float startphi, float dtheta, float dphi, int thetapoints, int phipoints, long len) {
	int  idx = blockIdx.x * blockDim.x + threadIdx.x;
 
	if (idx < len) {

		float temptheta = anttheta[idx];
		float tempphi = antphi[idx];
		float antPatternGain =  GPU_BillerInterpAntPattern(antpattern,
			starttheta, startphi, dtheta, dphi, thetapoints, phipoints,
			temptheta, tempphi) ;
		gain[idx] = antPatternGain;
	}
}


__global__ void CUDA_InterpSigma(
	long* demcls, float* sigmaAmp, float* localanglearr, long len,
	CUDASigmaParam* sigma0Paramslist, long sigmaparamslistlen) {
	long  idx = blockIdx.x * blockDim.x + threadIdx.x;
	if (idx < len) {
		long clsid = demcls[idx];
		float localangle = localanglearr[idx];
		CUDASigmaParam tempsigma = sigma0Paramslist[clsid];
		//printf("cls:%d;localangle=%f;\n",clsid, localangle);

		if (localangle < 0 || localangle >= LAMP_CUDA_PI/2) {
			sigmaAmp[idx] = 0;
		}
		else {}

		if (abs(tempsigma.p1)< PRECISIONTOLERANCE&&
			abs(tempsigma.p2) < PRECISIONTOLERANCE &&
			abs(tempsigma.p3) < PRECISIONTOLERANCE &&
			abs(tempsigma.p4) < PRECISIONTOLERANCE&&
			abs(tempsigma.p5) < PRECISIONTOLERANCE&&
			abs(tempsigma.p6) < PRECISIONTOLERANCE
			) {
			sigmaAmp[idx] = 0;
		}
		else {
			float sigma = GPU_getSigma0dB(tempsigma, localangle);
			sigma = powf(10.0, sigma / 10.0);// 后向散射系数
			//printf("cls:%d;localangle=%f;sigma0=%f;\n", clsid, localangle, sigma);
			sigmaAmp[idx] = sigma;
		}
	}
}


__global__ void CUDA_CalculationEchoAmp(float* sigma0, float* TransAnt, float* ReciveAnt, float* R, 
	float Pt, 
	float* ampArr, long len) {
	long  idx = blockIdx.x * blockDim.x + threadIdx.x;
	if (idx < len) {
		float r = R[idx];
		float amptemp = Pt * TransAnt[idx] * ReciveAnt[idx] * sigma0[idx];
		amptemp = amptemp / (powf(4 * LAMP_CUDA_PI, 2) * powf(r, 4)); // 反射强度
		ampArr[idx] = amptemp;
	}
}


__global__ void CUDA_CalculationEchoPhase(float* R, float lamda, float* phaseArr, long len) {
	long  idx = blockIdx.x * blockDim.x + threadIdx.x;
	if (idx < len) {
		float r = R[idx];
		// 处理相位
		float phi = (-4 * LAMP_CUDA_PI / lamda) * r;
		phaseArr[idx] = phi;
	}
}


__global__ void CUDA_CombinationEchoAmpAndPhase(float* R,
	float* echoAmp,float* echoPhase,
	float nearRange, float Fs, long plusepoints,
	cuComplex* echo, long* FreqID, long len) {
	long  idx = blockIdx.x * blockDim.x + threadIdx.x;
	if (idx < len) {
		float r = R[idx];
		float phase = echoPhase[idx];
		float amp = echoAmp[idx];
		cuComplex echophi = make_cuComplex(0, phase);
		cuComplex echophiexp = cuCexpf(echophi);

		float timeR = 2 * (r - nearRange) / LIGHTSPEED * Fs;
		long timeID = floorf(timeR);
		if (timeID < 0 || timeID >= plusepoints) {
			timeID = 0;
			amp = 0;
		}
		cuComplex echotemp = make_cuComplex(echophiexp.x*amp, echophiexp.y*amp);
		echo[idx] = echotemp;
		FreqID[idx] = timeID;

	}
}



extern "C" void SatelliteAntDirectNormal(float* RstX, float* RstY, float* RstZ,
	float  antXaxisX, float  antXaxisY, float  antXaxisZ,
	float  antYaxisX, float  antYaxisY, float  antYaxisZ,
	float  antZaxisX, float  antZaxisY, float  antZaxisZ,
	float  antDirectX, float  antDirectY, float  antDirectZ,
	float* thetaAnt, float* phiAnt
	, long len) {

	int blockSize = 256; // 每个块的线程数
	int numBlocks = (len + blockSize - 1) / blockSize; // 根据 pixelcount 计算网格大小
	// 调用 CUDA 核函数
	CUDA_SatelliteAntDirectNormal << <numBlocks, blockSize >> > (RstX, RstY, RstZ,
		antXaxisX, antXaxisY, antXaxisZ,
		antYaxisX, antYaxisY, antYaxisZ,
		antZaxisX, antZaxisY, antZaxisZ,
		antDirectX, antDirectY, antDirectZ,
		thetaAnt, phiAnt
		, len);

#ifdef __CUDADEBUG__
	cudaError_t err = cudaGetLastError();
	if (err != cudaSuccess) {
		printf("CUDA_RTPC_SiglePRF CUDA Error: %s\n", cudaGetErrorString(err));
		// Possibly: exit(-1) if program cannot continue....
	}
#endif // __CUDADEBUG__
	cudaDeviceSynchronize();

}

extern "C" void   AntPatternInterpGain(float* anttheta, float* antphi, float* gain,
	float* antpattern, float starttheta, float startphi, float dtheta, float dphi, int thetapoints, int phipoints, long len) {
	int blockSize = 256; // 每个块的线程数
	int numBlocks = (len + blockSize - 1) / blockSize; // 根据 pixelcount 计算网格大小
	//printf("\nCUDA_RTPC_SiglePRF blockSize:%d ,numBlock:%d\n", blockSize, numBlocks);

	CUDA_AntPatternInterpGain << <numBlocks, blockSize >> > ( anttheta,antphi, gain,
		 antpattern, 
		 starttheta,  startphi,  dtheta,  dphi,  thetapoints,  phipoints,
		len);
#ifdef __CUDADEBUG__
	cudaError_t err = cudaGetLastError();
	if (err != cudaSuccess) {
		printf("CUDA_RTPC_SiglePRF CUDA Error: %s\n", cudaGetErrorString(err));
		// Possibly: exit(-1) if program cannot continue....
	}
#endif // __CUDADEBUG__
	cudaDeviceSynchronize();
}
 

extern "C" void calculationEcho(float* sigma0, float* TransAnt, float* ReciveAnt,
	float* localangle, float* R, float* slopeangle,
	float nearRange, float Fs, float pt, float lamda, long FreqIDmax,
	cuComplex* echoAmp, long* FreqID,
	long len)
{
	int blockSize = 256; // 每个块的线程数
	int numBlocks = (len + blockSize - 1) / blockSize; // 根据 pixelcount 计算网格大小
	// 调用 CUDA 核函数
	CUDA_calculationEcho << <numBlocks, blockSize >> > (sigma0, TransAnt, ReciveAnt,
		localangle, R, slopeangle,
		nearRange, Fs, pt, lamda, FreqIDmax,
		echoAmp, FreqID,
		len);
#ifdef __CUDADEBUG__
	cudaError_t err = cudaGetLastError();
	if (err != cudaSuccess) {
		printf("CUDA_RTPC_SiglePRF CUDA Error: %s\n", cudaGetErrorString(err));
		// Possibly: exit(-1) if program cannot continue....
	}
#endif // __CUDADEBUG__
	cudaDeviceSynchronize();
}

extern "C" void CUDACalculationEchoAmp(float* sigma0, float* TransAnt, float* ReciveAnt, float* R, float Pt, float* ampArr, long len)
{

	int blockSize = 256; // 每个块的线程数
	int numBlocks = (len + blockSize - 1) / blockSize; // 根据 pixelcount 计算网格大小
	// 调用 CUDA 核函数
	CUDA_CalculationEchoAmp << <numBlocks, blockSize >> > (
		sigma0, TransAnt, ReciveAnt, R,	Pt, ampArr, len);
#ifdef __CUDADEBUG__
	cudaError_t err = cudaGetLastError();
	if (err != cudaSuccess) {
		printf("CUDA_RTPC_SiglePRF CUDA Error: %s\n", cudaGetErrorString(err));
		// Possibly: exit(-1) if program cannot continue....
	}
#endif // __CUDADEBUG__
	cudaDeviceSynchronize();

}

extern "C" void CUDACalculationEchoPhase(float* R, float lamda, float* phaseArr, long len)
{
	int blockSize = 256; // 每个块的线程数
	int numBlocks = (len + blockSize - 1) / blockSize; // 根据 pixelcount 计算网格大小
	// 调用 CUDA 核函数
	CUDA_CalculationEchoPhase << <numBlocks, blockSize >> > (
		R, lamda, phaseArr, len);
#ifdef __CUDADEBUG__
	cudaError_t err = cudaGetLastError();
	if (err != cudaSuccess) {
		printf("CUDA_RTPC_SiglePRF CUDA Error: %s\n", cudaGetErrorString(err));
		// Possibly: exit(-1) if program cannot continue....
	}
#endif // __CUDADEBUG__
	cudaDeviceSynchronize();


}

extern "C" void CUDACombinationEchoAmpAndPhase(float* R,
	float* echoAmp, float* echoPhase,
	float nearRange, float Fs, long plusepoints, cuComplex* echo, long* FreqID, long len)
{

	int blockSize = 256; // 每个块的线程数
	int numBlocks = (len + blockSize - 1) / blockSize; // 根据 pixelcount 计算网格大小
	// 调用 CUDA 核函数
	CUDA_CombinationEchoAmpAndPhase << <numBlocks, blockSize >> > (
		R, 
		echoAmp, echoPhase,
		nearRange, Fs, plusepoints, echo, FreqID, len
		);
#ifdef __CUDADEBUG__
	cudaError_t err = cudaGetLastError();
	if (err != cudaSuccess) {
		printf("CUDA_RTPC_SiglePRF CUDA Error: %s\n", cudaGetErrorString(err));
		// Possibly: exit(-1) if program cannot continue....
	}
#endif // __CUDADEBUG__
	cudaDeviceSynchronize();

}


extern "C" void CUDAInterpSigma(
	long* demcls,float* sigmaAmp, float* localanglearr,long len,
	CUDASigmaParam* sigma0Paramslist, long sigmaparamslistlen) {// 地表覆盖类型-sigma插值对应函数-ulaby
	int blockSize = 256; // 每个块的线程数
	int numBlocks = (len + blockSize - 1) / blockSize; // 根据 pixelcount 计算网格大小
	// 调用 CUDA 核函数
	CUDA_InterpSigma << <numBlocks, blockSize >> > (
		demcls, sigmaAmp, localanglearr, len,
		sigma0Paramslist, sigmaparamslistlen
		);
#ifdef __CUDADEBUG__
	cudaError_t err = cudaGetLastError();
	if (err != cudaSuccess) {
		printf("CUDA_RTPC_SiglePRF CUDA Error: %s\n", cudaGetErrorString(err));
		// Possibly: exit(-1) if program cannot continue....
	}
#endif // __CUDADEBUG__
	cudaDeviceSynchronize();
}


#endif


