Numpy 学习笔记——3. 数组的线性代数运算
NumPy 提供了比较丰富的线性代数运算功能,主要集中在 numpy.linalg 模块中,下面罗列一些基础的操作,主要针对一维和二维数组,对于其它高维数组的语义可能不太符合直觉。 重要函数 点积 np.dot np.dot() 函数可以计算两个向量的点积,最基本的用法例如 1234a = np.array([1, 2, 3], dtype=np.float64)b = np.array([4, 5, 6], dtype=np.float64)np.dot(a, b) # np.float64(32.0)# 1*4 + 2*5 + 3*6 = 32 np.dot(a, b)的完整语义需要根据两个数组的维度来区分: 第一类情况: 如果其中一个是标量,那么就是进行(逐元素的)乘法,等效于 np.multiply(a, b) 或 a * b。 第二类情况: 如果 a 是 \(N\) 维数组,b 是一维数组,那么会沿着两者的最后一个轴求和,得到 \(N-1\) 维数组。 (特例,标准情况)如果两者都是尺寸为 (m,) 的一维数组,那么就是标准的向量内积,结果是一个标量。 (特例...
Numpy 学习笔记——2. 数组的变换和基本运算
数组的拷贝 Python 本身有深拷贝和浅拷贝等复杂的概念,对于多层列表等数据结构,对应的行为差异非常明显。 但是 Numpy 的 ndarray 数组无论形状如何,在内存中始终是连续存储的,高维数组并不是数组的数组, 因此并没有深拷贝和浅拷贝的明显差异。 和其它 Python 数据一样,在函数传参过程中对 ndarray 数组的传递并不会触发任何的拷贝行为。 为了获取一个 ndarray 数组的完整拷贝,可以使用 ndarray.copy() 方法,例如 12345a = np.array([1, 2, 3])b = a.copy()b[0] = 100a # array([1, 2, 3]) 上述测试代码表明,拷贝得到的是完全独立的数组,修改不会相互影响。 也可以使用numpy.copy()函数,例如 12a = np.array([1, 2, 3])b = np.copy(a) ndarray.copy() 方法和 numpy.copy() 函数的行为是基本一致的,都是获取原数组的拷贝,但是两者关于内存排布参数的默认值有细微差异,可以参考具体文档。 数组的视图 为了优化计...
Numpy 学习笔记——1. 数组的创建和索引
Numpy 是一个用于科学计算的 Python 扩展库,虽然不是 Python 标准库,但是已经是 Python 在科学计算、机器学习等领域毋庸置疑的基础库,很多主流的 Python 库都依赖 Numpy。 1import numpy as np 一个循序渐进的入门笔记的内容组织比较麻烦,我也并不打算这么做,这个笔记的内容会围绕一些关键点展开, 主要参考 Numpy 的官方资料。 ndarray 基本概念 np.ndarray (别名 np.array)是 Numpy 的核心数据类型,可以用于存储 n 维数组,并提供了大量相关操作方法。 它与 Python 的 list 类型类似,但是存在更多限制:只能存储同类型数据,并且尺寸是固定且规则的,即不允许各个元素长短不一的数组。 这些限制使得 ndarray 的运算非常高效(直接调用底层的 C/C++ 实现)。 但是有一点不足的是:Numpy 没有提供稀疏矩阵的数据结构,需要时可以使用其它包提供的稀疏矩阵。 我们主要关注一维数组和二维数组,例如 123array([1, 2, 3]) # shape=(3,)array([[1, ...
MATLAB 高性能编程笔记
记录一些常用的 MATLAB 编程技巧/规范,目标是写出高性能的 MATLAB 代码。主要参考官方文档中的提升性能的方法。 基础 关于代码结构 MATLAB 提供了很多方式来执行代码:命令行 vs 脚本 vs 函数,绝大多数代码在不同方式中执行都是等效的,但是考虑优化就不是一回事了,通常的运行效率关系为:命令行 < 脚本 < 函数,也就是说函数的执行速度通常是最快的。 基于模块化编程的思维,避免使用过大的单一文件,考虑将其中重复使用的功能拆分为简洁的函数文件,这种做法可以降低首次运行的成本。 优先使用局部函数而非嵌套函数,嵌套函数可以直接访问外层函数的变量(按照引用捕获),这会影响效率,更好的做法是将所有需要的变量以函数参数的形式显式传递。 交互式地在命令行中调用某些内置函数,相比于从脚本文件中调用,可能会有不一样的结果。 关于内置函数 避免重载内置函数,尤其不要对标准 MATLAB 数据类重载内置函数。 在可选的情况下,优先考虑使用 MATLAB 的内置函数来实现数组的常用运算,因为内置函数可能是直接使用底层语言实现的,至少也经过了大量的优化,比我们直接实现的效...
MATLAB 踩坑记录
记录一下 MATLAB 踩过的小坑,MATLAB 的各种内置函数的用法实在是太奇怪了,一个小细节就可以搞出各种问题。 矩阵偏移 函数 circshift 可以用于向量或矩阵的循环偏移,不会修改原始数据。 向量偏移 123456A = [1, 2, 3, 4, 5];circshift(A, 1)% [5, 1, 2, 3, 4]circshift(A, -1)% [2, 3, 4, 5, 1] 矩阵的偏移就比较复杂了,按照前面的做法会以行为整体进行偏移!!! 1234567A = [1 2 3; 4 5 6; 7 8 9];circshift(A, 1);% 7 8 9% 1 2 3% 4 5 6 如果希望以列进行偏移,有两种方式,第一种方式是额外指定维数(传递两个标量) 1234567A = [1 2 3; 4 5 6; 7 8 9];circshift(A, 1, 2)% 3 1 2% 6 4 5% 9 7 8...
Cpp 多态方案对比——回字的四种写法
虽然C++没有直接提供interface,但是却提供了虚函数、模板类型等各种语法,使得我们可以用各种方式实现多态,这里我们不区分动态多态和静态多态,而是从设计一个框架的角度,分别使用四种方案实现: 虚函数(最简单直接的方式) std::function CRTP(最晦涩的方式) deducing this(可以视作CRTP的简化,不再需要将派生类作为模板参数传递,要求C++23) 需求 我们考虑这样一个需求: 基类A包括:(不可实例化) 主方法run:调用func1,func2和func3 实现方法func1 实现方法func2(多态,允许子类修改) 实现方法func3(多态,子类必须实现) 派生类B1:继承A 实现方法func3(多态,允许子类修改) 派生类B2:继承A 实现方法func3(多态,允许子类修改):调用func4 实现方法func4(多态,允许子类修改) 具体类C1:继承B2 实现方法func4 具体类C2:继承B2 实现方法func3 最终我们直接通过各种对象自身来调用run方法,达到如下效果: 12345678Running B1 ...
解读一份极其晦涩的 c++ 代码
事先声明,下面的各种语法技巧都是炫技式的,刻意降低代码的可读性,只是写着玩,在实际应用中是不会允许这么乱写的。 先来几个开胃菜。 开胃菜 (1) 嵌入网址? 下面这段代码看起来是在c++中直接嵌入了一个网址 1234567#include <iostream>int main(){ https://www.zhihu.com std::cout << "Hello World!" << std::endl; return 0;} 它确实是合法的c++代码,但是含义却并不是网址: 左半部分https: 是一个标签,可以通过goto跳转; 右半部分由于//的存在,就是一个注释,直接被忽略了。 下面的代码就更利于理解了 123456789#include <iostream>int main() {label: // 这是注释 std::cout << "Hello World!" << std::endl; ...
Jupyter notebook 本地和远程部署
整理一下 jupyter notebook 的各种使用方式。 本地部署 直接在本地主机上启动 jupyter notebook 服务是最简单的用法 1jupyter notebook 需要说明的是: jupyter 服务默认监听本机的 8888 端口,如果本机的 8888 端口已经被占用,在启动时会自动递增,改为 8889 端口等,也可以使用 --port 选项指定端口; jupyter 在启动时会尝试打开本地浏览器,或者手动通过 http://localhost:8888/ 访问即可,可以加上选项阻止自动开启浏览器 --no-browser; 默认只允许接收来自 localhost 的请求,可以使用 --ip 选项指定,例如--ip=0.0.0.0 代表允许所有的 ip 访问; 默认的工作目录是执行命令时所处的目录,可以在后面加上工作目录作为位置参数,例如 jupyter notebook /path/to/notebooks,还可以使用 --notebook-dir 选项指定,例如 --notebook-dir=/path/to/notebooks。 除了直接在前台运行,...
Python 包下载和虚拟环境管理
分成如下几个部分: pip:包下载安装 venv:虚拟环境管理 conda:包下载安装和 conda 环境管理 这些内容在不同的系统(Windows/Linux)中的实现细节各有不同,在不同的 shell(pwsh/bash/fish)中,对应的脚本实现也有差异,下面以 Linux + bash 为主,也会考虑 Windows + pwsh 的情况。 为了便于区分,本文中的虚拟环境特指使用 venv 创建的虚拟环境,conda 创建的虚拟环境则称为 conda 环境。 现在还有一些新的替代工具,例如 uv,但是它们只是简化使用,并没有本质区别。 pip 基本使用 使用 pip 可以安装 Python 包,常见形式为 1pip install <package_name> 例如安装进度条工具 tqdm 1pip install tqdm pip 会自动处理包的版本要求和依赖关系,依赖关系在不同系统下可能存在差异,例如: 在 Linux 上只会安装 tqdm 自身; 在 Windows 上会自动安装两个包:colorama, tqdm,前者是 tqdm 的依赖。...
星期算法
学习一下如何根据指定的年月日快速计算星期几,由于公历的规律性很强,将所有规律整理并不断简化就可以得到这种简便算法,有很多不同的变形算法,例如蔡勒公式,康威裁决日算法等,本文主要学习蔡勒公式。 公历 简要回顾一下公历:每年12个月,每个月可能有28、29、30、31天。 区分普通的年和闰年,非闰年有365天,闰年有366天,年份满足以下情况时为闰年: 年份除以100的余数不为0,除以4的余数为0 年份除以100的余数为0,并且除以400的余数为0 非闰年的12个月的天数依次为: 28天:2月 30天:4月、6月、9月、11月 31天:1月、3月、5月、7月、8月、10月、12月 闰年的12个月的天数依次为: 29天:2月 30天:4月、6月、9月、11月 31天:1月、3月、5月、7月、8月、10月、12月 由于公历于1582年10月正式建立,在这段时间以及更早的年份可能存在日期修正,细节比较复杂,不作讨论。 蔡勒公式 公式如下 \[ w = \left( y + \left[ \frac{y}4 \right] + \left[ \frac{c}4 \...
