【深度学习】ND4J-科学计算库
目录
简介
基础用法
基础信息
数组创建
打印数组
变更维度&堆叠
加减乘除
累加/最大/最小
转换操作
矩陈乘法
索引/迭代
深拷贝/引用传递/视图
引用传递
视图
深拷贝
其它
简介
ND4J主要是JVM的科学计算库,内置了很多计算方法,目的是以最低的RAM需求快速运行。主要特点是:
-
一个多功能的n维数组对象。
-
线性代数和信号处理函数。
-
多平台功能,包括GPU。
-
所有主要操作系统: win/linux/osx/android.
-
架构: x86, arm, ppc.
-
Nd4j的主要特点是具有多功能的n维阵列接口INDArray。为了提高性能,Nd4j使用堆外内存来存储数据。INDArray不同于标准Java数组。
基础用法
基础信息
创建数值为0的N维数组
INDArray xx = Nd4j.zeros(10);
System.out.println(xx);//运行结果
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]INDArray x = Nd4j.zeros(3, 4);
System.out.println(x);//运行结果
[[ 0, 0, 0, 0], [ 0, 0, 0, 0], [ 0, 0, 0, 0]]
同理,也支持三维、四维等,可以通过以下方法进行维度信息的查看:
// 数组的轴数(维度)。
int dimensions = x.rank();// 数组的维数。每个维度的大小。
long[] shape = x.shape();// 元素的总数。
long length = x.length();// 数组元素的类型。
DataType dt = x.dataType();
数组创建
要创建INDArray,可以使用ND4J类的静态工厂方法。
Nd4j.createFromArray函数通过重载,支持double、float、int、long类型,同时对各种类型最高支持四维。
double arr_2d[][]={{1.0,2.0,3.0},{4.0,5.0,6.0},{7.0,8.0,9.0}};
INDArray x_2d = Nd4j.createFromArray(arr_2d);double arr_1d[]={1.0,2.0,3.0};
INDArray x_1d = Nd4j.createFromArray(arr_1d);
可以使用函数zeros和ones创建用0和1初始化的数组
可以使用rand函数建用随机值初始化的数组
创建的INDArray的默认数据类型是float,有些重载允许您设置数据类型
INDArray x = Nd4j.zeros(5);
//运行结果
//[ 0, 0, 0, 0, 0], FLOATint [] shape = {5};
x = Nd4j.zeros(DataType.DOUBLE, 5);
//运行结果
//[ 0, 0, 0, 0, 0], DOUBLE// 对于更高的维度,可以提供形状数组。二维随机矩阵示例:
int[] shape = {4, 5};
INDArray x = Nd4j.rand(shape);//运行结果
[[ 0.5669, 0.0576, 0.8701, 0.9598, 0.6470], [ 0.2711, 0.8427, 0.2819, 0.6617, 0.5109], [ 0.0602, 0.2674, 0.6586, 0.9939, 0.4781], [ 0.4099, 0.9503, 0.2227, 0.4738, 0.3759]]
使用arange函数创建一个均匀空间值数组:
INDArray x = Nd4j.arange(5);
// [ 0, 1.0000, 2.0000, 3.0000, 4.0000]INDArray x = Nd4j.arange(2, 7);
// [ 2.0000, 3.0000, 4.0000, 5.0000, 6.0000]
linspace函数允许您指定生成的点数:
//开始数, 停止数, 个数.
INDArray x = Nd4j.linspace(1, 10, 5);
// [ 1.0000, 3.2500, 5.5000, 7.7500, 10.0000]// 对函数进行多点评估。
import static org.nd4j.linalg.ops.transforms.Transforms.sin;
INDArray x = Nd4j.linspace(0.0, Math.PI, 100, DataType.DOUBLE);
INDArray y = sin(x);
打印数组
如上图的例子,INDArray支持Java的toString()方法,可以直接通过System.out.println打印除结果
变更维度&堆叠
可以通过reshap函数进行维度的变更
int [] shape = {4,3};
//2维数组
x = Nd4j.arange(12).reshape(shape);
/*
[[ 0, 1.0000, 2.0000], [ 3.0000, 4.0000, 5.0000], [ 6.0000, 7.0000, 8.0000], [ 9.0000, 10.0000, 11.0000]]
*/
如果本身数据的数组不足以填满新的维度,则会报ND4JIllegalStateException异常
int [] shape = {4,3};
//2维数组
INDArray x = Nd4j.arange(11).reshape(shape);//运行结果
//org.nd4j.linalg.exception.ND4JIllegalStateException: New shape length doesn't match original length: [12] vs [11]. Original shape: [11] New Shape: [4, 3]
INDArray x = Nd4j.rand(3,4);
x.shape();
// [3, 4]INDArray x2 = x.ravel(); //转化成一列
x2.shape();
// [12]INDArray x3 = x.reshape(6,2).shape();
x3.shape();
//[6, 2]//注意x、x2和x3共享相同的数据。
x2.putScalar(5, -1.0);System.out.println( x);
/*
[[ 0.0270, 0.3799, 0.5576, 0.3086], [ 0.2266, -1.0000, 0.1107, 0.4895], [ 0.8431, 0.6011, 0.2996, 0.7500]]
*/System.out.println( x2);
// [ 0.0270, 0.3799, 0.5576, 0.3086, 0.2266, -1.0000, 0.1107, 0.4895, 0.8431, 0.6011, 0.2996, 0.7500]System.out.println( x3);
/*
[[ 0.0270, 0.3799], [ 0.5576, 0.3086], [ 0.2266, -1.0000], [ 0.1107, 0.4895], [ 0.8431, 0.6011], [ 0.2996, 0.7500]]
*/
可以使用vstack和hstack方法将数组堆叠在一起。
INDArray x = Nd4j.rand(2,2);
INDArray y = Nd4j.rand(2,2);x
/*
[[ 0.1462, 0.5037], [ 0.1418, 0.8645]]
*/y;
/*
[[ 0.2305, 0.4798], [ 0.9407, 0.9735]]
*/Nd4j.vstack(x, y);
/*
[[ 0.1462, 0.5037], [ 0.1418, 0.8645], [ 0.2305, 0.4798], [ 0.9407, 0.9735]]
*/Nd4j.hstack(x, y);
/*
[[ 0.1462, 0.5037, 0.2305, 0.4798], [ 0.1418, 0.8645, 0.9407, 0.9735]]
*/
加减乘除
使用INDArray方法对数组执行操作。
加法: arr.add(...), arr.addi(...)减法: arr.sub(...), arr.subi(...)乘法: arr.mul(...), arr.muli(...)除法 : arr.div(...), arr.divi(...)
对数组进行加减乘除操作,有两种类型
【1】in-place :在原有数组基础上变更,如add、sub
【2】复制:创建新的数组,将结果放在新数组中,如addi、subi
//复制
//返回一个新数组,并将标量添加到arr的每个元素。
arr_new = arr.add(scalar);
//返回一个新数组,它是arr和其他arr元素级别的加法。
arr_new = arr.add(other_arr); //In-place
arr_new = arr.addi(scalar);
arr_new = arr.addi(other_arr);
in-place运算符可以方便地将操作链接在一起。尽可能使用(in-place)运算符来提高性能,因为
复制运算符有新的数组创建开销。
注意,执行加减乘除操作时,必须确保基础数据类型相同。
int [] shape = {5};
INDArray x = Nd4j.zeros(shape, DataType.DOUBLE);
INDArray x2 = Nd4j.zeros(shape, DataType.INT);
INDArray x3 = x.add(x2);
// java.lang.IllegalArgumentException: Op.X 和 Op.Y must have the same data type, but got INT vs DOUBLE// 将x2转换为DOUBLE可以解决以下问题:
INDArray x3 = x.add(x2.castTo(DataType.DOUBLE));
累加/最大/最小
INDArray有实现累加/最值操作的方法,如 sum, min, max.
int [] shape = {2,3};
INDArray x = Nd4j.rand(shape);
x;
x.sum();
x.min();
x.max();
/*
[[ 0.8621, 0.9224, 0.8407], [ 0.1504, 0.5489, 0.9584]]
4.2830
0.1504
0.9584
*/
提供维度参数以在指定维度上应用操作:
INDArray x = Nd4j.arange(12).reshape(3, 4);
/*
[[ 0, 1.0000, 2.0000, 3.0000], [ 4.0000, 5.0000, 6.0000, 7.0000], [ 8.0000, 9.0000, 10.0000, 11.0000]]
*/ //每列的总和。
x.sum(0);
//[ 12.0000, 15.0000, 18.0000, 21.0000]//每行最小值
x.min(1);
//[ 0, 4.0000, 8.0000]//每行的累计和,
x.cumsum(1);
/*
[[ 0, 1.0000, 3.0000, 6.0000], [ 4.0000, 9.0000, 15.0000, 22.0000], [ 8.0000, 17.0000, 27.0000, 38.0000]]
*/
转换操作
Nd4j提供熟悉的数学函数,如sin、cos和exp,这些称为转换操作。结果作为INDArray返回。
import static org.nd4j.linalg.ops.transforms.Transforms.exp;
import static org.nd4j.linalg.ops.transforms.Transforms.sqrt;INDArray x = Nd4j.arange(3);
// [ 0, 1.0000, 2.0000]
exp(x);
// [ 1.0000, 2.7183, 7.3891]
sqrt(x);
// [ 0, 1.0000, 1.4142]
矩陈乘法
INDArray也支持矩阵运算,如下:
INDArray x = Nd4j.arange(12).reshape(3, 4);
/*
[[ 0, 1.0000, 2.0000, 3.0000], [ 4.0000, 5.0000, 6.0000, 7.0000], [ 8.0000, 9.0000, 10.0000, 11.0000]]
*/INDArray y = Nd4j.arange(12).reshape(4, 3);
/*
[[ 0, 1.0000, 2.0000], [ 3.0000, 4.0000, 5.0000], [ 6.0000, 7.0000, 8.0000], [ 9.0000, 10.0000, 11.0000]]
*/
// 矩阵乘积.
x.mmul(y);
/*
[[ 42.0000, 48.0000, 54.0000], [ 114.0000, 136.0000, 158.0000], [ 186.0000, 224.0000, 262.0000]]
*///点积
INDArray x = Nd4j.arange(12);
INDArray y = Nd4j.arange(12);
dot(x, y);
//506.0000
索引/迭代
获取某个位置的数据
INDArray x = Nd4j.arange(12);
// [ 0, 1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000, 11.0000]
//单一元素访问。其他方法: getDouble, getInt, ...
float f = x.getFloat(3);
// 3.0
转化为Java数组
//转换为Java数组。
float [] fArr = x.toFloatVector();
// [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0]
获取指定区间的数据
INDArray x2 = x.get(NDArrayIndex.interval(2, 6));
// [ 2.0000, 3.0000, 4.0000, 5.0000]
在x的副本上:从开始到位置6(不包括),将每2个元素设置为-1.0
//在x的副本上:从开始到位置6(不包括),将每2个元素设置为-1.0
INDArray y = x.dup();
y.get(NDArrayIndex.interval(0, 2, 6)).assign(-1.0);
//[ -1.0000, 1.0000, -1.0000, 3.0000, -1.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000, 11.0000]
y的反向副本
//y的反向副本。
INDArray y2 = Nd4j.reverse(y.dup());
//[ 11.0000, 10.0000, 9.0000, 8.0000, 7.0000, 6.0000, 5.0000, -1.0000, 3.0000, -1.0000, 1.0000, -1.0000]
对于多维数组,应该使用INDArray.get(NDArrayIndex...)。下面的示例演示如何遍历二维数组的行和列。注意,对于2D数组,我们可以使用getColumn和getRow便利方法。
// 在2d数组的行和列上迭代。
int rows = 4;
int cols = 5;
int[] shape = {rows, cols};INDArray x = Nd4j.rand(shape);
/*
[[ 0.2228, 0.2871, 0.3880, 0.7167, 0.9951], [ 0.7181, 0.8106, 0.9062, 0.9291, 0.5115], [ 0.5483, 0.7515, 0.3623, 0.7797, 0.5887], [ 0.6822, 0.7785, 0.4456, 0.4231, 0.9157]]
*/for (int row=0; row<rows; row++) {INDArray y = x.get(NDArrayIndex.point(row), NDArrayIndex.all());}
/*
[ 0.2228, 0.2871, 0.3880, 0.7167, 0.9951]
[ 0.7181, 0.8106, 0.9062, 0.9291, 0.5115]
[ 0.5483, 0.7515, 0.3623, 0.7797, 0.5887]
[ 0.6822, 0.7785, 0.4456, 0.4231, 0.9157]
*/for (int col=0; col<cols; col++) {INDArray y = x.get(NDArrayIndex.all(), NDArrayIndex.point(col));}
/*
[ 0.2228, 0.7181, 0.5483, 0.6822]
[ 0.2871, 0.8106, 0.7515, 0.7785]
[ 0.3880, 0.9062, 0.3623, 0.4456]
[ 0.7167, 0.9291, 0.7797, 0.4231]
[ 0.9951, 0.5115, 0.5887, 0.9157]
*/
深拷贝/引用传递/视图
引用传递
以下用法,仅仅只是指向x的指针,进行了引用传递,并未复制
INDArray x = Nd4j.rand(2,2);
//y和x指向同一个INDArray对象。
INDArray y = x;
视图
一些函数将返回数组的视图,并未进行数组的复制
INDArray x = Nd4j.rand(3,4);
INDArray x2 = x.ravel();
INDArray x3 = x.reshape(6,2);// 修改 x, x2 和 x3
x2.putScalar(5, -1.0); x
/*
[[ 0.8546, 0.1509, 0.0331, 0.1308], [ 0.1753, -1.0000, 0.2277, 0.1998], [ 0.2741, 0.8257, 0.6946, 0.6851]]
*/x2
// [ 0.8546, 0.1509, 0.0331, 0.1308, 0.1753, -1.0000, 0.2277, 0.1998, 0.2741, 0.8257, 0.6946, 0.6851]x3
/*
[[ 0.8546, 0.1509], [ 0.0331, 0.1308], [ 0.1753, -1.0000], [ 0.2277, 0.1998], [ 0.2741, 0.8257], [ 0.6946, 0.6851]]
*/
深拷贝
要复制数组,请使用dup方法。这将为您提供一个包含新数据的新数组。
INDArray x = Nd4j.rand(3,4);
INDArray x2 = x.ravel().dup();//现在只改变x2。
x2.putScalar(5, -1.0);
x
/*
[[ 0.1604, 0.0322, 0.8910, 0.4604], [ 0.7724, 0.1267, 0.1617, 0.7586], [ 0.6117, 0.5385, 0.1251, 0.6886]]
*/x2
// [ 0.1604, 0.0322, 0.8910, 0.4604, 0.7724, -1.0000, 0.1617, 0.7586, 0.6117, 0.5385, 0.1251, 0.6886]
其它
ND4J还有很多科学计算函数,具体可以查看文档
nd4j-api 1.0.0-M2.1 javadoc (org.nd4j)
相关文章:
【深度学习】ND4J-科学计算库
目录 简介 基础用法 基础信息 数组创建 打印数组 变更维度&堆叠 加减乘除 累加/最大/最小 转换操作 矩陈乘法 索引/迭代 深拷贝/引用传递/视图 引用传递 视图 深拷贝 其它 简介 ND4J主要是JVM的科学计算库,内置了很多计算方法,目的…...
2024-01-29 ubuntu 用脚本设置安装交叉编译工具链路径方法,设置PATH环境变量
一、设置PATH环境变量的方法,建议用~/.bash_profile的方法,不然在ssh登录的时候可能没有设置PATH. 二、下面的完整的脚本,里面的echo "export PATH$build_toolchain_path:\$PATH" >> $HOME/.bashrc 就是把交叉编译路径写写到.bashrc设置…...
今年春节很多年轻人选择不买战袍,减少年货置办,「极简过年」,如何看待此现象?
近年来,春节期间出现了一种新的现象,越来越多的年轻人选择不买战袍,减少年货置办,采用“极简过年”的方式度过春节。对于这一现象,不同人有不同的看法。 首先,这种极简过年的方式符合当前社会的一些价值观…...
C语言·贪吃蛇游戏(下)
上节我们将要完成贪吃蛇游戏所需的前置知识都学完了,那么这节我们就开始动手写代码了 1. 程序规划 首先我们应该规划好我们的代码文件,设置3个文件:snack.h 用来声明游戏中实现各种功能的函数,snack.c 用来实现函数,t…...
Flask 入门2:路由
1. 前言 在上一节中,我们使用到了静态路由,即一个路由规则对应一个 URL。而在实际应用中,更多使用的则是动态路由,它的 URL是可变的。 2. 定义一个很常见的路由地址 app.route(/user/<username>) def user(username):ret…...
【C++】 C++入门— 基于范围的 for 循环
C 基于范围的for循环1 使用样例2 使用条件3 完善措施 Thanks♪(・ω・)ノ谢谢阅读!下一篇文章见!!! 基于范围的for循环 1 使用样例 使用for循环遍历数组,我们通常这么写: …...
C++——析构函数
C——析构函数 什么是析构函数 析构函数是C中的一个特殊的成员函数,它在对象生命周期结束时被自动调用,用于执行对象销毁前的清理工作。析构函数特别重要,尤其是在涉及动态分配的资源(如内存、文件句柄、网络连接等)…...
Vue3学习记录(二)--- 组合式API之计算属性和侦听器
一、计算属性 1、简介 计算属性computed(),用于根据依赖的响应式变量的变化,进行自动的计算,并返回计算后的结果。当依赖的响应式变量发生变化时,computed()会自动进行重新计算,并返回最新的计算结果。如果依赖的…...
react-virtualized实现行元素不等高的虚拟列表滚动
前言: 当一个页面中需要接受接口返回的全部数据进行页面渲染时间,如果数据量比较庞大,前端在渲染dom的过程中需要花费时间,造成页面经常出现卡顿现象。 需求:通过虚拟加载,优化页面渲染速度 优点࿱…...
Linux系统各目录作用
/etc文件系统 /etc 目录包含各种系统配置文件,下面说明其中的一些。其他的你应该知道它们属于哪个程序,并阅读该程序的m a n页。许多网络配置文件也在/etc 中。 1. /etc/rc或/etc/rc.d或/etc/rc?.d 启动、或改变运行级时运行的脚本或脚本的目录。 2. /…...
嵌入式系统学习(一)
嵌入式现状(UP经历): 大厂的招聘要求: 技术栈总结: 产品拆解网站: 52audio 方案查询网站iotku,我爱方案网, 主要元器件类型:...
重写Sylar基于协程的服务器(3、协程模块的设计)
重写Sylar基于协程的服务器(3、协程模块的设计) 重写Sylar基于协程的服务器系列: 重写Sylar基于协程的服务器(0、搭建开发环境以及项目框架 || 下载编译简化版Sylar) 重写Sylar基于协程的服务器(1、日志模…...
Linux之系统安全与应用续章
目录 一. PAM认证 1.2 初识PAM 1.2.1 PAM及其作用 1.2.2 PAM认证原理 1.2.3 PAM认证的构成 1.2.4 PAM 认证类型 1.2.5 PAM 控制类型 二. limit 三. GRUB加密 /etc/grub.d目录 四. 暴力破解密码 五. 网络扫描--NMAP 六. 总结 一. PAM认证 1.2 初识PAM PAM是Linux系…...
《HTML 简易速速上手小册》第7章:HTML 多媒体与嵌入内容(2024 最新版)
文章目录 7.1 在HTML中嵌入视频和音频7.1.1 基础知识7.1.2 案例 1:嵌入视频文件7.1.3 案例 2:嵌入音频文件7.1.4 案例 3:创建一个视频和音频混合的播放列表 7.2 使用 <iframe> 嵌入外部内容7.2.1 基础知识7.2.2 案例 1:嵌入…...
【CSS】移动端适配
移动端适配怎么做? 适配的目的是在屏幕大小不同的终端设备拥有统一的界面,让拥有更大屏幕的终端展示更多的内容。 meta viewport (视口) 移动端初始视口的大小默认是980px,因为世界上绝大多数PC网页的版心宽度为980px ,如果网页…...
DFS剪枝算法经典题目-挑选
4954. 挑选 - AcWing题库 给定一个包含 n 个正整数 a1,a2,…,an的集合。 集合中可能存在数值相同的元素。 请你从集合中挑选一些元素,要求同时满足以下所有条件: 被选中元素不少于 2 个。所有被选中元素之和不小于 l 且不大于 r。所有被选中元素之中最大…...
考研经验总结——考试期间
文章目录 一、订房二、看考场三、休息四、考前带宾馆的书五、安全 一、订房 我刚刚看了看,是9.10号订的酒店。你们可以提前向学长学姐打听你的考场在哪个学校(徐州的考生,考省外的学校是在矿大考试,考省内的学校是在江师大&#…...
vue3 源码解析(6)— lifecycle 生命周期的实现
前言 对于 vue3 的生命周期,我们经常性会去疑问,生命周期有哪些呢,它是怎么去实现的, 又是什么时候调用的。 vue3 生命周期有哪些 下面这个表格列出了所有选项式api生命周期钩子和组合式api生命周期钩子,以及他们的…...
three.js CSS2DRenderer、CSS2DObject渲染HTML标签
有空的老铁关注一下我的抖音: 效果: <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red;position: relative;"><…...
SECS/GEM300和半导体e84控制器
SECS(SEMI EQUIPMENT COMMUNICATIONS STANDARD 2)半导体设备通讯标准 GEM(Generic Equipment Model)定义了Fab中各个场景下设备行为及其所使用SECS消息。 GEM300也称为300mm标准,FAB是12寸设备的处理作业规范。主要包…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
