向量化计算cell_Matlab向量化编程在二级劝退学科中的一个应用例子
本文使用 Zhihu On VSCode 创作并发布
向量化编程对于用过Matlab或者numpy做过稍微复杂一点的数值运算的人来说并不陌生,甚至说刚入门Matlab或者numpy的小白都知道要用z = x .* y
来代替一个for k = 1 : N {z(k) = x(k) * y(k);}
,进阶一点的人也明白迭代算法最好把更新函数写成向量化的形式。以前觉得向量化编程就是个小技巧,对着入门教程中那些梯度下降例子无脑抄几遍就能掌握向量化编程的主要精髓,直到前两天因为要对一个二级劝退学科的实验数据后处理程序向量化,才体会到要掌握向量化编程思想还是得动脑子。。。
实验数据后处理需求
我有在
在获得了这个随机序列
其中
这还不行,单次实验结果方差太大,需要做
向量化过程
这个实验数据后处理程序初始版本还真的是严格按照上面过程编写的:每次产生一个随机setting,然后从原始数据抽取数据点填充,计算
我对源程序向量化的过程主要用到的技巧是数组的逻辑寻址,然后对满足不同逻辑的数据点分别进行不同的运算。首先生成指定分布的随机序列是不需要一个一个来的,假设我在
function randseq = getRandSeq(len, probs)
cutpoints = cumsum(probs); % 给不同结果划分区间
randseq = rand(1, len);
idx = randseq < cutpoints(1); % 找到落在第一个区间的所有点的下标
randseq(idx) = 2; % 给第一个区间上的点赋予对应的值
for k = 2 : max(size(probs)) % 对后面K-1个区间重复上面过程idx = randseq < cutpoints(k) & randseq >= cutpoints(k-1);randseq(idx) = k+1;
end
randseq = randseq - 1;
end
随机setting序列生成之后,用原始数据填充过程也是可以向量化的:
results = zeros(1, N); % 给生成的随机序列预分配空间
% 生成随机setting序列
setting_seq = getRandSeq(N, probs);
% 用原始数据填充setting序列
for k = 1 : setting_num idx = (setting_seq == k); % 在setting序列中找出所有S_k对应的下标results(idx) = raw_data{k}(1:sum(idx)); % 用对应原始数据往对应位置填充
end
计算
results = cumsum(results) ./ (1:N); % 直接在原地更新,不新建数组了
计算KL散度的函数
function D = klDiv(p1, p0)
% 计算两个伯努利分布之间的KL散度
% p1和p2要么是两个长度相等的array,要么其中一个是数,另一个是array% 检查输入的范围
if sum(p0 < 0) > 0 || sum(p0 > 1) > 0 || sum(p1 > 1) > 0 || sum(p1 < 0) > 0error("illegal input.")
end
if max(size(p0)) == 1 % p1为array, p0为数值D = zeros(size(p1)); % 预分配内存indices0 = (p1 <= p0); % 特殊情况0点下标indices1 = (p1 == 1); % 特殊情况1点下标indices2 = (p1 > p0) & (p1 < 1); % 正常情况点下标D(indices0) = 0;D(indices1) = log(1 / p0);D(indices2) = p1(indices2) .* log(p1(indices2) / p0) +...(1 - p1(indices2)) .* log((1 - p1(indices2)) / (1 - p0));
elseif max(size(p1)) == 1 % p0为array, p1为数值D = zeros(size(p0)); % 预分配内存if p1 == 1D(1:end) = log(1 ./ p0);elseindices0 = (p0 >= p1); % 特殊情况0点下标indices1 = (p0 < p1); % 正常情况点下标D(indices0) = 0;D(indices1) = p1 * log(p1 ./ p0) +...(1 - p1) * log((1 - p1) ./ (1 - p0));end
elseif max(size(p1)) == max(size(p0)) % p0和p1为等长度的arrayD = zeros(size(p1)); % 预分配内存indices0 = (p1 <= p0); % 特殊情况0点下标indices1 = (p1 == 1); % 特殊情况1点下标indices2 = (p1 > p0) & (p1 < 1); % 正常情况点下标D(indices0) = 0;D(indices1) = log(1 ./ p0(indices1));D(indices2) = p1(indices2) .* log(p1(indices2) ./ p0(indices2)) +...(1 - p1(indices2)) .* log((1 - p1(indices2)) ./ (1 - p0(indices3)));
elseerror("illegal input.")
end
end
那么计算
Delta = exp(-klDiv(results, p0) .* (1:N));
最头疼的是
function x = invKLDiv(ps, y)
threshold = 1e-4; % 计算精度
left = zeros(size(ps));
right = ps;
x = (left + right) / 2;
res = klDiv(ps, x) - y;
idx = (right - left) > threshold; % 找出精度仍然不达标的所有下标
idx1 = (res > 0) & idx; % 找出idx中需要更新区间左边界的所有下标
idx2 = (res <= 0) & idx; % % 找出idx中需要更新区间右边界的所有下标
while sum(idx) > 0 % 循环直到所有点都达到精度要求left(idx1) = x(idx1);right(idx2) = x(idx2);x(idx) = (left(idx) + right(idx)) / 2;res(idx) = klDiv(ps(idx), x(idx)) - y(idx);idx = (right - left) > threshold;idx1 = (res > 0) & idx;idx2 = (res <= 0) & idx;
end
end
那现在
eps_A = 16 * (1 - invKLDiv(results, -log(delta)./ (1:N))) / 3;
最后就是把那
% start post-processing the raw data
one_to_N = 1 : N;
one_to_N_M = repmat(one_to_N, 1, M);
results = zeros(1, N*M); % test results sequence
% generate a random setting sequence
setting_seq = getRandSeq(N*M, probs);
% fill the results sequence by raw data according to setting_seq
for k = 1 : setting_num idx = (setting_seq == k);results(idx) = raw_data{k}(1:sum(idx));
end
% compute the significance and infidelity sequence
for k = 1 : Mresults((k-1)*N+1 : k*N) = cumsum(results((k-1)*N+1 : k*N)) ./ one_to_N;
end
Delta = exp(-klDiv(results, p0) .* one_to_N_M);
eps_A = d * (1 - invKLDiv(results, -log(delta) ./ one_to_N_M)) / ((d + 1) * nu);
% store the M i.i.d. exp data
for k = 1 : Mexp_data{4*(k - 1) + 1} = results(k*N);exp_data{4*(k - 1) + 2} = Delta((k-1)*N+1 : k*N);exp_data{4*(k - 1) + 3} = eps_A((k-1)*N+1 : k*N);exp_data{4*(k - 1) + 4} = results((k-1)*N+1 : k*N);
end
整个运行时常缩短为11秒,比之前的十几分钟快了60多倍,爽爆了。
向量化计算cell_Matlab向量化编程在二级劝退学科中的一个应用例子相关推荐
- matlab repmat函数_Matlab向量化编程在二级劝退学科中的一个应用例子
本文使用 Zhihu On VSCode 创作并发布 向量化编程对于用过Matlab或者numpy做过稍微复杂一点的数值运算的人来说并不陌生,甚至说刚入门Matlab或者numpy的小白都知道要用z ...
- C++:计算有n种情况a,b,c中任意一个使之成为最大数需要额外加多少
题目概述: 有n种情况,向三人投票,总票数分别为a,b,c.如果使其中一人票数超过其他人,则需要多少票. 编程: #include< iostream> using namespace s ...
- C语言编程 5.7 从键盘中输入一个英文字母,如果它是大写则转化为小写。如果它是小写则转化为大写,并将其ASCll码显示到屏幕上。
方法一: #include <stdio.h> void main() { char ch; printf("请输入字母"); ch=getchar() ...
- PyTorch与向量化计算
还是先认错啊 只为自己好加标签 自己看方便~~ 向量化计算是一种特殊的并行计算方式.程序在同一时间内只执行一个操作,而并行计算可以在同一时间内执行多个操作.向量化计算是指对不同的数据执行同样的一个或 ...
- 向量化计算cell_吴恩达老师课程笔记系列第24节-Octave教程之向量化和作业(6)
5.1 向量化 参考视频: 5 - 6 - Vectorization (14 min).mkv 在这段视频中,我将介绍有关向量化的内容,无论你是用 Octave,还是别的语言,比如MATLAB 或者 ...
- [转载] Python之NumPy基础:数组与向量化计算
参考链接: Python中的numpy.tanh 本博客为<利用Python进行数据分析>的读书笔记,请勿转载用于其他商业用途. 文章目录 1. NumPy ndarray:多维数组对象1 ...
- Python之NumPy基础:数组与向量化计算
本博客为<利用Python进行数据分析>的读书笔记,请勿转载用于其他商业用途. 文章目录 1. NumPy ndarray:多维数组对象 1.1 生成ndarray 1.2 ndarray ...
- 计算平均指令时间_为什么向量化计算(vectorization)会这么快?
背景 在一次iOS程序的性能测试过程中,我们发现一个自己写的argmax函数的耗时严重超出预期--这个预期是基于平常神经网络中的argmax op的速度得到的直接感官体验.不过这也不算意外,第一个版本 ...
- C++性能优化系列——3D高斯核卷积计算(二)FMA向量化计算一维卷积
高斯核的卷积计算是可分离的,即高斯核的每一个维度可以分开处理.因此,一维卷积计算成为了实现3D高斯卷积的基础.一维卷积计算的性能直接影响了整个程序的性能.本篇将实现一维卷积功能,同时引出ICC编译器对 ...
- R语言学习系列之向量化计算
##R语言学习系列之向量化计算 本文主要讲解R语言向量化计算的原理及方法,希望对初学者能够提供帮助. ##一.向量化 什么是向量化计算呢?其实你可以简单的理解成这样:当我们在使用函数或者定义函数的时候 ...
最新文章
- 安装完python后、还需要安装什么-安装python后
- Android 监听手机GPS打开状态
- Wechat的支付逻辑流程
- 字节跳动只剩下小米这一个朋友了
- 前端学习(2755):配置tabber其他属性
- Github作为maven私服仓库用
- linux下的C语言开发(网络编程)
- 模拟admin组件自己开发stark组件之创建篇
- TensorFlow学习笔记——TensorFlow入门
- H3CSE路由-配置OSPF高级
- 在windows10上安装texlive的参考文档
- 必收藏的九大塑料注塑成型技术及其特点
- 让gentoo安装不再难
- H264码流中NALU sps pps IDR帧的理解
- 如何实现1分钟写一个API接口
- 集福啦!你想要的“福”这里都有~
- 学术英语/专业英语——基本结构及特点
- 北京市重点区域5G网络实测分析
- JavaWeb学习之BS/CS架构及tomcat容器项目部署
- w7设置双显示器_win7如何设置双显示器