DSPF_dp_qrd_solver_cmplx

**

本博客目的是解释QR分解求解线性方程组(复数形式)的源码

**
一:储备知识
(1)该函数是在完成矩阵QR分解(householder法)的基础之上进行的。
故double *restrict Q和double *restrict R都是已知的,double *restrict b也是已知的(restrict用于 声明只会通过该指针对其指向的内存空间进行读写操作,以便编译器能进行更好的优化。)
(2)共轭转置矩阵
即先取共轭(把虚部取反),后进行转置。
在这里插入图片描述
(有个小错误,应该是4+2i)

(3)复数的有关运算
即复数的乘除法(略)

(4)高斯消元法
高斯消元法详解

简述就是:
将Ax=b按照从上至下、从左至右的顺序化为上三角方程组,中间过程不对矩阵进行交换。
(存在的限制详见上述博客)

由刘学长提供

二:过程简述

在这里插入图片描述
在这里插入图片描述
谭博宇同学的QR分解求解线性方程组(实数形式)
三:源码解释

(1):求y(y=Q*b)

//(restrict用于 声明只会通过该指针对其指向的内存空间进行读写操作,以便编译器能进行更好的优化。)
int DSPF_dp_qrd_solver_cmplx(const int Nrows,const int Ncols,double *restrict Q,double *restrict R,double *restrict b,double *restrict y,double *restrict x) {

  short row,col,loop_cnt,Nrows2,Ncols2;//
  double xreal,ximag,yreal,yimag,zreal,zimag,sum_real,sum_imag;
//  _nassert():简单判断
  _nassert(Nrows>0);
  _nassert(Ncols>0);
  _nassert((int)Q % 8 == 0);
  _nassert((int)R % 8 == 0);
  _nassert((int)b % 8 == 0);
  _nassert((int)y % 8 == 0);
  _nassert((int)x % 8 == 0);
  //第一步:求y
  /* generate y=Q'*b */
  Nrows2=2*Nrows;//存实部和虚部
  Ncols2=2*Ncols;
//把#pragma MUST_ITERATE(, , )放在循环体之前,告知开发板循环次数,改善软件流水
//MUST_ITERATE告诉编译器循环的属性,但是这些属性必须是真实的,不然程序可能运行出错。此指令主要用于优化C函数循环,一般情况下,只要有循环都最好带上此指令
//
//#pragma MUST_ITERATE(min, max, multiple);其中multiple参数必须有,循环执行次数必是multiple的整数倍。
//这个信息对编译器使用软件流水技术非常重要
#pragma MUST_ITERATE(1,,)
  for (row=0;row<Nrows;row++) {
	sum_real=0;
	sum_imag=0;
#pragma MUST_ITERATE(1,,)
	for (col=0;col<Nrows;col++) 
  {
	  xreal= Q[2*row  +col*Nrows2];
	  ximag=-Q[2*row+1+col*Nrows2];
	  yreal=b[2*col  ];
	  yimag=b[2*col+1];
	  sum_real+=xreal*yreal-ximag*yimag;
	  sum_imag+=xreal*yimag+ximag*yreal;
	}
	y[2*row  ]=sum_real;
	y[2*row+1]=sum_imag;
  }

(2):求x(高斯消元法)

这部分和实数形式如出一辙,看代码就很好理解
complex_dp_div函数也就是进行复数的除法运算

/* use backward substitution to solve x=inv(R)*y */


//loop_cnt取两者较小值
//但是如果Nrows小的话说明可能有无穷多解那么就把(Ncols-Nrows)这几个多出来的x值取0就行了
  if (Nrows>=Ncols) 
  	loop_cnt=Ncols;
  else             
  	loop_cnt=Nrows;
  	
   //memset():常用于较大的对结构体或数组的清零操作。
  memset(x,0,sizeof(double)*Ncols2);
  
#pragma MUST_ITERATE(1,,)
  for (row=loop_cnt-1;row>=0;row--)
   {
	sum_real=0;
	sum_imag=0;
#pragma MUST_ITERATE(1,,)
	for (col=row+1;col<loop_cnt;col++)
	 {
	  xreal=R[2*col  +row*Ncols2];
	  ximag=R[2*col+1+row*Ncols2];
	  yreal=x[2*col  ];
	  yimag=x[2*col+1];
	  //当然一开始sum_real,sum_imag都为零,后面求出xn_real,xn_imag的值了便不为零(理解高斯消元法就很方便了)
	  sum_real+=xreal*yreal-ximag*yimag;
	  sum_imag+=xreal*yimag+ximag*yreal;
	}
	xreal=y[2*row  ]-sum_real;
	ximag=y[2*row+1]-sum_imag;
	yreal=R[2*row  +row*2*Ncols];
	yimag=R[2*row+1+row*2*Ncols];
	//复数的除法运算
	complex_dp_div(xreal,ximag,yreal,yimag,&zreal,&zimag);
	x[2*row  ]=zreal;
	x[2*row+1]=zimag;
  }

  return 0;
}
static void complex_dp_div(double x_real,double x_imag,double y_real,double y_imag,double *z_real,double *z_imag) 
{
//#define ENABLE_NR 1
//条件编译的用法:略
  double inv_mag_sq;
#ifdef ENABLE_NR
  double x,y;
#endif
#ifndef ENABLE_NR
  inv_mag_sq=1/(y_real*y_real+y_imag*y_imag);
#else
  x=y_real*y_real+y_imag*y_imag;
  y=_rcpdp(x);//取倒数
  //多次操作用以提高精度(项目对精度要求很高)
  y=y*(2.0-x*y);
  y=y*(2.0-x*y);
  y=y*(2.0-x*y);
  inv_mag_sq=y;
#endif
  *z_real=(x_real*y_real+x_imag*y_imag)*inv_mag_sq;
  *z_imag=(x_imag*y_real-x_real*y_imag)*inv_mag_sq;

}

