golang fft

19 篇文章 0 订阅

fft

fft函数参数说明:
在这里插入图片描述
参考:https://blog.csdn.net/yga_airspace/article/details/86688278
核心代码:

// 输入初始数据切片pr,切片长度n,在pr上操作,返回fft后的pr
func fft(pr []float64, n int)[]float64{
	k:=int(Floor(Log2(float64(n))))
	var pi =make([]float64,n)
	var fi =make([]float64,n)
	var fr =make([]float64,n)
	var it, m,is,i, j, nv, l0 int
	var p,q,s,vr,vi,poddr,poddi float64
	for it=0; it<=n-1; it++{
		m=it;
		is=0;
		for i=0; i<=k-1; i++{
			j=m/2;
			is=2*is+(m-2*j);
			m=j;
		}
		fr[it]=pr[is];
		fi[it]=pi[is];
	}
	pr[0]=1.0;
	pi[0]=0.0;
	p=2*Pi/float64(n);
	pr[1]=Cos(p); //将w=e^-j2pi/n用欧拉公式表示
	pi[1]=-Sin(p);

	for i=2; i<=n-1; i++{
		p=pr[i-1]*pr[1];
		q=pi[i-1]*pi[1];
		s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);
		pr[i]=p-q; pi[i]=s-p-q;
	}
	for it=0; it<=n-2; it=it+2{
		vr=fr[it];
		vi=fi[it];
		fr[it]=vr+fr[it+1];
		fi[it]=vi+fi[it+1];
		fr[it+1]=vr-fr[it+1];
		fi[it+1]=vi-fi[it+1];
	}
	m=n/2;
	nv=2;
	for l0=k-2; l0>=0; l0--{ //蝴蝶操作
		m=m/2;
		nv=2*nv;
		for it=0; it<=(m-1)*nv; it=it+nv{
			for j = 0; j <= (nv/2)-1; j++{

				p = pr[m*j] * fr[it+j+nv/2]
				q = pi[m*j] * fi[it+j+nv/2]
				s = pr[m*j] + pi[m*j]
				s = s * (fr[it+j+nv/2] + fi[it+j+nv/2])
				poddr = p - q
				poddi = s - p - q
				fr[it+j+nv/2] = fr[it+j] - poddr
				fi[it+j+nv/2] = fi[it+j] - poddi
				fr[it+j] = fr[it+j] + poddr
				fi[it+j] = fi[it+j] + poddi
			}
		}
	}

	for i=0; i<=n-1; i++{
		pr[i]=Sqrt(fr[i]*fr[i]+fi[i]*fi[i]);  //幅值计算
	}
	return pr
}

测试:

package main
import (
	"fmt"
	. "math"
	"time"
)
const n0  =1024
func main(){
	var i int
	var pr,t [n0]float64
	for i=0; i<n0; i++ { //生成输入信号
		t[i] = float64(i)*0.001
		pr[i]=1.2+2.7*Cos(2*Pi*33*t[i])+5*Cos(2*Pi*200*t[i]+Pi/2);

	}

	now :=time.Now()

	fft(pr[0:n0],n0);  //调用FFT函数
	for i=0; i<n0; i++{
		fmt.Printf("%v\t%f\n",i,pr[i]); //输出结果
	}
	fmt.Print(now,"\n",time.Now())
}

应用fft 编写kuiper 的function

stream输入格式

1. 两个参数:前者是double[64],记录输入,后者是int n=64,记录输入个数
2. 一个参数:double[64],记录输入

3. 一个参数:doulbe,当数量达到64是,停止
第二种好一点,第一种多了一个多余的参数,第三种要接收64次。

把数据量改小一点,fft函数,输入 pr:=float64{12},应该是输出31。
所以stream:
type input struct {
	pr []float64
	n int
}

//校验输入格式
func (f *input) Validate(args []interface{}) error{
	if len(args) != 1{
		return fmt.Errorf("echo function only supports 1 parameter but got %d", len(args))
	}
	return nil
}

//处理
func (f *input) Exec(args []interface{}) (interface{}, bool) {
	m :=args[0].(input)
	result :=fft(m.pr,m.n)
	return result,true
}
//是不是xx函数
func (f *input) IsAggregate() bool {
	return false
}
//测试
func main(){
	pr1 := make([]float64,64)
	input1 := input{pr1}
'''
//args是一个包含一个元素的切片,元素是一个input struct,struct包含一个float64数组
	var arg, t [64]float64
	for i:=0; i<64; i++ { //生成输入信号
		t[i] = float64(i)*0.001
		arg[i]=1.2+2.7*Cos(2*Pi*33*t[i])+5*Cos(2*Pi*200*t[i]+Pi/2);

	}
	argtype :=input{arg[0:64]}
	var args []interface{}
	args= append(args,argtype)
'''
	ret,_:=input1.Exec(args)//ret是一个float64数组
	for _,i:= range ret.([]float64){
		println(i)
	}
}

//或者改成如下:
	for _,i:= range ret.(input).pr{//ret是一个结构,包含folat64数组
//对印的E
func (f *input) Exec(args []interface{}) (interface{}, bool) {
	m :=args[0].(input)
	result :=fft(m.pr,len(m.pr))
	output:=input{result}
	return output,true
}
//exec方法返回的是一个空接口,所以返回结构也可以,返回float数组也行。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值