其实是初中数学的内容。

研究高斯软件的并行效率时,作者根据公式

$ s = n \times (1.015 - n \times 0.0067) $

得出了「并行核数大概在75的时候达到最大速度」。我突然有点糊涂了,这个结论是怎么得出的呢?

明显这是一个初中数学问题,因为函数是个一元二次函数,有公式,可惜我已经忘光光了。用数形结合的思路

1
2
3
4
5
6
7
f = @(x) -0.0067 * x.^2 + 1.015 * x;
x = 1:100;
plot(x, f(x));
xl = xlabel("n", "Units", "Normalized", "Position", [0.5 -0.07786 0]);
yl = ylabel("s", "Units", "Normalized", "Position", [-0.1 0.5 0]);
set(xl, "FontSize", 30); set(yl, "FontSize", 36);
print("n(1.015-n0.0067).ps", "-color");

s = n × (1.015 - n × 0.0067)

可以看出大概是75的时候效率最大,这时我也大概想起了公式是啥样的。不行,这个问题要一般话,要用专门的工具解决:

1
2
phi = @(x) 0.0067 * x^2 - 1.01 * x;
sqp([1], phi)

这里用Octave的sqp()函数求了phi()的最小值,这个phi()就是上面公式的值乘以−1,也就是把求最大值转换为求最小值,其他的量都默认,从1开始找最小值,求得的结果是75.373。

又是一次脱裤子放屁的经历。收获是又玩了一把Octave,但这个方法的价值不局限在这里,因为如果函数更为复杂,没有公式,图形又不好看,还需要精确求解的时候,该方法的优势就体现出来了。

举个栗子,某种药物的释放程度随时间变化,t分钟时释放比例以P表示,得到的数据是

1
2
t = [0 2 4 6 8 10 15 17.5 22 30 45 60];
P = [0 0.1435 0.29768 0.46835 0.58834 0.66296 0.82152 0.9215 1 1 1 1 ];

如果以如下的模型来拟合这些数据

$ P = 1 - e^{-K \times t} $

看不出来了吧,我可以拟合

1
phi = @(K) abs(sum(P) - sum(1 - exp(-K * t))); sqp([0.01], phi)

结果是0.11390,画图

1
2
3
4
5
6
7
8
plot(t, P * 100, '@');
K = 0.11390;
hold on;
plot(t, (1 - exp(-K * t)) * 100);
xl = xlabel("Time (min)", "Units", "Normalized", "Position", [0.5 -0.07786 0]);
yl = ylabel("Intrinsic dissolution rate (%)", "Units", "Normalized", "Position", [-0.1 0.5 0]);
set(xl, "FontSize", 24); set(yl, "FontSize", 26);
print("Fit.ps", "-color");

Fit

这两个图都用了一些技巧,除了坐标的位置动过外,还改了PostScript文件,怎么改另写一篇文章介绍咯。