Java实现的傅里叶变化算法示例

2025-05-29 0 69

本文实例讲述了java实现的傅里叶变化算法。分享给大家供大家参考,具体如下:

用java实现傅里叶变化 结果为复数形式 a+bi

废话不多说,实现代码如下,共两个class

fft.class 傅里叶变化功能实现代码

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237
package fft.test;

/*************************************************************************

* compilation: javac fft.java execution: java fft n dependencies: complex.java

*

* compute the fft and inverse fft of a length n complex sequence. bare bones

* implementation that runs in o(n log n) time. our goal is to optimize the

* clarity of the code, rather than performance.

*

* limitations ----------- - assumes n is a power of 2

*

* - not the most memory efficient algorithm (because it uses an object type for

* representing complex numbers and because it re-allocates memory for the

* subarray, instead of doing in-place or reusing a single temporary array)

*

*************************************************************************/

public class fft {

// compute the fft of x[], assuming its length is a power of 2

public static complex[] fft(complex[] x) {

int n = x.length;

// base case

if (n == 1)

return new complex[] { x[0] };

// radix 2 cooley-tukey fft

if (n % 2 != 0) {

throw new runtimeexception("n is not a power of 2");

}

// fft of even terms

complex[] even = new complex[n / 2];

for (int k = 0; k < n / 2; k++) {

even[k] = x[2 * k];

}

complex[] q = fft(even);

// fft of odd terms

complex[] odd = even; // reuse the array

for (int k = 0; k < n / 2; k++) {

odd[k] = x[2 * k + 1];

}

complex[] r = fft(odd);

// combine

complex[] y = new complex[n];

for (int k = 0; k < n / 2; k++) {

double kth = -2 * k * math.pi / n;

complex wk = new complex(math.cos(kth), math.sin(kth));

y[k] = q[k].plus(wk.times(r[k]));

y[k + n / 2] = q[k].minus(wk.times(r[k]));

}

return y;

}

// compute the inverse fft of x[], assuming its length is a power of 2

public static complex[] ifft(complex[] x) {

int n = x.length;

complex[] y = new complex[n];

// take conjugate

for (int i = 0; i < n; i++) {

y[i] = x[i].conjugate();

}

// compute forward fft

y = fft(y);

// take conjugate again

for (int i = 0; i < n; i++) {

y[i] = y[i].conjugate();

}

// divide by n

for (int i = 0; i < n; i++) {

y[i] = y[i].scale(1.0 / n);

}

return y;

}

// compute the circular convolution of x and y

public static complex[] cconvolve(complex[] x, complex[] y) {

// should probably pad x and y with 0s so that they have same length

// and are powers of 2

if (x.length != y.length) {

throw new runtimeexception("dimensions don't agree");

}

int n = x.length;

// compute fft of each sequence,求值

complex[] a = fft(x);

complex[] b = fft(y);

// point-wise multiply,点值乘法

complex[] c = new complex[n];

for (int i = 0; i < n; i++) {

c[i] = a[i].times(b[i]);

}

// compute inverse fft,插值

return ifft(c);

}

// compute the linear convolution of x and y

public static complex[] convolve(complex[] x, complex[] y) {

complex zero = new complex(0, 0);

complex[] a = new complex[2 * x.length];// 2n次数界,高阶系数为0.

for (int i = 0; i < x.length; i++)

a[i] = x[i];

for (int i = x.length; i < 2 * x.length; i++)

a[i] = zero;

complex[] b = new complex[2 * y.length];

for (int i = 0; i < y.length; i++)

b[i] = y[i];

for (int i = y.length; i < 2 * y.length; i++)

b[i] = zero;

return cconvolve(a, b);

}

// display an array of complex numbers to standard output

public static void show(complex[] x, string title) {

system.out.println(title);

system.out.println("-------------------");

int complexlength = x.length;

for (int i = 0; i < complexlength; i++) {

// 输出复数

// system.out.println(x[i]);

// 输出幅值需要 * 2 / length

system.out.println(x[i].abs() * 2 / complexlength);

}

system.out.println();

}

/**

* 将数组数据重组成2的幂次方输出

*

* @param data

* @return

*/

public static double[] pow2doublearr(double[] data) {

// 创建新数组

double[] newdata = null;

int datalength = data.length;

int sumnum = 2;

while (sumnum < datalength) {

sumnum = sumnum * 2;

}

int addlength = sumnum - datalength;

if (addlength != 0) {

newdata = new double[sumnum];

system.arraycopy(data, 0, newdata, 0, datalength);

for (int i = datalength; i < sumnum; i++) {

newdata[i] = 0d;

}

} else {

newdata = data;

}

return newdata;

}

/**

* 去偏移量

*

* @param originalarr

* 原数组

* @return 目标数组

*/

public static double[] deskew(double[] originalarr) {

// 过滤不正确的参数

if (originalarr == null || originalarr.length <= 0) {

return null;

}

// 定义目标数组

double[] resarr = new double[originalarr.length];

// 求数组总和

double sum = 0d;

for (int i = 0; i < originalarr.length; i++) {

sum += originalarr[i];

}

// 求数组平均值

double aver = sum / originalarr.length;

// 去除偏移值

for (int i = 0; i < originalarr.length; i++) {

resarr[i] = originalarr[i] - aver;

}

return resarr;

}

public static void main(string[] args) {

// int n = integer.parseint(args[0]);

double[] data = { -0.35668879080953375, -0.6118094913035987, 0.8534269560320435, -0.6699697478438837, 0.35425500561437717,

0.8910250650549392, -0.025718699518642918, 0.07649691490732002 };

// 去除偏移量

data = deskew(data);

// 个数为2的幂次方

data = pow2doublearr(data);

int n = data.length;

system.out.println(n + "数组n中数量....");

complex[] x = new complex[n];

// original data

for (int i = 0; i < n; i++) {

// x[i] = new complex(i, 0);

// x[i] = new complex(-2 * math.random() + 1, 0);

x[i] = new complex(data[i], 0);

}

show(x, "x");

// fft of original data

complex[] y = fft(x);

show(y, "y = fft(x)");

// take inverse fft

complex[] z = ifft(y);

show(z, "z = ifft(y)");

// circular convolution of x with itself

complex[] c = cconvolve(x, x);

show(c, "c = cconvolve(x, x)");

// linear convolution of x with itself

complex[] d = convolve(x, x);

show(d, "d = convolve(x, x)");

}

}

