• 《算法》BEYOND 部分程序 part 2


    ▶ 书中第六章部分程序,加上自己补充的代码,包括快速傅里叶变换,多项式表示

    ● 快速傅里叶变换,需要递归

      1 package package01;
      2 
      3 import edu.princeton.cs.algs4.StdOut;
      4 import edu.princeton.cs.algs4.StdRandom;
      5 import edu.princeton.cs.algs4.Complex;
      6 
      7 public class class01 
      8 {
      9     private static final Complex ZERO = new Complex(0, 0);
     10     private static final double EPSILON = 1e-8;
     11     private class01() { }
     12 
     13     public static Complex[] fft(Complex[] x)// 正向傅里叶变换
     14     {
     15         int n = x.length;
     16         if (n == 1)
     17             return new Complex[] {x[0]};
     18         if (n % 2 != 0)
     19             throw new IllegalArgumentException("n != 2^k");
     20 
     21         Complex[] temp = new Complex[n/2], result = new Complex[n];
     22         for (int k = 0; k < n/2; k++)       // 偶数项和奇数分别递归
     23             temp[k] = x[2*k];
     24         Complex[] q = fft(temp);
     25         for (int k = 0; k < n/2; k++)
     26             temp[k] = x[2*k + 1];
     27         Complex[] r = fft(temp);
     28         for (int k = 0; k < n/2; k++)       // 合并
     29         {
     30             double kth = -2 * k * Math.PI / n;
     31             Complex wk = new Complex(Math.cos(kth), Math.sin(kth));
     32             result[k]       = q[k].plus(wk.times(r[k]));
     33             result[k + n/2] = q[k].minus(wk.times(r[k]));
     34         }
     35         return result;
     36     }
     37 
     38     public static Complex[] ifft(Complex[] x)// 傅里叶反变换,共轭、正变换、再共轭,最后除以项数
     39     {
     40         int n = x.length;
     41         Complex[] result = new Complex[n], temp;
     42         for (int i = 0; i < n; i++)
     43             result[i] = x[i].conjugate();
     44         result = fft(result);
     45         for (int i = 0; i < n; i++)
     46             result[i] = result[i].conjugate();
     47         for (int i = 0; i < n; i++)
     48             result[i] = result[i].scale(1.0 / n);
     49         return result;
     50     }
     51 
     52     public static Complex[] cconvolve(Complex[] x, Complex[] y)// 环形卷积
     53     {
     54         if (x.length != y.length)
     55             throw new IllegalArgumentException("x.length != y.length");
     56         int n = x.length;
     57         Complex[] a = fft(x), b = fft(y), c = new Complex[n];
     58         for (int i = 0; i < n; i++)
     59             c[i] = a[i].times(b[i]);
     60         return ifft(c);
     61     }
     62 
     63     public static Complex[] convolve(Complex[] x, Complex[] y)// 线性卷积,后一半垫 0
     64     {
     65         if (x.length != y.length)
     66             throw new IllegalArgumentException("x.length != y.length");
     67         Complex[] a = new Complex[2 * x.length], b = new Complex[2 * y.length];
     68         for (int i = 0; i < x.length; i++)
     69             a[i] = x[i];
     70         for (int i = x.length; i < 2*x.length; i++)
     71             a[i] = ZERO;
     72         for (int i = 0; i < y.length; i++)
     73             b[i] = y[i];
     74         for (int i = y.length; i < 2*y.length; i++)
     75             b[i] = ZERO;
     76         return cconvolve(a, b);
     77     }
     78 
     79     private static void show(Complex[] x, String title)
     80     {
     81         StdOut.printf("%s
    -------------------
    ",title);
     82         for (int i = 0; i < x.length; i++)
     83             StdOut.println(x[i]);
     84         StdOut.println();
     85     }
     86 
     87     public static void main(String[] args)
     88     {
     89         int n = 16;
     90         Complex[] x = new Complex[n];
     91         for (int i = 0; i < n; i++)
     92             x[i] = new Complex(StdRandom.uniform(-1.0, 1.0), 0);
     93 
     94         show(x, "x");
     95         Complex[] y = fft(x);
     96         show(y, "y = fft(x)");
     97         Complex[] z = ifft(y);
     98         show(z, "z = ifft(y)");
     99         Complex[] c = cconvolve(x, x);
    100         show(c, "c = cconvolve(x, x)");
    101         Complex[] d = convolve(x, x);
    102         show(d, "d = convolve(x, x)");
    103     }
    104 }

    ● 多项式表示

      1 package package01;
      2 
      3 import edu.princeton.cs.algs4.StdOut;
      4 
      5 public class class01
      6 {
      7     private int[] coef;                 // 系数列表
      8     private int degree;                 // 次数
      9 
     10     public class01(int a, int b)        // 建立单项式 a*x^b
     11     {
     12         coef = new int[b + 1];
     13         coef[b] = a;
     14         reduce();
     15     }
     16 
     17     private void reduce()               // 记录多项式的次数
     18     {
     19         degree = -1;
     20         for (int i = coef.length - 1; i >= 0; i--)
     21         {
     22             if (coef[i] != 0)
     23             {
     24                 degree = i;
     25                 return;
     26             }
     27         }
     28     }
     29 
     30     public int degree()
     31     {
     32         return degree;
     33     }
     34 
     35     public class01 plus(class01 that)   // p(x) + q(x),把系数从低次项向高次项各加一遍
     36     {
     37         class01 poly = new class01(0, Math.max(degree, that.degree));
     38         for (int i = 0; i <= degree; i++)
     39             poly.coef[i] = coef[i];
     40         for (int i = 0; i <= that.degree; i++)
     41             poly.coef[i] += that.coef[i];
     42         poly.reduce();
     43         return poly;
     44     }
     45 
     46     public class01 minus(class01 that)
     47     {
     48         class01 poly = new class01(0, Math.max(degree, that.degree));
     49         for (int i = 0; i <= degree; i++)
     50             poly.coef[i] = coef[i];
     51         for (int i = 0; i <= that.degree; i++)
     52             poly.coef[i] -= that.coef[i];
     53         poly.reduce();
     54         return poly;
     55     }
     56 
     57     public class01 times(class01 that)
     58     {
     59         class01 poly = new class01(0, degree + that.degree);
     60         for (int i = 0; i <= degree; i++)
     61         {
     62             for (int j = 0; j <= that.degree; j++)
     63                 poly.coef[i + j] += (coef[i] * that.coef[j]);
     64         }
     65         poly.reduce();
     66         return poly;
     67     }
     68 
     69     public class01 compose(class01 that)// p(q(x)),用了秦九韶
     70     {
     71         class01 poly = new class01(0, 0);
     72         for (int i = degree; i >= 0; i--)
     73         {
     74             class01 term = new class01(coef[i], 0);
     75             poly = term.plus(that.times(poly));
     76         }
     77         return poly;
     78     }
     79 
     80     public class01 differentiate()      // p'(x)
     81     {
     82         if (degree == 0)
     83             return new class01(0, 0);
     84         class01 poly = new class01(0, degree - 1);
     85         poly.degree = degree - 1;
     86         for (int i = 0; i < degree; i++)
     87             poly.coef[i] = (i + 1) * coef[i + 1];
     88         return poly;
     89     }
     90 
     91     public int evaluate(int x)          // p(x) /. {x->a}
     92     {
     93         int p = 0;
     94         for (int i = degree; i >= 0; i--)
     95             p = coef[i] + (x * p);
     96         return p;
     97     }
     98 
     99     public int compareTo(class01 that)
    100     {
    101         if (degree < that.degree)
    102             return -1;
    103         if (degree > that.degree)
    104             return +1;
    105         for (int i = degree; i >= 0; i--)
    106         {
    107             if (coef[i] < that.coef[i])
    108                 return -1;
    109             if (coef[i] > that.coef[i])
    110                 return +1;
    111         }
    112         return 0;
    113     }
    114 
    115     @Override
    116         public String toString()
    117     {
    118         if (degree == -1)
    119             return "0";
    120         if (degree == 0)
    121             return "" + coef[0];
    122         if (degree == 1)
    123             return coef[1] + "x + " + coef[0];
    124         String s = coef[degree] + "x^" + degree;
    125         for (int i = degree - 1; i >= 0; i--)
    126         {
    127             if (coef[i] == 0)
    128                 continue;
    129             if (coef[i]  > 0)
    130                 s += " + " + (coef[i]);
    131             if (coef[i]  < 0)
    132                 s += " - " + (-coef[i]);
    133             s += (i == 1) ? "x" : ("x^" + i);
    134         }
    135         return s;
    136     }
    137 
    138     public static void main(String[] args)
    139     {
    140         class01 zero = new class01(0, 0);
    141         class01 p1 = new class01(4, 3);
    142         class01 p2 = new class01(3, 2);
    143         class01 p3 = new class01(1, 0);
    144         class01 p4 = new class01(2, 1);
    145         class01 p = p1.plus(p2).plus(p3).plus(p4);   // 4x^3 + 3x^2 + 1
    146 
    147         class01 q1 = new class01(3, 2);
    148         class01 q2 = new class01(5, 0);
    149         class01 q = q1.plus(q2);                     // 3x^2 + 5
    150 
    151         StdOut.println("zero(x)     = " + zero);
    152         StdOut.println("p(x)        = " + p);
    153         StdOut.println("q(x)        = " + q);
    154         StdOut.println("p(x) + q(x) = " + p.plus(q));
    155         StdOut.println("p(x) * q(x) = " + p.times(q));
    156         StdOut.println("p(q(x))     = " + p.compose(q));
    157         StdOut.println("p(x) - p(x) = " + p.minus(p));
    158         StdOut.println("0 - p(x)    = " + zero.minus(p));
    159         StdOut.println("p(3)        = " + p.evaluate(3));
    160         StdOut.println("p'(x)       = " + p.differentiate());
    161         StdOut.println("p''(x)      = " + p.differentiate().differentiate());
    162     }
    163 }
  • 相关阅读:
    Explain用法
    轻量快速的 Python ASGI 框架 uvicorn
    conda常用命令
    ubuntu 安装并配置zsh
    ubuntu安装zsh终端
    /etc/profile、/etc/bashrc、.bash_profile、.bashrc
    python用List的内建函数list.sort进行排序
    python对象排序
    修改python接口返回给前端的格式封装
    linux设置uwsgi开机自启
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/10115981.html
Copyright © 2020-2023  润新知