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

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

 package package01;

 import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.Complex; public class class01
{
private static final Complex ZERO = new Complex(0, 0);
private static final double EPSILON = 1e-8;
private class01() { } public static Complex[] fft(Complex[] x)// 正向傅里叶变换
{
int n = x.length;
if (n == 1)
return new Complex[] {x[0]};
if (n % 2 != 0)
throw new IllegalArgumentException("n != 2^k"); Complex[] temp = new Complex[n/2], result = new Complex[n];
for (int k = 0; k < n/2; k++) // 偶数项和奇数分别递归
temp[k] = x[2*k];
Complex[] q = fft(temp);
for (int k = 0; k < n/2; k++)
temp[k] = x[2*k + 1];
Complex[] r = fft(temp);
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));
result[k] = q[k].plus(wk.times(r[k]));
result[k + n/2] = q[k].minus(wk.times(r[k]));
}
return result;
} public static Complex[] ifft(Complex[] x)// 傅里叶反变换,共轭、正变换、再共轭,最后除以项数
{
int n = x.length;
Complex[] result = new Complex[n], temp;
for (int i = 0; i < n; i++)
result[i] = x[i].conjugate();
result = fft(result);
for (int i = 0; i < n; i++)
result[i] = result[i].conjugate();
for (int i = 0; i < n; i++)
result[i] = result[i].scale(1.0 / n);
return result;
} public static Complex[] cconvolve(Complex[] x, Complex[] y)// 环形卷积
{
if (x.length != y.length)
throw new IllegalArgumentException("x.length != y.length");
int n = x.length;
Complex[] a = fft(x), b = fft(y), c = new Complex[n];
for (int i = 0; i < n; i++)
c[i] = a[i].times(b[i]);
return ifft(c);
} public static Complex[] convolve(Complex[] x, Complex[] y)// 线性卷积,后一半垫 0
{
if (x.length != y.length)
throw new IllegalArgumentException("x.length != y.length");
Complex[] a = new Complex[2 * x.length], b = new Complex[2 * y.length];
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;
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);
} private static void show(Complex[] x, String title)
{
StdOut.printf("%s\n-------------------\n",title);
for (int i = 0; i < x.length; i++)
StdOut.println(x[i]);
StdOut.println();
} public static void main(String[] args)
{
int n = 16;
Complex[] x = new Complex[n];
for (int i = 0; i < n; i++)
x[i] = new Complex(StdRandom.uniform(-1.0, 1.0), 0); show(x, "x");
Complex[] y = fft(x);
show(y, "y = fft(x)");
Complex[] z = ifft(y);
show(z, "z = ifft(y)");
Complex[] c = cconvolve(x, x);
show(c, "c = cconvolve(x, x)");
Complex[] d = convolve(x, x);
show(d, "d = convolve(x, x)");
}
}

