矩阵

发霉日记 Day1

倾然丶 夕夏残阳落幕 提交于 2020-01-31 00:32:21
今日目标 矩阵快速幂 完成矩阵快速幂模板 矩阵快速幂的相关运用 刷题 矩阵快速幂 矩阵快速幂是将矩阵乘法和快速幂进行结合,对递推式进行快速运算的一种方法。 矩阵乘法 假如矩阵a有m列s行,矩阵b有s列n行,那么他们的乘积是一个m行n列的矩阵。 如图所示,矩阵a有2行3列,矩阵b有3行2列,那么矩阵c就是一个2*2的矩阵。 矩阵乘法的规则就是a矩阵的m行与b矩阵的n列分别相乘。 a矩阵的行必须b矩阵的列相等才能进行矩阵乘法 快速幂 int QuickPow(int x,int N) { int res = x;//底数 int ans = 1;//和 while(N) { if(N&1)//判断二进制数最后位是否为1 //如果为1 { ans = ans * res;//将和与当前底数相乘得到新的和 } res = res*res;//更新底数 N = N>>1;//将二进制数后移一位,相当于/2 } return ans; } 快速幂就是将幂拆解 对于2 18 ,根据18的二进制数1 0 0 1 0,我们可以将2 8 拆解为(2 16 )*(2 2 )=2 18 。 矩阵快速幂的实现 矩阵快速幂 = 对矩阵使用快速幂算法 具体实现原理为,矩阵取代快速幂算法中的底数,矩阵乘法取代快速幂中的算数乘法。 矩阵快速幂模板 struct matrix { int m [ maxx ] [

剑指offer-12. 矩阵中的路径

跟風遠走 提交于 2020-01-31 00:13:54
判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向上下左右移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 public class Solution { private int [ ] [ ] next = { { 0 , 1 } , { 0 , - 1 } , { 1 , 0 } , { - 1 , 0 } } ; private int rows ; private int cols ; public boolean hasPath ( char [ ] matrix , int rows , int cols , char [ ] str ) { this . rows = rows ; this . cols = cols ; char [ ] [ ] matArr = getMatrix ( matrix ) ; boolean [ ] [ ] markarr = new boolean [ rows ] [ cols ] ; for ( int i = 0 ; i < rows ; i ++ ) { for ( int j = 0 ; j < cols ; j ++ ) { if ( backTracking ( matArr , 0 , i , j , str ,

[SHOI 2013]超级跳马

江枫思渺然 提交于 2020-01-30 23:20:16
Description 题库连接 现有一个 \(n\) 行 \(m\) 列的棋盘,一只马欲从棋盘的左上角跳到右下角。每一步它向右跳奇数列,且跳到本行或相邻行。跳越期间,马不能离开棋盘。试求跳法种数,取模。 \(1\leq n\leq50,2\leq m\leq 10^9\) Solution 令 \(f_{i,j}\) 表示在第 \(i\) 列第 \(j\) 行的方案数。那么, \(f_{i,j}=\sum\limits_{k=1}^i\text{odd}(i-k)\cdot(f_{k,j-1}+f_{k,j}+f_{k,j+1})\) 。 显然如果我们分奇偶做一个前缀和的话就可以 \(O(1)\) 转移。 由于 \(n\) 比较大,并且决策(转移)比较少,那么我们考虑用矩乘法优化。构造 \(1\times n\) 的状态矩阵 \(\mathbf{A_n}\) ,第 \(1\) 行第 \(i\) 列表示从左上角到 \((n,i)\) 有多少种方法。 显然 \(\mathbf{A_n}[1][1]=1\) 。构造状态矩阵 \(\mathbf{S}=\begin{bmatrix}\mathbf{A_n} &\mathbf{A_{n-1}}\end{bmatrix}\) 。 再构造转移矩阵 \(\mathbf{T}=\begin{bmatrix}\mathbf{V} &\mathbf{I

PA=LU

雨燕双飞 提交于 2020-01-30 22:49:39
P A = L U PA=LU P A = L U 对矩阵 A A A 做 L U LU L U 分解(考虑行交换) A = [ a 11 a 12 a 13 a 14 a 21 a 22 a 23 a 24 a 31 a 32 a 33 a 34 a 41 a 42 a 43 a 44 ] A = \begin{bmatrix} a_{11} & a_{12} & a_{13} & a_{14} \\ a_{21} & a_{22} & a_{23} & a_{24} \\ a_{31} & a_{32} & a_{33} & a_{34} \\ a_{41} & a_{42} & a_{43} & a_{44} \end{bmatrix} A = ⎣ ⎢ ⎢ ⎡ ​ a 1 1 ​ a 2 1 ​ a 3 1 ​ a 4 1 ​ ​ a 1 2 ​ a 2 2 ​ a 3 2 ​ a 4 2 ​ ​ a 1 3 ​ a 2 3 ​ a 3 3 ​ a 4 3 ​ ​ a 1 4 ​ a 2 4 ​ a 3 4 ​ a 4 4 ​ ​ ⎦ ⎥ ⎥ ⎤ ​ 第一步,将矩阵 A A A 的第一列元素 a 11 , a 21 , a 31 , a 41 a_{11},a_{21},a_{31},a_{41} a 1 1 ​ , a 2 1 ​ , a 3 1 ​ , a 4 1 ​

矩阵相乘优化(Gemm)

瘦欲@ 提交于 2020-01-30 16:35:02
一、参考链接 http://tvm.d2l.ai/ https://www.cs.utexas.edu/users/pingali/CS378/2008sp/papers/gotoPaper.pdf https://zhuanlan.zhihu.com/p/65436463 https://github.com/flame/how-to-optimize-gemm/ 二、矩阵相乘优化方法 假设矩阵C = 矩阵A * 矩阵B; 矩阵A的shape为(M, K),矩阵B的shape为(K, N),矩阵C的shape为(m,n)。 普通的矩阵为 A的一行乘以B的一列,如下图:     c/c++/python基本上是以行存储优先的,本文将以行存储优先作为基础进行优化分析。 考虑两种情况: (1)当AB矩阵较小时,根据计算机结构可知,当从RAM中读取AB矩阵内存,根据局部性原理可以将AB矩阵放到cache中,因为cpu访问cache比访问主存的快。   (2)当AB矩阵较大时,超过cache大小时,根据矩阵乘的普通方法,由于访问“行优先存储的B矩阵”的时候内存不连续(读取B矩阵的一列),造成缓存cache频繁的换入换出,从RAM读取内存的次数大于AB矩阵的大小。因此第一种优化方法: 1. 向量化(SIMD)      向量化可以使一条指令并行的使多个相同操作数执行相同的操作

shader入门精要读书笔记06 数学基础

倖福魔咒の 提交于 2020-01-30 14:50:39
第四章 数学基础 一、坐标系 笛卡尔坐标系,分为二维三维。 二维坐标系 OpenGL是左下角为0,DirectX是左上角。 三维坐标系,3个坐标轴也被称为基矢量,长度为1的基矢量叫做标准正交基,长度不唯1的叫正交基。 三维笛卡尔坐标系又分为左手坐标系与右手坐标系。 Unity使用的是左手坐标系,摄像头的观察空间是右手坐标系(摄像头前方为z轴的负方向)。 二、点和矢量 矢量:有方向有模,没有位置。 点:只是一个位置。 矢量的加减乘除运算,模运算。 单位矢量:被归一化的矢量。通过在矢量上方加个^来表示是矢量的模。 单位矢量的运算:通过矢量除以矢量的模来进行计算。 单位矢量计算通常使用在法线方向、光源方向等。 矢量的点积(内积/点乘): 点积就是可以确定两个矢量的方向关系。投影长度=标量。 点乘结果>0 :两个矢量方向关系为<90°。(=0 : 垂直,<0 : >90°) 求适量的模可以将矢量对其自身进行点乘,运算后开方。 a·b=|a||b|cos夹角 矢量的叉积(外积/叉乘): 叉积结果是矢量,不满足交换律,叉积的结果是得到一个同时垂直于这两个矢量的新矢量。 使用左手定则,右手定则来判断在不同坐标系中,新得到的矢量方向。 |a×b|=|a||b|sin夹角 我们可以通过点乘(cos值)来确定某两个矢量的夹角关系。 还可以通过叉乘判断一个面的正面反面(通过确定面上的三个点的顺时针

二维数组数组详解

ぐ巨炮叔叔 提交于 2020-01-30 12:49:31
转载自: 胡小兔博客,https://www.cnblogs.com/RabbitHu/p/BIT.html %%大连市理科状元。 “高级”数据结构——树状数组! ※本文一切代码未经编译,不保证正确性,如发现问题,欢迎指正! 1. 单点修改 + 区间查询 最简单的树状数组就是这样的: void add(int p, int x){ //给位置p增加x while(p <= n) sum[p] += x, p += p & -p; } int ask(int p){ //求位置p的前缀和 int res = 0; while(p) res += sum[p], p -= p & -p; return res; } int range_ask(int l, int r){ //区间求和 return ask(r) - ask(l - 1); } 2. 区间修改 + 单点查询 通过“差分”(就是记录数组中每个元素与前一个元素的差),可以把这个问题转化为问题1。 查询 设原数组为 a [ i ] a[i], 设数组 d [ i ] = a [ i ] − a [ i − 1 ] ( a [ 0 ] = 0 ) d[i]=a[i]−a[i−1](a[0]=0),则 a [ i ] = ∑ i j = 1 d [ j ] a[i]=∑j=1id[j],可以通过求 d [ i ] d[i

剑指offer-矩阵覆盖

故事扮演 提交于 2020-01-30 11:39:32
题目:矩阵覆盖 题目描述:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 思路:此题和前面裴波那切类题是一样的,尤其是和那个上楼梯的题; 找到递推式:f(n) = f(n-1) + f(n-2), (n > 2) 对于这类题的变形 相应的结论应该是: (1)1 * 3方块 覆 盖3*n区域:f(n) = f(n-1) + f(n - 3), (n > 3) (2) 1 *4 方块 覆 盖4*n区域:f(n) = f(n-1) + f(n - 4),(n > 4) 更一般的结论,如果用1*m的方块覆盖m*n区域,递推关系式为f(n) = f(n-1) + f(n-m),(n > m)。 1 public class Solution { 2 public int RectCover(int n) { 3 if(n==0)return 0; 4 if(n==1)return 1; 5 if(n==2)return 2; 6 int[]dp=new int[n+1]; 7 dp[0]=0; 8 dp[1]=1; 9 dp[2]=2; 10 for(int i=3;i<=n;i++){ 11 dp[i]=dp[i-1]+dp[i-2]; 12 } 13 return dp[n]; 14 } 15 } 来源:

C语言初阶——4.扩展:数组

…衆ロ難τιáo~ 提交于 2020-01-30 10:04:58
C语言初阶——4.扩展:数组 1. 返回值含义 返回值有时存在两种情况:合法值和非法值。 如果有非法值的情况,通常使用一些特定的值指代特殊情况。例如:数组下标只能是0和正数。我们实现数组查找元素下标时,存在找不到元素的情况,这时,使用 -1 可以作为这种情况的返回值。 返回值的含义以及值是人为定义的。 2. 二维数组指针用法 一维数组指针用法 No. 操作 下标 指针 1 第 i 个元素值 arr[i] *(arr+i) 2 第 i 个元素地址 &arr[i] arr+i 二维数组指针用法 No. 操作 下标 指针 1 第 i 行第 j 列元素值 arr[i][j] *(*(arr+i)+j) 2 第 i 行第 j 列元素地址 &arr[i][j] *(arr+i)+j 在二维数组中 a[i] 就是一个一维数组。 问题 二维数组数组名是第一个元素的首地址吗? 试一下下面的代码 # include <stdio.h> int main ( ) { int days [ 4 ] [ 3 ] = { 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 } ; printf ( "days[0]\t\t = %p\n&days[0][0]\t = %p\n" , days [ 0 ] , & days [ 0 ] [ 0 ]

算法:回溯法 矩阵中的路径

不羁岁月 提交于 2020-01-30 10:03:44
题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径,路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子 利用回溯法:直接上代码 public static boolean hasPath(char[][] matrix,char[] str){ int rows= matrix.length; int cols = matrix[0].length; boolean[][] visited = new boolean[rows][cols]; int pathLength = 0; for(int row = 0 ; row < rows ; row++){ for(int col = 0 ; col < cols ; col++){ if(hasPathCore(matrix,rows,cols,row,col,str,pathLength,visited)){ return true; } } } return false; } private static boolean hasPathCore(char[][] matrix, int rows, int cols, int row, int col, char[] str, int pathLength,