下面举个小李子:
在这里插入图片描述

①:

sum_real=0;
	sum_imag=0;
#pragma MUST_ITERATE(1,,)
	for (col=row+1;col<loop_cnt;col++)
	 {
	  xreal=R[2*col  +row*Ncols2];
	  ximag=R[2*col+1+row*Ncols2];
	  yreal=x[2*col  ];
	  yimag=x[2*col+1];
	  //当然一开始sum_real,sum_imag都为零,后面求出xn_real,xn_imag的值了便不为零(理解高斯消元法就很方便了)
	  sum_real+=xreal*yreal-ximag*yimag;
	  sum_imag+=xreal*yimag+ximag*yreal;

②:

xreal=y[2*row  ]-sum_real;
ximag=y[2*row+1]-sum_imag;

③:

complex_dp_div(xreal,ximag,yreal,yimag,&zreal,&zimag);
	x[2*row  ]=zreal;
	x[2*row+1]=zimag;
### 回答1: dspf_sp_fftspxsp是一种用于信号处理的算法,主要用于实现FFT(快速傅里叶变换)。FFT是一种将时域信号转换为频域信号的算法,它能够对信号进行频谱分析和频域处理。这种算法可以应用于很多领域,如音频处理、图像处理、通信系统等。 dspf_sp_fftspxsp算法是一种优化后的FFT算法,它使用了一系列高效的技术和优化策略,能够在较短的时间内完成FFT运算。它具有高计算速度、低延迟和较少的内存消耗等特点,适用于实时信号处理和高性能计算任务。 在算法实现方面,dspf_sp_fftspxsp使用了特殊的数据结构和计算模式,能够充分利用现代CPU和并行计算架构的优势。它可以在多核处理器上并行运行,提高计算效率和吞吐量。 dspf_sp_fftspxsp还具有很好的可扩展性和灵活性。它可以与其他信号处理算法结合使用,如滤波、调制解调、信号生成等。同时,它还支持不同的采样率和信号长度,适应不同应用场景的需求。 总的来说,dspf_sp_fftspxsp是一种高效、快速的FFT实现算法,能够帮助我们在信号处理领域进行准确、实时的频域分析和处理。它在很多应用中发挥着重要的作用,为我们提供了更好的信号处理解决方案。 ### 回答2: "dfs_sp_fftspxsp"是一个计算器,用于计算两个频谱相乘的结果。其中"dspf"表示待处理的频谱,"sp"表示频谱,"fftspxsp"表示进行快速傅里叶变换的频谱相乘。 在信号处理中,频谱是信号在频率域上的表示。傅里叶变换是一种将信号从时域转换到频域的方法。相乘是在频域上进行的运算,可以用于滤波、卷积等信号处理任务。 "dspf_sp_fftspxsp"的作用是将输入的两个频谱相乘,得到它们的乘积。这个过程通过快速傅里叶变换来实现,以提高计算效率。 使用"dspf_sp_fftspxsp",可以通过输入两个频谱,然后调用该函数来获得它们的乘积的频谱。这个结果可以进一步用于其他信号处理任务,如滤波器设计、频谱分析等。 总之,"dspf_sp_fftspxsp"是一个用于计算两个频谱相乘的函数,它使用快速傅里叶变换来提高计算效率。通过使用该函数,可以方便地进行频域信号处理任务。 ### 回答3: dspf_sp_fftspxsp是一个用于实现快速傅里叶变换(FFT)的函数。其中,dspf代表“digital signal processing function”(数字信号处理函数),sp代表“single precision”(单精度),fftspxsp代表“Fast Fourier Transform SP X SP”(单精度FFT)。这个函数可以在单精度的数据上进行FFT运算。 FFT是一种用于将信号从时域转换到频域的算法。在数字信号处理中,FFT通常用于信号分析、频谱估计、信号压缩等应用。通过计算离散傅里叶变换(DFT),FFT可以高效地计算出信号的频谱信息。 dspf_sp_fftspxsp函数利用了快速傅里叶变换算法的优势,可以在较短的时间内完成FFT运算。该函数接受单精度的输入数据,并返回相应的FFT结果。除了计算FFT之外,这个函数还可以执行相关的额外操作,例如零填充、频谱平滑等。 使用dspf_sp_fftspxsp函数时,我们需要先准备好输入数据,然后将其传递给函数函数会根据输入数据的长度进行相应的运算,并生成FFT结果。生成的结果可以供我们进一步分析和处理。 总之,dspf_sp_fftspxsp是一个实现了单精度FFT运算的函数,可以在数字信号处理中广泛应用。它可以高效地计算出信号的频谱信息,帮助我们进行信号分析和处理。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值