/*********************************************************************

* % java fft 8 x ------------------- -0.35668879080953375 -0.6118094913035987

* 0.8534269560320435 -0.6699697478438837 0.35425500561437717 0.8910250650549392

* -0.025718699518642918 0.07649691490732002

*

* y = fft(x) ------------------- 0.5110172121330208 -1.245776663065442 +

* 0.7113504894129803i -0.8301420417085572 - 0.8726884066879042i

* -0.17611092978238008 + 2.4696418005143532i 1.1395317305034673

* -0.17611092978237974 - 2.4696418005143532i -0.8301420417085572 +

* 0.8726884066879042i -1.2457766630654419 - 0.7113504894129803i

*

* z = ifft(y) ------------------- -0.35668879080953375 -0.6118094913035987 +

* 4.2151962932466006e-17i 0.8534269560320435 - 2.691607282636124e-17i

* -0.6699697478438837 + 4.1114763914420734e-17i 0.35425500561437717

* 0.8910250650549392 - 6.887033953004965e-17i -0.025718699518642918 +

* 2.691607282636124e-17i 0.07649691490732002 - 1.4396387316837096e-17i

*

* c = cconvolve(x, x) ------------------- -1.0786973139009466 -

* 2.636779683484747e-16i 1.2327819138980782 + 2.2180047699856214e-17i

* 0.4386976685553382 - 1.3815636262919812e-17i -0.5579612069781844 +

* 1.9986455722517509e-16i 1.432390480003344 + 2.636779683484747e-16i

* -2.2165857430333684 + 2.2180047699856214e-17i -0.01255525669751989 +

* 1.3815636262919812e-17i 1.0230680492494633 - 2.4422465262488753e-16i

*

* d = convolve(x, x) ------------------- 0.12722689348916738 +

* 3.469446951953614e-17i 0.43645117531775324 - 2.78776395788635e-18i

* -0.2345048043334932 - 6.907818131459906e-18i -0.5663280251946803 +

* 5.829891518914417e-17i 1.2954076913348198 + 1.518836016779236e-16i

* -2.212650940696159 + 1.1090023849928107e-17i -0.018407034687857718 -

* 1.1306778366296569e-17i 1.023068049249463 - 9.435675069681485e-17i

* -1.205924207390114 - 2.983724378680108e-16i 0.796330738580325 +

* 2.4967811657742562e-17i 0.6732024728888314 - 6.907818131459906e-18i

* 0.00836681821649593 + 1.4156564203603091e-16i 0.1369827886685242 +

* 1.1179436667055108e-16i -0.00393480233720922 + 1.1090023849928107e-17i

* 0.005851777990337828 + 2.512241462921638e-17i 1.1102230246251565e-16 -

* 1.4986790192807268e-16i

*********************************************************************/

complex.class 复数类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158
package fft.test;

