📄 form1.java
字号:
MessageBox.show("计算结果:滤波器阶数N="+String.valueOf(rankx)+",截止频率Ωc="+String.valueOf(Qcx)+"。而本程序允许的最大阶数是"+String.valueOf(rankMAX)+",最小阶数为2,你的输入不在此范围!"+'\n'+"对不起,请重试!","提示",MessageBox.ICONINFORMATION);
}
else if(rank<=rankMAX){//阶数是允许的,则画出极点分布图
rank=rankx;//合格!接受此值
Qc=Qcx;
MessageBox.show("计算结果:滤波器阶数N="+String.valueOf(rank)+",截止频率Ωc="+String.valueOf(Qc)+'\n'+"祝贺你,滤波器参数初始化成功!","提示",MessageBox.ICONINFORMATION);
//求出极点位置
P=new complex[rank];
K0=1;//归一化常数
for(int i=0;i<rank;i++){
P[i]=new complex();
P[i].Re=-Qc*this.sh(this.arsh(1/omiga)/(double)rank)*Math.sin((2*i+1)*Math.PI/2/(double)rank);
P[i].Im=Qc*this.ch(this.arsh(1/omiga)/(double)rank)*Math.cos((2*i+1)*Math.PI/2/(double)rank);
//System.out.println("P["+i+"]=("+P[i].Re+")+("+P[i].Im+")");
K0*=Math.sqrt(P[i].Re*P[i].Re+P[i].Im*P[i].Im);
}
K0/=Math.sqrt(1+omiga*omiga);
//System.out.println("归一化常数K0="+K0+"");
//求得部分分式表达式的各项分解系数
A=new complex[rank];
complex aa=new complex();
complex bb=new complex();
complex cc=new complex();
for(int i=0;i<rank;i++){
A[i]=new complex();
aa.Re=1;aa.Im=0;//aa=1
for(int j=0;j<rank;j++){
if(i!=j){
bb=this.complexsub(P[i],P[j]);
aa=this.complexmult(aa,bb);
}
}//for int j
cc.Re=K0;cc.Im=0;
A[i]=this.complexdiv(cc,aa);//求倒数
//System.out.println("A["+i+"]=("+A[i].Re+")+("+A[i].Im+")");
}//for int i
//已经求得求得部分分式表达式的各项分解系数A[i]!
//根据分解系数A【i】和极点P【i】求出标准差分方程的系数Br【】和Ak【】
complex H[]=new complex[rank+1];
for(int i=0;i<=rank;i++)H[i]=new complex();
H[0].Re=1;H[0].Im=0;
complex aaa=new complex();
for(int j=0;j<rank;j++){
//aaa.Re=-Math.exp(P[j].Re)*Math.cos(P[j].Im);
//aaa.Im=-Math.exp(P[j].Re)*Math.sin(P[j].Im);
aaa.Re=((P[j].Re+2)*(P[j].Re-2)+(P[j].Im*P[j].Im))/((P[j].Re-2)*(P[j].Re-2)+P[j].Im*P[j].Im);
aaa.Im=(-P[j].Im*(P[j].Re+2)+P[j].Im*(P[j].Re-2))/((P[j].Re-2)*(P[j].Re-2)+P[j].Im*P[j].Im);
for(int i=rank;i>=1;i--){
H[i].Re+=aaa.Re*H[i-1].Re-aaa.Im*H[i-1].Im;
H[i].Im+=aaa.Re*H[i-1].Im+aaa.Im*H[i-1].Re;
}//for i
}//for j
//此时已经得到的系数Ak【】存在H【】的序号从1到rank的地方
//存入Ak【】
Ak=new complex[rank];
for(int i=0;i<rank;i++){
Ak[i]=new complex();
Ak[i].Re=H[i+1].Re;
Ak[i].Im=H[i+1].Im;
//System.out.println("Ak["+i+"]=("+Ak[i].Re+")+("+Ak[i].Im+")");
}
//初始化Br【】
Br=new complex[rank];
for(int i=0;i<rank;i++) Br[i]=new complex();
//此时已经定义的H【】和aaa可以拿来做缓存
for(int k=0;k<rank;k++){
for(int i=0;i<=rank;i++){H[i].Re=0;H[i].Im=0;}
H[0].Re=1;
aaa.Re=0;aaa.Im=0;
for(int j=0;j<rank;j++){
if(j!=k){
//aaa.Re=-Math.exp(P[j].Re)*Math.cos(P[j].Im);
//aaa.Im=-Math.exp(P[j].Re)*Math.sin(P[j].Im);
aaa.Re=((P[j].Re+2)*(P[j].Re-2)+(P[j].Im*P[j].Im))/((P[j].Re-2)*(P[j].Re-2)+P[j].Im*P[j].Im);
aaa.Im=(-P[j].Im*(P[j].Re+2)+P[j].Im*(P[j].Re-2))/((P[j].Re-2)*(P[j].Re-2)+P[j].Im*P[j].Im);
}
if(j==k){
aaa.Re=0;
aaa.Im=0;
}
for(int i=rank;i>=1;i--){
H[i].Re+=aaa.Re*H[i-1].Re-aaa.Im*H[i-1].Im;
H[i].Im+=aaa.Re*H[i-1].Im+aaa.Im*H[i-1].Re;
}//for i
}//for j
for(int j=0;j<=rank;j++){//得到的每一项都还要乘上一个常数A[k]/(2-P[k])
double hre=H[j].Re;
double him=H[j].Im;
H[j].Re=hre*(A[k].Re*(2-P[k].Re)-A[k].Im*P[k].Im)/((2-P[k].Re)*(2-P[k].Re)+P[k].Im*P[k].Im)-him*(A[k].Re*P[k].Im+A[k].Im*(2-P[k].Re))/((2-P[k].Re)*(2-P[k].Re)+P[k].Im*P[k].Im);
H[j].Im=hre*(A[k].Re*P[k].Im+A[k].Im*(2-P[k].Re))/((2-P[k].Re)*(2-P[k].Re)+P[k].Im*P[k].Im)+him*(A[k].Re*(2-P[k].Re)-A[k].Im*P[k].Im)/((2-P[k].Re)*(2-P[k].Re)+P[k].Im*P[k].Im);
}
for(int i=0;i<rank;i++) {//Br[0]为常数项;注意!Ak[0]为1/Z项系数
Br[i].Re+=H[i].Re;
Br[i].Im+=H[i].Im;
}
}//for k
for(int i=rank-1;i>0;i--){
Br[i].Re+=Br[i-1].Re;
Br[i].Im+=Br[i-1].Im;
}
//此时就得到了确定差分方程必须的系数Ak【】和Br【】!
//至于处理输出结果的事情,就留到要显示输出序列y【】时去处理
//准备画极点
Yinputed=true;//标志:滤波器已经初始化!
solved=false;
this.displaywhichdata=5;
this.label1.setText("当前显示数据:巴特渥斯滤波器在S平面的极点位置");
this.label3.setText("");
this.currentlabel.setText("");
this.scroll.setEnabled(false);
this.panel.invalidate();
}//else if
}//result=ok
}
private void menuItem3_click(Object source, Event e)
{
if(this.displaywhichdata==-1){
MessageBox.show("当前没有任何显示数据可供查询!","提示",MessageBox.ICONINFORMATION);
}
else if(this.displaywhichdata==0||this.displaywhichdata==2||this.displaywhichdata==5||this.displaywhichdata==6||this.displaywhichdata==7){
query q=new query();
if(this.displaywhichdata==5){//极点
q.fromscroll.setMaximum(this.rank);
q.toscroll.setMaximum(this.rank);
q.trackBar1.setMaximum(this.rank);
q.lengthlabel.setText(String.valueOf(this.rank));
}
else{
q.fromscroll.setMaximum(this.totallength);
q.toscroll.setMaximum(this.totallength);
q.trackBar1.setMaximum(this.totallength);
q.lengthlabel.setText(String.valueOf(this.totallength));
}
int result=q.showDialog();
if(result==DialogResult.OK){
int startt=1,endd=1;
if(q.queryall.getChecked()){//query all!
startt=1;
endd=q.fromscroll.getMaximum();
}
if(q.querypart.getChecked()){
startt=q.fromscroll.getValue();
endd=q.toscroll.getValue();
}
if(q.queryone.getChecked()){
startt=q.trackBar1.getValue();
endd=startt;
}
datareader dd=new datareader();
switch(this.displaywhichdata){
case 0:
dd.setText("查询输入序列x[]");
for(int i=startt;i<=endd;i++){
dd.listBox1.addItem("x["+i+"]="+String.valueOf(x[i]));
}
break;
case 2:
dd.setText("查询输出序列y[]");
for(int i=startt;i<=endd;i++){
dd.listBox1.addItem("y["+i+"]="+String.valueOf(y[i-1]));
}
break;
case 5:
dd.setText("查询滤波器极点位置");
for(int i=startt;i<=endd;i++){
dd.listBox1.addItem("S"+i+"="+String.valueOf(P[i-1].Re)+((P[i-1].Im>0)?"+j":"-j")+String.valueOf(Math.abs(P[i-1].Im)));
}
break;
case 6:
dd.setText("查询输入序列频谱X[]");
for(int i=startt;i<=endd;i++){
dd.listBox1.addItem("X["+i+"]="+String.valueOf(Math.sqrt(X[i].Re*X[i].Re+X[i].Im*X[i].Im)));
}
break;
case 7:
dd.setText("查询输出序列频谱Y[]");
for(int i=startt;i<=endd;i++){
dd.listBox1.addItem("Y["+i+"]="+String.valueOf(Math.sqrt(X[i].Re*X[i].Re+X[i].Im*X[i].Im)));
}
break;
}
dd.showDialog();
}
}
}
private void menuItem19_click(Object source, Event e)
{
if(Xinputed==false){//如果尚未定义x【】
MessageBox.show("你尚未定义输入序列x[]!\n请你点击“初始化”菜单命令,定义此输入序列。","警告!",MessageBox.OK+MessageBox.ICONWARNING);
}
else{//如果已经定义x【】
this.N=this.getN(x.length-1);
X=new complex[N+1];
for(int i=1;i<X.length;i++){
X[i]=new complex();
if(i<x.length){
X[i].Re=x[i];
}
}
fft();
this.displaywhichdata=6;
this.totallength=X.length-1;
this.label1.setText("当前显示数据:输入序列频谱X[]");
this.label3.setText("数据总长度:"+this.totallength+"");
this.steppelix=2;
//this.ysize=100;
this.scroll.setValue(0);
this.current=0;
double Ymax=Math.sqrt(X[1].Re*X[1].Re+X[1].Im*X[1].Im);
for(int i=2;i<=this.totallength;i++)
if(Math.sqrt(X[i].Re*X[i].Re+X[i].Im*X[i].Im)>Ymax) Ymax=Math.sqrt(X[i].Re*X[i].Re+X[i].Im*X[i].Im);//得到序列y[]中的最大绝对值
if(Ymax!=0)
this.ysize=(this.panel.getHeight()/2-5)/Ymax;
panel.invalidate();
}
}
private void menuItem20_click(Object source, Event e)
{
if(Xinputed==false){//如果尚未定义x[]
MessageBox.show("你尚未定义输入序列x[]!\n请你点击“初始化”菜单命令,定义输入序列。","警告!",MessageBox.OK+MessageBox.ICONWARNING);
}
if(Yinputed==false){//如果尚未定义滤波器特性
MessageBox.show("你尚未定义滤波器特性!\n请你点击“初始化”菜单命令,设置数字滤波器的参数。","警告!",MessageBox.OK+MessageBox.ICONWARNING);
}
if(Xinputed&Yinputed){//如果已经定义x[]以及滤波器参数(设置滤波器参数完成时就已经得到了h[])
if(solved==false){//如果已经定义,但是没有处理
y=new double[this.MaxLength];
for(int n=0;n<y.length;n++){
for(int r=0;r<rank-1;r++){
if(n+1-r>0&&n+1-r<=x.length-1)y[n]-=Br[r].Re*(-x[n+1-r]);
}//for int r
for(int k=1;k<=rank;k++){
if(n-k>=0&&n-k<=y.length-1)y[n]-=y[n-k]*Ak[k-1].Re;
}//for int k
}//差分方程结束!
solved=true;//处理完成!
}//solved=false
this.N=this.getN(y.length);
X=new complex[N+1];
for(int i=1;i<X.length;i++){
X[i]=new complex();
if(i<=y.length){
X[i].Re=y[i-1];
}
}
fft();
this.displaywhichdata=6;
this.totallength=X.length-1;
this.label1.setText("当前显示数据:输出序列频谱Y[]");
this.label3.setText("数据总长度:"+this.totallength+"");
this.steppelix=2;
//this.ysize=100;
this.scroll.setValue(0);
this.current=0;
double Ymax=Math.sqrt(X[1].Re*X[1].Re+X[1].Im*X[1].Im);
for(int i=2;i<=this.totallength;i++)
if(Math.sqrt(X[i].Re*X[i].Re+X[i].Im*X[i].Im)>Ymax) Ymax=Math.sqrt(X[i].Re*X[i].Re+X[i].Im*X[i].Im);//得到序列y[]中的最大绝对值
if(Ymax!=0)
this.ysize=(this.panel.getHeight()/2-5)/Ymax;
panel.invalidate();
}//Xinputed&Yinputed
}
private void panel_mouseMove(Object source, MouseEvent e)
{
if(this.displaywhichdata==3&&e.x>=40&&e.x<=this.panel.getWidth()-10){
double xx=K0;
double w=(double)(e.x-40)/(double)(this.panel.getWidth()-50)*Math.PI;
for(int i=0;i<P.length;i++)
xx/=Math.sqrt(P[i].Re*P[i].Re+(w-P[i].Im)*(w-P[i].Im));
xx=10*Math.log(xx);
this.timelabel.setText("ω="+String.valueOf((float)(e.x-40)/(float)(this.panel.getWidth()-50))+"π,Hdb(ω)="+xx+"dB");
}
if(this.displaywhichdata==4&&e.x>=40&&e.x<=this.panel.getWidth()-10){
double xx=0;
double w=(double)(e.x-40)/(double)(this.panel.getWidth()-50)*Math.PI;
for(int i=0;i<P.length;i++)
xx-=Math.atan((w-P[i].Im)/(-P[i].Re));
while(xx<-Math.PI)xx+=2*Math.PI;
this.timelabel.setText("ω="+String.valueOf((float)(e.x-40)/(float)(this.panel.getWidth()-50))+"π,Ф(ω)="+xx/Math.PI*180+"°");
}
}
Container components = new Container();
MenuItem menuxstepadd = new MenuItem();
MenuItem menudrawway = new MenuItem();
MenuItem menuexit = new MenuItem();
MainMenu mainMenu1 = new MainMenu();
MenuItem menuItem10 = new MenuItem();
MenuItem menuItem13 = new MenuItem();
MenuItem menuItem2 = new MenuItem();
MenuItem menu = new MenuItem();
MenuItem menuItem14 = new MenuItem();
MenuItem menuItem6 = new MenuItem();
MenuItem menuItem12 = new MenuItem();
MenuItem menuItem11 = new MenuItem();
MenuItem inputXfromfile = new MenuItem();
MenuItem menuxstep = new MenuItem();
MenuItem menuxstepsub = new MenuItem();
MenuItem menusavefile = new MenuItem();
MenuItem menuItem9 = new MenuItem();
MenuItem menuItem8 = new MenuItem();
MenuItem menuItem7 = new MenuItem();
Panel panel = new Panel();
HScrollBar scroll = new HScrollBar();
Label currentlabel = new Label();
Label lastlabel = new Label();
MenuItem menushow = new MenuItem();
MenuItem menushowX = new MenuItem();
StatusBarPanel statusBarPanel1 = new StatusBarPanel();
Label label1 = new Label();
MenuItem menuItem1 = new MenuItem();
StatusBarPanel statusBarPanel2 = new StatusBarPanel();
StatusBarPanel statusBarPanel3 = new StatusBarPanel();
StatusBarPanel statusBarPanel4 = new StatusBarPanel();
StatusBarPanel statusBarPanel5 = new StatusBarPanel();
StatusBarPanel statusBarPanel6 = new StatusBarPanel();
StatusBarPanel statusBarPanel7 = new StatusBarPanel();
Label timelabel = new Label();
Label label3 = new Label();
MenuItem menuxstepdefault = new MenuItem();
MenuItem menuysize = new MenuItem();
MenuItem menuysizeadd = new MenuItem();
MenuItem menuysizesub = new MenuItem();
MenuItem menuysizedefault = new MenuItem();
MenuItem menuysizemax = new MenuItem();
MenuItem menushowH = new MenuItem();
MenuItem menuinputX = new MenuItem();
MenuItem inputXdefault = new MenuItem();
MenuItem inputXonebyone = new MenuItem();
MenuItem menuItem4 = new MenuItem();
MenuItem menuItem5 = new MenuItem();
MenuItem menuItem15 = new MenuItem();
MenuItem menuItem16 = new MenuItem();
MenuItem menuItem3 = new MenuItem();
MenuItem menuItem17 = new MenuItem();
MenuItem menuItem18 = new MenuItem();
MenuItem menuItem19 = new MenuItem();
MenuItem menuItem20 = new MenuItem();
ContextMenu contextMenu1 = new ContextMenu();
MenuItem menuItem36 = new MenuItem();
MenuItem menuItem35 = new MenuItem();
MenuItem menuItem34 = new MenuItem();
MenuItem menuItem33 = new MenuItem();
MenuItem menuItem32 = new MenuItem();
MenuItem menuItem31 = new MenuItem();
MenuItem menuItem30 = new MenuItem();
MenuItem menuItem29 = new MenuItem();
MenuItem menuItem28 = new MenuItem();
MenuItem menuItem27 = new MenuItem();
MenuItem menuItem26 = new MenuItem();
MenuItem menuItem25 = new MenuItem();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -