SGISTL源码探究-stl_numeric.h中的数值算法

Altium Designer学习---如何进行SI仿真 Altium designer 如何进行SI仿真。         1、仿真电路中需要至少一块集成电路;             2、器件的IBIS模型;              3、在规则中必须设定电源网络和地网络;              4、建立SI规则约束;              5、层堆栈必须设置正确,电源平面必须连续;     建立的文件必须是一个工程,并把相应的文件放在工程目... 阅读详情

前言

上一小节中,我们对stl中的算法部分做了一个大致的说明。本小节我们将进入到其中关于数值算法的部分,都在stl_numeric.h文件中。废话不多说,直接看源码吧。

stl_numeric

accumulate

注意该算法要求了迭代器的类型至少是InputIterator类型,如果是OutputIterator类型,肯定是不行的。
用于计算元素总和,init加上[first, last)范围内的元素之和。

template <class InputIterator, class T>
T accumulate(InputIterator first, InputIterator last, T init) {
  /* 将[first, last)的值累加到init上
   * 最后返回结果
   */
  for ( ; first != last; ++first)
    init = init + *first;
  return init;
}
//这里多提供了一个BinaryOperation参数。之前是执行的求和运算,现在换成binary_op,对每个元素执行binary_op操作,换成减法、乘法都可以,但是并不建议换成违背函数本意的操作。
template <class InputIterator, class T, class BinaryOperation>
T accumulate(InputIterator first, InputIterator last, T init,
             BinaryOperation binary_op) {
  for ( ; first != last; ++first)
    init = binary_op(init, *first);
  return init;
}
inner_product

该函数用于计算[first1, last1)和[first2, first2 + (last1 - first1))的点积,最后加上init的值。

template <class InputIterator1, class InputIterator2, class T>
T inner_product(InputIterator1 first1, InputIterator1 last1,
                InputIterator2 first2, T init) {
  //遍历[first1, last)以及[first2, first2 + (last1 - first1))
  for ( ; first1 != last1; ++first1, ++first2)
    init = init + (*first1 * *first2);
  return init;
}

//该版本的inner_product不是执行init + (*fist1 ) * (*first2)操作,而是执行传入的binary_op1以及binary_op2操作
template <class InputIterator1, class InputIterator2, class T,
          class BinaryOperation1, class BinaryOperation2>
T inner_product(InputIterator1 first1, InputIterator1 last1,
                InputIterator2 first2, T init, BinaryOperation1 binary_op1,
                BinaryOperation2 binary_op2) {
  for ( ; first1 != last1; ++first1, ++first2)
    init = binary_op1(init, binary_op2(*first1, *first2));
  return init;
}
partial_sum

该函数用于计算局部的和。将*result赋值为*first,将*(result+1)赋值为*first + *(first+1)依次类推。
当传入的迭代器result为first,这就变成了一个质变算法了。

//该函数供partial_sum调用
template <class InputIterator, class OutputIterator, class T>
OutputIterator __partial_sum(InputIterator first, InputIterator last,
                             OutputIterator result, T*) {
  //从first + 1指向的位置开始进行累加并赋值给*result
  T value = *first;
  while (++first != last) {
    value = value + *first;
    *++result = value;
  }
  //注意返回的是result + (last - first)的位置,即当前被赋值末尾元素的下一个位置
  return ++result;
}

//partial_sum算法,版本一
template <class InputIterator, class OutputIterator>
OutputIterator partial_sum(InputIterator first, InputIterator last,
                           OutputIterator result) {
  //处理特殊情况,若first等于last,直接返回
  if (first == last) return result;
  //将*result赋值为*first
  *result = *first;
  //从first + 1开始遍历累加,并将结果返回
  return __partial_sum(first, last, result, value_type(first));
}

//这是针对提供了BinaryOperation的partial_sum算法版本实现的
template <class InputIterator, class OutputIterator, class T,
          class BinaryOperation>