/******************************************************************************

* compilation: javac complex.java

* execution: java complex

*

* data type for complex numbers.

*

* the data type is "immutable" so once you create and initialize

* a complex object, you cannot change it. the "final" keyword

* when declaring re and im enforces this rule, making it a

* compile-time error to change the .re or .im instance variables after

* they've been initialized.

*

* % java complex

* a = 5.0 + 6.0i

* b = -3.0 + 4.0i

* re(a) = 5.0

* im(a) = 6.0

* b + a = 2.0 + 10.0i

* a - b = 8.0 + 2.0i

* a * b = -39.0 + 2.0i

* b * a = -39.0 + 2.0i

* a / b = 0.36 - 1.52i

* (a / b) * b = 5.0 + 6.0i

* conj(a) = 5.0 - 6.0i

* |a| = 7.810249675906654

* tan(a) = -6.685231390246571e-6 + 1.0000103108981198i

*

******************************************************************************/

import java.util.objects;

public class complex {

private final double re; // the real part

private final double im; // the imaginary part

// create a new object with the given real and imaginary parts

public complex(double real, double imag) {

re = real;

im = imag;

}

// return a string representation of the invoking complex object

public string tostring() {

if (im == 0)

return re + "";

if (re == 0)

return im + "i";

if (im < 0)

return re + " - " + (-im) + "i";

return re + " + " + im + "i";

}

// return abs/modulus/magnitude

public double abs() {

return math.hypot(re, im);

}

// return angle/phase/argument, normalized to be between -pi and pi

public double phase() {

return math.atan2(im, re);

}

// return a new complex object whose value is (this + b)

public complex plus(complex b) {

complex a = this; // invoking object

double real = a.re + b.re;

double imag = a.im + b.im;

return new complex(real, imag);

}

// return a new complex object whose value is (this - b)

public complex minus(complex b) {

complex a = this;

double real = a.re - b.re;

double imag = a.im - b.im;

return new complex(real, imag);

}

// return a new complex object whose value is (this * b)

public complex times(complex b) {

complex a = this;

double real = a.re * b.re - a.im * b.im;

double imag = a.re * b.im + a.im * b.re;

return new complex(real, imag);

}

// return a new object whose value is (this * alpha)

public complex scale(double alpha) {

return new complex(alpha * re, alpha * im);

}

// return a new complex object whose value is the conjugate of this

public complex conjugate() {

return new complex(re, -im);

}

// return a new complex object whose value is the reciprocal of this

public complex reciprocal() {

double scale = re * re + im * im;

return new complex(re / scale, -im / scale);

}

// return the real or imaginary part

public double re() {

return re;

}

public double im() {

return im;

}

// return a / b

public complex divides(complex b) {

complex a = this;

return a.times(b.reciprocal());

}

// return a new complex object whose value is the complex exponential of

// this

public complex exp() {

return new complex(math.exp(re) * math.cos(im), math.exp(re) * math.sin(im));

}

// return a new complex object whose value is the complex sine of this

public complex sin() {

return new complex(math.sin(re) * math.cosh(im), math.cos(re) * math.sinh(im));

}

// return a new complex object whose value is the complex cosine of this

public complex cos() {

return new complex(math.cos(re) * math.cosh(im), -math.sin(re) * math.sinh(im));

}

// return a new complex object whose value is the complex tangent of this

public complex tan() {

return sin().divides(cos());

}

// a static version of plus

public static complex plus(complex a, complex b) {

double real = a.re + b.re;

double imag = a.im + b.im;

complex sum = new complex(real, imag);

return sum;

}

// see section 3.3.

public boolean equals(object x) {

if (x == null)

return false;

if (this.getclass() != x.getclass())

return false;

complex that = (complex) x;

return (this.re == that.re) && (this.im == that.im);

}

// see section 3.3.

public int hashcode() {

return objects.hash(re, im);

}

// sample client for testing

public static void main(string[] args) {

complex a = new complex(3.0, 4.0);

complex b = new complex(-3.0, 4.0);

system.out.println("a = " + a);

system.out.println("b = " + b);

system.out.println("re(a) = " + a.re());

system.out.println("im(a) = " + a.im());

system.out.println("b + a = " + b.plus(a));

system.out.println("a - b = " + a.minus(b));

system.out.println("a * b = " + a.times(b));

system.out.println("b * a = " + b.times(a));

system.out.println("a / b = " + a.divides(b));

system.out.println("(a / b) * b = " + a.divides(b).times(b));

system.out.println("conj(a) = " + a.conjugate());

system.out.println("|a| = " + a.abs());

system.out.println("tan(a) = " + a.tan());

}

}

希望本文所述对大家java程序设计有所帮助。

原文链接:https://blog.csdn.net/ffj0721/article/details/78521821

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Java实现的傅里叶变化算法示例 https://www.kuaiidc.com/111260.html

相关文章

发表评论
暂无评论