● 多项式表示

 package package01;

 import edu.princeton.cs.algs4.StdOut;

 public class class01
{
private int[] coef; // 系数列表
private int degree; // 次数 public class01(int a, int b) // 建立单项式 a*x^b
{
coef = new int[b + 1];
coef[b] = a;
reduce();
} private void reduce() // 记录多项式的次数
{
degree = -1;
for (int i = coef.length - 1; i >= 0; i--)
{
if (coef[i] != 0)
{
degree = i;
return;
}
}
} public int degree()
{
return degree;
} public class01 plus(class01 that) // p(x) + q(x),把系数从低次项向高次项各加一遍
{
class01 poly = new class01(0, Math.max(degree, that.degree));
for (int i = 0; i <= degree; i++)
poly.coef[i] = coef[i];
for (int i = 0; i <= that.degree; i++)
poly.coef[i] += that.coef[i];
poly.reduce();
return poly;
} public class01 minus(class01 that)
{
class01 poly = new class01(0, Math.max(degree, that.degree));
for (int i = 0; i <= degree; i++)
poly.coef[i] = coef[i];
for (int i = 0; i <= that.degree; i++)
poly.coef[i] -= that.coef[i];
poly.reduce();
return poly;
} public class01 times(class01 that)
{
class01 poly = new class01(0, degree + that.degree);
for (int i = 0; i <= degree; i++)
{
for (int j = 0; j <= that.degree; j++)
poly.coef[i + j] += (coef[i] * that.coef[j]);
}
poly.reduce();
return poly;
} public class01 compose(class01 that)// p(q(x)),用了秦九韶
{
class01 poly = new class01(0, 0);
for (int i = degree; i >= 0; i--)
{
class01 term = new class01(coef[i], 0);
poly = term.plus(that.times(poly));
}
return poly;
} public class01 differentiate() // p'(x)
{
if (degree == 0)
return new class01(0, 0);
class01 poly = new class01(0, degree - 1);
poly.degree = degree - 1;
for (int i = 0; i < degree; i++)
poly.coef[i] = (i + 1) * coef[i + 1];
return poly;
} public int evaluate(int x) // p(x) /. {x->a}
{
int p = 0;
for (int i = degree; i >= 0; i--)
p = coef[i] + (x * p);
return p;
} public int compareTo(class01 that)
{
if (degree < that.degree)
return -1;
if (degree > that.degree)
return +1;
for (int i = degree; i >= 0; i--)
{
if (coef[i] < that.coef[i])
return -1;
if (coef[i] > that.coef[i])
return +1;
}
return 0;
} @Override
public String toString()
{
if (degree == -1)
return "0";
if (degree == 0)
return "" + coef[0];
if (degree == 1)
return coef[1] + "x + " + coef[0];
String s = coef[degree] + "x^" + degree;
for (int i = degree - 1; i >= 0; i--)
{
if (coef[i] == 0)
continue;
if (coef[i] > 0)
s += " + " + (coef[i]);
if (coef[i] < 0)
s += " - " + (-coef[i]);
s += (i == 1) ? "x" : ("x^" + i);
}
return s;
} public static void main(String[] args)
{
class01 zero = new class01(0, 0);
class01 p1 = new class01(4, 3);
class01 p2 = new class01(3, 2);
class01 p3 = new class01(1, 0);
class01 p4 = new class01(2, 1);
class01 p = p1.plus(p2).plus(p3).plus(p4); // 4x^3 + 3x^2 + 1 class01 q1 = new class01(3, 2);
class01 q2 = new class01(5, 0);
class01 q = q1.plus(q2); // 3x^2 + 5 StdOut.println("zero(x) = " + zero);
StdOut.println("p(x) = " + p);
StdOut.println("q(x) = " + q);
StdOut.println("p(x) + q(x) = " + p.plus(q));
StdOut.println("p(x) * q(x) = " + p.times(q));
StdOut.println("p(q(x)) = " + p.compose(q));
StdOut.println("p(x) - p(x) = " + p.minus(p));
StdOut.println("0 - p(x) = " + zero.minus(p));
StdOut.println("p(3) = " + p.evaluate(3));
StdOut.println("p'(x) = " + p.differentiate());
StdOut.println("p''(x) = " + p.differentiate().differentiate());
}
}