OutputIterator __partial_sum(InputIterator first, InputIterator last,
                             OutputIterator result, T*,
                             BinaryOperation binary_op) {
  //不同之处在于之前的累加操作换成了binary_op二元操作
  T value = *first;
  while (++first != last) {
    value = binary_op(value, *first);
    *++result = value;
  }
  return ++result;
}

//partial_sum版本二,提供了自己的二元操作
template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator partial_sum(InputIterator first, InputIterator last,
                           OutputIterator result, BinaryOperation binary_op) {
  if (first == last) return result;
  *result = *first;
  return __partial_sum(first, last, result, value_type(first), binary_op);
}
adjacent_difference

该函数用于计算[first, last)中相邻元素之间的差。它将*result的值赋为*first,然后在[first+1, last)范围内的元素,分别计算*(first) - *(first-1)的值,然后分别赋值给*(result + 1)。
在不使用自己提供的binary_op情况下,它和partial_sum互为逆运算。比如{1, 2, 3, 4, 5},执行adjacent_difference之后,结果为{1, 1, 1, 1, 1},然后再对{1, 1, 1, 1, 1}执行partial_sum,结果又恢复成了原样,为{1, 2, 3, 4, 5}。

//该函数实现了adjacent_difference函数的主要功能,供adjacent_difference调用。和__partial_sum的实现很像,就是执行的二元操作不一样而已。
template <class InputIterator, class OutputIterator, class T>
OutputIterator __adjacent_difference(InputIterator first, InputIterator last,
                                     OutputIterator result, T*) {
  T value = *first;
  while (++first != last) {
    T tmp = *first;
    *++result = tmp - value;
    value = tmp;
  }
  return ++result;
}

//adjacent_difference,版本一
template <class InputIterator, class OutputIterator>
OutputIterator adjacent_difference(InputIterator first, InputIterator last,
                                   OutputIterator result) {
  if (first == last) return result;
  *result = *first;
  return __adjacent_difference(first, last, result, value_type(first));
}

//为提供了binary_op的adjacent_difference版本提供主要操作
template <class InputIterator, class OutputIterator, class T,
          class BinaryOperation>
OutputIterator __adjacent_difference(InputIterator first, InputIterator last,
                                     OutputIterator result, T*,
                                     BinaryOperation binary_op) {
  T value = *first;
  while (++first != last) {
    T tmp = *first;
    *++result = binary_op(tmp, value);
    value = tmp;
  }
  return ++result;
}

//adjacent_difference,版本二
template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator adjacent_difference(InputIterator first, InputIterator last,
                                   OutputIterator result,
                                   BinaryOperation binary_op) {
  if (first == last) return result;
  *result = *first;
  return __adjacent_difference(first, last, result, value_type(first),
                               binary_op);
}
power

该函数是SGI专属的算法,不在STL的标准中。它的作用是计算x的n次方,当然也可以自己指定运算的类型,比如加法除法之类的。

// Returns x ** n, where n >= 0.  Note that "multiplication"
//  is required to be associative, but not necessarily commutative.

//指定运算类型    
template <class T, class Integer, class MonoidOperation>
T power(T x, Integer n, MonoidOperation op) {
  if (n == 0)
    return identity_element(op);
  else {
    //当n为偶数,不断的执行op,然后将n/2,直到n为奇数
    while ((n & 1) == 0) {
      n >>= 1;
      x = op(x, x);
    }
    //对n为奇数时进行计算
    T result = x;
    n >>= 1;
    while (n != 0) {
      x = op(x, x);
      if ((n & 1) != 0)
        result = op(result, x);
      n >>= 1;
    }
    return result;
  }
}

//调用上面的版本,通过multiplies<T>()表示做乘法运算
template <class T, class Integer>
inline T power(T x, Integer n) {
  return power(x, n, multiplies<T>());
}

上面计算x的n次方的计算方式并不是依次相乘,而是采用的快速幂算法。区分奇偶,计算x^n的值,只需要O(logn)的复杂度,而不是O(n)。
快速幂算法的公式如下:

  • a^b = (a^2)^b/2,b为偶数
  • a^b = (a^2)^b/2*a,b为奇数

比如2的4次方,并没有采用(2)*(2)*(2)*(2)这样依次相乘的算法,而是采用(2*2)*(2*2),这样的做法,这种只用2次运算,而依次相乘需要4次运算。

itoa

该函数由SGISTL提供,并不在STL标准中。
它并不是那个C语言里面实现的整数转字符串的函数。
而是在[first, last)区间内将元素的值依次设置为value, value + 1, value + 2......
这是一个质变算法,改变了传入的迭代器范围指向的元素的值。

template <class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value) {
  while (first != last) *first++ = value++;
}

小结

本小节对stl_numeric.h中的算法进行了分析,里面大部分算法都很简单,也就power算法稍微需要理解下,如果有算法基础也很容易理解。除了注重算法本身,也要注意它是如何实现泛化的,这点同样也很重要。

微信小程序推送微信服务号模板消息 微信小程序中发送微信服务号模板消息,无需用户手动确认订阅,无需绑定开放平台,无需使用UnionId。 阅读详情

相关推荐

Metal ECO实战:如何在不修改底层掩模的情况下修复芯片时序问题

本文深入探讨了Metal ECO技术在芯片设计中的应用,这是一种在不修改底层晶体管掩模的前提下,仅通过调整金属连线和替换预置填充单元来修复时序问题的“微创手术”。文章详细解析了其原理、适用场景、关键操作流程与命令,并分享了实战中的高级技巧与常见陷阱,为面临流片前时序违例的工程师提供了宝贵的修复指南。

wdx0123456的博客 430

标准库头文件:numeric

1.常用操作 iota(vec.begin(), vec.end(), 2);//将vec填充成2开始的递增序列 accumulate(vec1.begin(), vec1.end(), 0);//累加区间内的和,初值是0 reduce(vec1.begin(), vec1.end(), 0);//累加区间内的和,初值是0,和accumulate相似,但是执行速度更快,C++17支持 inne...

zhuikefeng的博客 480

计算机模拟爆破过程,基于LSDYNA岩石爆破模拟建模分析

原标题:基于LSDYNA岩石爆破模拟建模分析 Ls Dyna岩石爆破模拟仿真作者:dyna_focus擅长领域:dyna/abaqus/hypermesh一、 数值模型的建立1.1 单元及算法的选择岩石,炸药,空气都采用solid164实体单元。岩石采用常应力实体单元,该种单元属于纯粹的lagrange算法,该种算法单元网格附着在材料上,随着材料的流动而产生单元网格的变形,但是在结构变形巨大时,有...

weixin_29494379的博客 7314

MyTinySTL阅读笔记---算法

算法

c++小白的博客 1168

AntV G6边动画实战:手把手教你实现数据流向箭头与虚线流动效果

本文详细解析了如何使用AntV G6实现数据流向箭头与虚线流动效果,通过自定义边动画提升数据可视化的动态表现力。从基础环境搭建到核心概念讲解,再到虚线流动动画和箭头路径动画的具体实现与参数调控,帮助开发者掌握G6边动画的高级技巧,适用于网络流量监控、数据传递等场景。

weixin_28487433的博客 265

保姆级教程:用C++逆向解析通达信shm.tnf文件(附完整代码与偏移量详解)

本文提供了一份详细的C++逆向工程教程,指导开发者如何解析通达信的shm.tnf文件。通过分析文件结构、定位关键字段并实现完整解析流程,帮助量化交易开发者高效获取沪市股票数据。教程包含完整代码示例和偏移量详解,适合金融数据本地化处理需求。

weixin_27945229的博客 523

STL源码剖析之数值算法<numeric.h>

一、accumulate 作用:初始化init,对区间[first,last)的迭代器i执行init += *i或init = binaryop(init,*i)。  template //版本1,用来计算init和[first,last)区间元素的总和 _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __in

HappyToEat的博客 615

告别DLTS的模糊地带:手把手教你用拉普拉斯深能级瞬态光谱(LDLTS)精准揪出半导体缺陷

本文详细介绍了拉普拉斯深能级瞬态光谱(LDLTS)技术在半导体缺陷检测中的高分辨率解决方案。相比传统DLTS,LDLTS通过拉普拉斯变换和正则化算法,将分辨率提升至1meV,有效解析复杂重叠缺陷谱,适用于硅、GaN等材料的精确缺陷分析。文章涵盖LDLTS原理、系统搭建、测量流程及工业应用案例,为半导体工艺优化提供强大工具。

weixin_29238147的博客 193

STL源码剖析——数值算法stl_numeric.h

本文讲解了STL算法中的数值算法,在源码中给出了详细的剖析,同时给出例子进行说明。

关注校招求职,微信号:job_campus 1886

AGV路径规划实战:如何用Python+ROS实现激光SLAM导航(附避障代码)

本文提供了一份基于Python和ROS实现AGV激光SLAM导航的实战指南。内容涵盖从Docker环境搭建、激光雷达数据处理、Gmapping建图,到Move_Base全局/局部路径规划与TEB局部规划器配置的全流程。重点解析了如何通过参数调优实现稳定导航,并附带了紧急避障代码,帮助开发者快速构建具备自主路径规划与实时避障能力的AGV系统。

pepsi的博客 1234

LoRa学习:LoRa通信调制解调的实现原理与性能

LoRa学习:LoRa调制解调原理与性能 1、LoRa调制解调器原理 LoRa调制解调器采用专利扩频调制和前向纠错技术。与传统的FSK、OOK调制技术相比,LoRa扩大了无线通讯链路的覆盖范围(实现了远距离无线传输),提高了链路的鲁棒性。。 开发人员可调整扩频因子和纠错率这两个参数,从而平衡通讯时的带宽占用、通信速率、空中包的存活时间、以及抗干扰性等。。 LoRa调制解调器...

HowieXue 薛永浩的博客 3万+

STL 简单 <stl_numeric.h> 算法的实现

1.简介 在STL中,算法可以大致分为两类:质变算法、非质变算法。质变算法会改变操作对象的值,非质变算法不会改变操作对象的值。所有的STL算法都作用在迭代器(iterator)所标识的区间上。          本文介绍的数值算法包括: 1.      accumulate:计算 [ first,last ) 内所有元素的总和; 2.      adjacent_difference:计算

chengonghao的博客 758

从零开始:C#上位机集成YOLO完成摄像头目标追踪(保姆级教程)

新手入门C#上位机+YOLO做摄像头目标追踪,最忌讳的是“只抄代码,不懂逻辑”。这个教程不仅给了完整代码,还把核心原理和踩坑点都讲清楚了,新手跟着走,不仅能跑通demo,还能理解为什么这么写。如果你们在运行时遇到具体问题,比如模型导出失败、代码报错,都可以在评论区留言,我会一一解答。后续也可以出一期工业相机+YOLO目标追踪的教程,帮助大家把demo落地到实际生产中。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1030

SGISTL源码阅读二十六 数值算法 (stl_numeric.h)

SGISTL源码阅读二十六 数值算法 (stl_numeric.h) 前言 上一篇博客我们简要介绍了一下STL中的算法,所有的数值算法都是放在&lt;stl_numeric.h中的。 深入源码 accumulate 该算法是做累加操作,将指向范围的元素累加到init上,并且将init作为返回值返回,若init为0,则是计算迭代器指定范围值的累加和。要求迭代器类型至少为InputIterator /...

Lyn&Xx 403

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

SGISTL源码探究-STL中的算法(前言)

前言我们目前已经分析了STL中的六大组件的一半。剩下的还有算法、仿函数、配接器,已经分析了配置器、迭代器、容器部分。接下来进入到剩下的三大组件中最复杂的算法部分,关于STL中的算法,它实现了很多功能,但是分析这部分的时候我只打算选择一部分比较经典的算法进行分析(因为这部分的算法实在是太多了),只要掌握了分析的方法,以后自己遇到其他的STL算法或者感兴趣的,直接阅读源码就行了。概览大致分类STL中的算

Move_now的博客 589

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

SGISTL源码阅读 算法 前言

