บทความนี้อธิบายอัลกอริทึมการเปลี่ยนแปลงฟูริเยร์ที่ใช้ใน Java แบ่งปันสำหรับการอ้างอิงของคุณดังนี้:
ผลการแปรผันของฟูริเยร์ใช้ในการใช้ Java เป็นรูปแบบพหูพจน์ A+BI
โดยไม่ต้องกังวลใจเพิ่มเติมรหัสการใช้งานมีดังนี้รวมสองคลาสทั้งหมด
FFT.CLASS FOURIER CHANGE FUNCTION CODE CODE CODE
แพ็คเกจ fft.test;/************************************************************************************************************************* กระดูกเปลือย * การใช้งานที่ทำงานในเวลา O (n log n) เป้าหมายของเราคือการเพิ่มประสิทธิภาพความชัดเจนของรหัสมากกว่าประสิทธิภาพ * * ข้อ จำกัด - - *************************************************************************************************************************************************************************************** // กรณีฐานถ้า (n == 1) ส่งคืนคอมเพล็กซ์ใหม่ [] {x [0]}; // radix 2 cooley-tukey fft ถ้า (n % 2! = 0) {โยน runtimeException ใหม่ ("n ไม่ใช่พลังของ 2"); } // fft ของคำที่ซับซ้อน [] even = new complex [n / 2]; สำหรับ (int k = 0; k <n / 2; k ++) {แม้กระทั่ง [k] = x [2 * k]; } complex [] q = fft (แม้); // fft ของคำคี่คอมเพล็กซ์ [] คี่ = even; // นำอาร์เรย์กลับมาใช้ใหม่สำหรับ (int k = 0; k <n / 2; k ++) {คี่ [k] = x [2 * k+1]; } complex [] r = fft (คี่); // รวมคอมเพล็กซ์ [] y = ใหม่คอมเพล็กซ์ [n]; สำหรับ (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; } // คำนวณค่าผกผัน fft ของ x [] สมมติว่าความยาวของมันเป็นพลังของ 2 public static complex [] ifft (complex [] x) {int n = x.length; คอมเพล็กซ์ [] y = ใหม่คอมเพล็กซ์ [n]; // ใช้คอนจูเกตสำหรับ (int i = 0; i <n; i ++) {y [i] = x [i] .conjugate (); } // คำนวณไปข้างหน้า fft y = fft (y); // ใช้คอนจูเกตอีกครั้งสำหรับ (int i = 0; i <n; i ++) {y [i] = y [i] .conjugate (); } // หารด้วย n สำหรับ (int i = 0; i <n; i ++) {y [i] = y [i] .scale (1.0 / n); } return y; } // คำนวณการโน้มน้าวใจวงกลมของ X และ Y Public Static Complex [] cconvolve (complex [] x, complex [] y) {// น่าจะเป็นแผ่น x และ y ด้วย 0s เพื่อให้พวกเขามีความยาวเท่ากัน // และเป็นพลังของ 2 ถ้า (x.length! } int n = x.length; // คำนวณ FFT ของแต่ละลำดับประเมินความซับซ้อน [] a = fft (x); ซับซ้อน [] b = fft (y); // การคูณแบบจุด-จุด, การคูณค่าจุดที่ซับซ้อน [] c = ใหม่คอมเพล็กซ์ [n]; สำหรับ (int i = 0; i <n; i ++) {c [i] = a [i] .times (b [i]); } // คำนวณผกผัน FFT, การแก้ไขส่งคืน IFFFT (C); } // คำนวณการประชุมเชิงเส้นของ X และ Y Public Static Complex [] convolve (complex [] x, complex [] y) {คอมเพล็กซ์ศูนย์ = ใหม่คอมเพล็กซ์ (0, 0); complex [] a = new complex [2 * x.length]; // 2n Times Boundary, ค่าสัมประสิทธิ์การสั่งซื้อที่สูงขึ้นคือ 0. สำหรับ (int i = 0; i <x.length; i ++) a [i] = x [i]; สำหรับ (int i = x.length; i <2 * x.length; i ++) a [i] = zero; คอมเพล็กซ์ [] b = ใหม่คอมเพล็กซ์ [2 * y.length]; สำหรับ (int i = 0; i <y.length; i ++) b [i] = y [i]; สำหรับ (int i = y.length; i <2 * y.length; i ++) b [i] = zero; ส่งคืน cconvolve (a, b); } // แสดงอาร์เรย์ของตัวเลขที่ซับซ้อนเพื่อแสดงโมฆะคงที่สตแตนสาธารณะแสดง (คอมเพล็กซ์ [] x, ชื่อสตริง) {System.out.println (ชื่อ); System.out.println ("----------------------------------------"); int complexLength = x.length; สำหรับ (int i = 0; i <complexLength; i ++) {// output complex // system.out.println (x [i]); // แอมพลิจูดเอาต์พุตต้องใช้ * 2 / ความยาว System.out.println (x [i] .abs () * 2 / complexLength); } system.out.println (); }/ ** * จัดระเบียบข้อมูลอาร์เรย์ใหม่เป็นกำลังของ 2 เอาท์พุท * * @param data * @return */ สาธารณะคงที่สองเท่า [] pow2doublearr (dauln [] ข้อมูล) {// สร้างอาร์เรย์ใหม่สองเท่า [] newData = null; int datalength = data.length; int sumnum = 2; ในขณะที่ (sumnum <datalength) {sumnum = sumnum * 2; } int addLength = sumnum - datalength; if (addLength! = 0) {newData = ใหม่ double [sumnum]; System.ArrayCopy (ข้อมูล, 0, NewData, 0, Datalength); สำหรับ (int i = datalength; i <sumnum; i ++) {newData [i] = 0d; }} else {newData = data; } ส่งคืน Newdata; } /** * deoffset * * @param OriginalArr * OriginalArr * OriginalAr * Public Static Double [] Deskew (double [] OriginalArr) {// ตัวกรองพารามิเตอร์ที่ไม่ถูกต้องถ้า (OriginalAr == NULL || OriginalAr.length <= 0) {return null; } // กำหนดอาร์เรย์เป้าหมายสองเท่า [] resarr = ใหม่ double [originalAr.length]; // ค้นหาผลรวมของอาร์เรย์สองครั้งรวม = 0d; สำหรับ (int i = 0; i <OriginalAr.length; i ++) {sum+= originalAr [i]; } // ค้นหาค่าเฉลี่ยของอาร์เรย์ double aver = sum / originalAr.length; // ลบค่าออฟเซ็ตสำหรับ (int i = 0; i <OriginalAr.length; i ++) {resarr [i] = OriginalAr [i] - aver; } return resarr; } โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// int n = integer.parseint (args [0]); double [] data = {-0.35668879080953375, -0.6118094913035987, 0.8534269560320435, -0.6699697478438837 -0.025718699518642918, 0.07649691490732002}; // ลบข้อมูลออฟเซ็ต = deskew (ข้อมูล); // กำลังของจำนวน 2 = pow2doublearr (ข้อมูล); int n = data.length; System.out.println (n + "หมายเลขในอาร์เรย์ n ... "); คอมเพล็กซ์ [] x = ใหม่คอมเพล็กซ์ [n]; // ข้อมูลต้นฉบับสำหรับ (int i = 0; i <n; i ++) {// x [i] = new complex (-2 * math.random ()+1, 0); x [i] = ใหม่คอมเพล็กซ์ (data [i], 0); } show (x, "x"); // fft ของข้อมูลดั้งเดิมที่ซับซ้อน [] y = fft (x); แสดง (y, "y = fft (x)"); // ใช้ค่าผกผัน fft complex [] z = ifft (y); แสดง (z, "z = ifft (y)"); // convolution แบบวงกลมของ x ด้วยตัวเองซับซ้อน [] c = cconvolve (x, x); แสดง (c, "c = cconvolve (x, x)"); // linear convolution ของ x กับตัวเองซับซ้อน [] d = convolve (x, x); แสดง (d, "d = convolve (x, x)"); }}/************************************************************************************************************************ - 0.35425500561437717 0.8910250650549392 * -0.025718699518642918 0.07649691490732002 * * Y = FFT (x) - 2.4696418005143532I 1.1395317305034673 * -0.17611092978237974 -2.4696418005143532I -0.8301420417085572 + * 0.872688872068726872068720420 -1.24577666306544419 - 0.7113504894129803i * * z = ifft (y) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 0.8534269560320435 -2.691607282636124E -17I * -0.6699697478438837 + 4.1114763914420734E -17I 0.3542555614377777777717 6.887033953004965E-17I -0.02571869518642918 + * 2.691607282636124E-17I 0.07649691490732002-1.439638731683709696969691490732002 - 1.9986455722517509E-16I 1.432390480003344 + 2.636779683484747E-16I * -2.2165857430333684 + 2.218004769856214 1.3815636262919812E-17I 1.0230680492494633-2.4422465262488753E-16I * * D = Convolve (X, X) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 0.43645117531775324 -2.78776395788635E -18I * -0.2345048043334932 -6.907818131459906E -18I -0.566328028025194680303 1.2954076913348198 + 1.518836016779236E -16I * -2.212650940696159 + 1.109002384928107E -17I -0.0184070346878785718181818687187 1.023068049249463 -9.435675069681485E -17I * -1.205924207390114 -2.983724378680108E -16I 0.7963307380325 + * 2.49676767656565765656565656565656565656565656565656 0.6732024728888314-6.907818131459906E-18I * 0.00836681821649593 + 1.4156564203603091E-16I 0.1369827866685222203603091E-16I -0.00393480233720922 + 1.1090023849928107E-17I * 0.0058517777990337828 + 2.512241462921638E-167I 1.1102202462515656 -complex.class คลาสพหูพจน์
แพ็คเกจ fft.test;/***************************************************************************************************************************** * * ชนิดข้อมูลคือ "ไม่เปลี่ยนรูป" ดังนั้นเมื่อคุณสร้างและเริ่มต้น * วัตถุที่ซับซ้อนคุณไม่สามารถเปลี่ยนได้ คำหลัก "สุดท้าย" * เมื่อประกาศ RE และ IM บังคับใช้กฎนี้ทำให้เป็นข้อผิดพลาดในการรวบรวม * เวลาเพื่อเปลี่ยนตัวแปรอินสแตนซ์. หรือ. IM หลังจาก * พวกเขาได้เริ่มต้นแล้ว * * % 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 * a /b = 0.36 - 1.52i * (a /b) | A | = 7.810249675906654 * tan (a) = -6.685231390246571E -6 + 1.0000103108981198i * *********************************************************************************************************************************************************************************************** สองครั้งสุดท้ายซ้ำอีกครั้ง; // ส่วนที่เป็นจริงส่วนตัวสองครั้งสุดท้าย IM; // ส่วนจินตนาการ // สร้างวัตถุใหม่ด้วยส่วนที่แท้จริงและจินตนาการที่ซับซ้อนสาธารณะ (สองภาพสองภาพคู่) {re = real; IM = จินตนาการ; } // ส่งคืนการแสดงสตริงของการเรียกใช้วัตถุที่ซับซ้อนของสตริงสาธารณะ toString () {ถ้า (im == 0) return re + ""; ถ้า (re == 0) ส่งคืน IM + "I"; if (IM <0) return re + " -" + (-im) + "i"; return re + " +" + " + im +" i ";} // return abs/modulus/ขนาดสาธารณะ double abs () {return math.hypot (re, im);} // return angle/phase/rigment, normalized ให้อยู่ระหว่าง -pi และ pi publa double ({return math.atan2 (im, re) สิ่งนี้; {คอมเพล็กซ์ A = สิ่งนี้; {return complex (re, -im); {complex a = this; complex (math.sin (re) * math.cosh (im), math.cos (re) * math.sinh (im)); Public Complex () {return sin () Divides (cos ()); ! คอมเพล็กซ์ (-3.0, 4.0); System.out.println ("A - B =" + A.Minus (B)); A.Divides (b) .times (b));สำหรับข้อมูลเพิ่มเติมเกี่ยวกับอัลกอริทึม Java ผู้อ่านที่มีความสนใจในเว็บไซต์นี้สามารถดูหัวข้อ: "โครงสร้างข้อมูล Java และการสอนอัลกอริทึม", "บทสรุปของเคล็ดลับการดำเนินการ Java Dom", "บทสรุปของไฟล์ Java และเคล็ดลับการดำเนินการไดเรกทอรี" และ "สรุป
ฉันหวังว่าบทความนี้จะเป็นประโยชน์กับการเขียนโปรแกรม Java ของทุกคน