《算法》BEYOND 部分程序 part 2的更多相关文章

  1. 信号量和PV操作写出Bakery算法的同步程序

    面包店烹制面包及蛋糕,由n个销售员卖出.当有顾客进店购买面包或蛋糕时,应先在取号机上取号,然后等待叫号,若有销售员空闲时便叫下一号,试用信号量和PV操作写出Bakery算法的同步程序. 设计要求 1) ...

  2. GMM算法的matlab程序

    GMM算法的matlab程序 在“GMM算法的matlab程序(初步)”这篇文章中已经用matlab程序对iris数据库进行简单的实现,下面的程序最终的目的是求准确度. 作者:凯鲁嘎吉 - 博客园 h ...

  3. GMM算法的matlab程序(初步)

    GMM算法的matlab程序 在https://www.cnblogs.com/kailugaji/p/9648508.html文章中已经介绍了GMM算法,现在用matlab程序实现它. 作者:凯鲁嘎 ...

  4. KFCM算法的matlab程序(用FCM初始化聚类中心)

    KFCM算法的matlab程序(用FCM初始化聚类中心) 在“聚类——KFCM”这篇文章中已经介绍了KFCM算法,现在用matlab程序对iris数据库进行实现,用FCM初始化聚类中心,并求其准确度与 ...

  5. KFCM算法的matlab程序

    KFCM算法的matlab程序 在“聚类——KFCM”这篇文章中已经介绍了KFCM算法,现在用matlab程序对iris数据库进行简单的实现,并求其准确度. 作者:凯鲁嘎吉 - 博客园 http:// ...

  6. FCM算法的matlab程序2

    FCM算法的matlab程序2 在“FCM算法的matlab程序”这篇文章中已经用matlab程序对iris数据库进行实现,并求解准确度.下面的程序是另一种方法,是最常用的方法:先初始化聚类中心,在进 ...

  7. FCM算法的matlab程序

    FCM算法的matlab程序 在“FCM算法的matlab程序(初步)”这篇文章中已经用matlab程序对iris数据库进行简单的实现,下面的程序最终的目的是求准确度. 作者:凯鲁嘎吉 - 博客园 h ...

  8. K-means算法的matlab程序

    K-means算法的matlab程序 在“K-means算法的matlab程序(初步)”这篇文章中已经用matlab程序对iris数据库进行简单的实现,下面的程序最终的目的是求准确度. 作者:凯鲁嘎吉 ...

  9. FCM算法的matlab程序(初步)

    FCM算法的matlab程序 在https://www.cnblogs.com/kailugaji/p/9648430.html文章中已经介绍了FCM算法,现在用matlab程序实现它. 作者:凯鲁嘎 ...

  10. K-means算法的matlab程序(初步)

    K-means算法的matlab程序 在https://www.cnblogs.com/kailugaji/p/9648369.html 文章中已经介绍了K-means算法,现在用matlab程序实现 ...

随机推荐

  1. 《JavaScript设计模式与开发》笔记 6.高阶函数

    1.函数作为参数传递 1.回调函数 2.Array.prototype.sort 2.函数作为返回值输出 1.判断数据的类型 3.高级函数的实现AOP 4.高阶函数的其他应用 1.currying 函 ...

  2. PHP在Linux下的套件LNMP

    LNMP官网:https://lnmp.org/install.html 另外不要忘了Azkaban和WhereHows

  3. [ZZ]知名互联网公司Python的16道经典面试题及答案

    知名互联网公司Python的16道经典面试题及答案 https://mp.weixin.qq.com/s/To0kYQk6ivYL1Lr8aGlEUw 知名互联网公司Python的16道经典面试题及答 ...

  4. [转]SuperSocket

    public class SocketServer : AppServer<AppSession> { public SocketServer() : base(new DefaultRe ...

  5. 网站首页多URL可访问,如何集中首页网站权重?

    原文地址:http://ask.seowhy.com/question/8573 百度站长平台Lee在文章<建立符合搜索引擎抓取习惯>一文中提出:唯一性网站中同一内容页只与唯一一个url相 ...

  6. 如果在 Windows 10 家庭版中使用「远程桌面」

    远程桌面是 Windows 系统下原生.跨平台的的远程控制功能,拥有微软官方提供的各平台客户端,就可以让你在远程轻松帮助别人或者控制自己的 PC,而从 Windows 7 以来家庭版都不支持桌面功能

  7. 修改Linux终端提示符颜色

    修改Linux终端提示符颜色 作者:Eric 微信:loveoracle11g [root@linux-node2 ~]# tail -1 .bashrc PS1='[\[\033[1;31m\]\u ...

  8. /dev/null 2>&1 解释

    cmd >a 2>a 和 cmd >a 2>&1 为什么不同?cmd >a 2>a :stdout和stderr都直接送往文件 a ,a文件会被打开两遍,由 ...

  9. html 网页生产pdf文件

    在nuget中安装组件 Install-Package CPechkin https://www.nuget.org/packages/CPechkin/ 根据html生产pdf文件 using Sy ...

  10. javasript-for循环

    先来个for循环的例子: var i=0,j=0; for(;i<10,j<6;i++,j++){ k=i+j; } console.log(k) 想知道会输出什么,首先得知道完整循环了多 ...