SGISTL源码阅读 算法 前言 STL有六大组件,我们已经分析了空间配置器、迭代器和容器,现在将进入对算法的学习。 STL中实现了很多极具复用价值的算法,排序(sorting),查找(searching),排列组合(permutation),用于数据移动、复制、删除、比较、组合、运算等的算法。所有STL算法都作用在由迭代器[first,last)所标示出来的范围内,在进入正式分析算法之前,我们先...

Lyn&Xx 391

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

《STL源码剖析》---stl_numeric.h阅读笔记

STL中的数值算法。包括累加、乘幂、计算差值。

KangRoger的专栏 2059

STL源码剖析(十八)数值算法<stl_numeric.h>

namespace std _GLIBCXX_VISIBILITY(default) { template<typename _ForwardIterator, typename _Tp> void iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value) { // concept requirements __glibcxx_function_requires(_

mei_true的博客 319

《STL源码剖析》chapter6 算法

STL算法概述 所有泛型算法的前两个参数都是一对迭代器,通常称为first和last,用以标示算法的操作区间,该区间是一个前闭后开区间,即[first,last)。 由前面章节我们知道,STL中迭代器可以分为5类,在每一个STL算法的声明中,都表现出它所需要的最低程度的迭代器类型。 所有数值算法,包括adjacent_difference(),accumulate(),inner_product(),partial_sum()等等,都实现于stl_numeric.h文件中,这是个内部文件,STL规定用户必须

qq_39621037的博客 148

C++程序员应了解的那些事(32)STL 源码剖析-算法stl_numeric.h

<1>accumulate 描述:计算 init 和 [first, last) 内所有元素的总和 源码: //version1-普通操作版本 template <class InputIterator, class T> T accumulate(InputIterator first, InputIterator last, T init) { for ( ; first != last; ++first) init = init + *first; re.

qfturauyls的博客 247

C++ STL数值算法(头文件numeric内)

accumulate //版本1 template &lt;typename InputIterator, typename T&gt; T accumulate(InputIterator first, InputIterator last, T init) { for ( ; first != last; ++first) init = init + *first; return ...

程序人生 4931

《STL源码剖析》第六章笔记

文章目录复杂度标记法仿函数(functor)数值(numeric)算法错误?智能指针ostream_iteratoriotainserter()reverse_iterator辗转相除法可以进行小改进?建议反复学习的算法列表 复杂度标记法 // 《STL源码剖析》,p287 如果有任何正值常数 ccc 和 N0N0N0,使得当 N≥N0N \ge N_0N≥N0​ 时,T(N)≤cF(N)T(N) \le cF(N)T(N)≤cF(N),那么我们便可将 T(N)T(N)T(N) 的复杂度表示为 O(F(N

荣书的博客 328

stl-numeric库使用

文章目录accumulatepartial_sumadjacent_diffentenceinner_productiota accumulate 累加运算。它的特点是参数中有初始值。 template <class InputIterator, class T> T accumulate (InputIterator first, InputIterator last, T init...

Starr 389

算法之快速幂运算的实现方法

快速幂运算(反复平方法) 先来看一道题目:题目链接 本题代码在最后哦~ 快速幂运算的优势: 1.可用来算大数的幂的一种算法。 2.其时间复杂度为 O(log₂N), 如果我们使用循环来计算的话,那么时间复杂度就是 O(n) ,与朴素的O(N)相比效率有了极大的提高。 快速幂算法的核心思想:每一步都把指数分成两半,而相应的底数做平方运算。 如这张图片上所写的计算2的n次方所示,可以进行对底数做平方,幂做除2运算。 算法如何实现? 首先我们要知道对于幂是偶数时我们可以这样操作,如果幂是奇数呢? 如计算123的

JixTlhh的博客 2788

STL algorithm/numeric 函数总结

STL algorithm函数总结一级目录 一级目录

Yang_137476932的博客 972

STL之numeric

.

https://gitee.com/liuyuan185442111/chest-view 792
上一篇: SGISTL源码探究-STL中的算法(前言)
下一篇: Centos7下一步一步安装YCM插件(附vimrc配置文件)
UKey_
博客等级 码龄10年 258粉丝 186原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值