大家看到推文标题第一眼作何感想呀?是不是以为小编要爆什么猛料,给大家讲些恋爱技巧之类的呀?要真有这么想的就等下次吧。
不错!今天确实是要以一个爱情主题来开始今天的推文。之前一位小伙伴给咱们留言说老师布置的一道有关matlab加密的问题不会做,希望能够得到小编的帮助。一看问题还挺有意思的,是一小伙给一妹子写的情书。接下来就一起来看看这到底是一个什么样的问题,情书到底写了些啥内容。
问题:“小明怀着复杂的心情给一位女孩写了一首诗,见附件。写的过程中有意的去掉了标点符号,刚好凑成一个规整的豆腐块,为了怕外人看懂,又有意存储为MATLAB数据存储方式。那么你能猜出小明写的是什么内容吗?”
附件:“爱灵亡扰使经望受嫉那地保会情里但到你默地着妒么爱佑像也还愿你难默爱羞的真过你我许没它我过无过怯折诚你另一在有不也悲语你又磨那但一样我完会不伤毫我忍我么愿个地的全再想我无既受曾温上人爱心消打再曾指忍着经柔帝也你”
一看附件内容,乱成一锅粥,没看出来到底写的是个啥
。既然有问题,当然就有解决办法。要解决这道题关键就是需要明白两个关键词,一是“豆腐块”,二是“matlab数据存储方式”。
豆腐块是什么意思呢?意思就是矩形,一个长为m、宽为n的长方形,即满足:S = m*n。
那matlab数据存储方式是怎么样的呢?下面来看一个示例:
在matlab命令窗口用magic函数一个3*3的矩阵并输出结果
A = magic(3)
A =
8 1 6
3 5 7
4 9 2
取矩阵A中全部元素赋值给矩阵B,转置并输出
B = A(:)'
B =
8 3 4 1 5 9 6 7 2
从上面结果不难看出matlab是按列来存储数据的。搞清楚了这两个关键词,这份情书也就迎刃而解了。由于推文内容过多,放不下了,这里小编就不给大家答案,欢迎大家将解密后的情书留言在本推文下方。
恰巧小编头几天在搜索有关矢量化与循环计算效率的内容时,看到这么一个问题:同样的矩阵,按整行取值计算和按整列取值计算所花费的时间是不一样的。既然所花时间不一样,必然有一优一劣,那就可以通过这个方式提高程序的运行效率。根据资料显示,按整行取值计算要比按整列取值计算花费更多的时间,究其原因竟然是按列存储数据,这就让小编联想到了开篇的那封加密情书。说句实话,小编也是第一次知道按列竟然要优于按行。不过细想一下也很好理解,matlab的一些函数如mean、sum、std等默认就是按列来进行计算的。
接下来通过一个实例来看看按行计算和按列计算到底有什么差异,不同配置的电脑运行的时间会不尽相同,但两者差异肯定是明显的。(注:以下示例程序只是为了说明按行计算和按列计算的耗时差异,并不是该程序的最优写法)
clc;clear;
% 定义矩阵行数
C = 10000;
% 令行数等于列数,方便比较
R = C;
% 定义自变量x
x = randn(C, R);
% 所需要解决的问题是:
% y = 3*x^2 + 2*x - 1
% 程序运行计算采用“tic—toc”
%% 按行计算示例
tic
solA = ones(C, R);
for k = 1:C
solA(k, :) = 3*x(k,:).^2 + 2*x(k,:) - 1;
end
toc
%% 按列计算示例
tic
solB = ones(C, R);
for n = 1:R
solB(:,n) = 3*x(:,n).^2 + 2*x(:,n) - 1;
end
toc
耗时对比图
上图是在小编电脑上运行的耗时结果,从上图不难看出,按行计算耗时大约是按列计算耗时的5倍。因此,建议大家在日常存储数据时同类数据优先采用按列存储,计算过程中优先采用按列计算,虽不能大幅提升效率,但还是比不优化强嘛。
感谢QQ昵称为...小迷糊(QQ:258****663)的小伙伴提供的情书谜题!
以上就是今天的全部内容,欢迎大家留言写下自己不同的看法或提供其他更好更优的建议。
参考资料:
[1] https://stackoverflow.com/questions/12522888/arrayfun-can-be-significantly-slower-than-an-explicit-loop-in-matlab-why
[2] https://www.mathworks.com/matlabcentral/answers/54522-why-is-indexing-vectors-matrices-in-matlab-very-inefficient