Opencv 三对角线矩阵(Tridiagonal Matrix)解法之(Thomas Algorithm)
1. 简介
三对角线矩阵(Tridiagonal Matrix),结构如公式(1)所示:
其中a1=0,cn=0。写成矩阵形式如(2):
常用的解法为Thomas algorithm,又称为The Tridiagonal matrix algorithm(TDMA). 它是一种高斯消元法的解法。分为两个阶段:向前消元(Forward Elimination)和回代(Back Substitution)。
向前消元(Forward Elimination):
c′i=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪cibicibi−aic′i−1;i=1;i=2,3,…,n−1(3)d′i=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪dibidi−aid′i−1bi−aic′i−1;i=1;i=2,3,…,n.(4)回代(Back Substitution):
xn=d′nxi=d′i−c′ixi+1;i=n−1,n−2,…,1.(5)
2.代码
- 维基百科提供的C语言版本:
void solve_tridiagonal_in_place_destructive(float * restrict const x, const size_t X, const float * restrict const a, const float * restrict const b, float * restrict const c)
{
/*
solves Ax = v where A is a tridiagonal matrix consisting of vectors a, b, c
x - initially contains the input vector v, and returns the solution x. indexed from 0 to X - 1 inclusive
X - number of equations (length of vector x)
a - subdiagonal (means it is the diagonal below the main diagonal), indexed from 1 to X - 1 inclusive
b - the main diagonal, indexed from 0 to X - 1 inclusive
c - superdiagonal (means it is the diagonal above the main diagonal), indexed from 0 to X - 2 inclusive
Note: contents of input vector c will be modified, making this a one-time-use function (scratch space can be allocated instead for this purpose to make it reusable)
Note 2: We don't check for diagonal dominance, etc.; this is not guaranteed stable
*/
/* index variable is an unsigned integer of same size as pointer */
size_t ix;
c[0] = c[0] / b[0];
x[0] = x[0] / b[0];
/* loop from 1 to X - 1 inclusive, performing the forward sweep */
for (ix = 1; ix < X; ix++) {
const float m = 1.0f / (b[ix] - a[ix] * c[ix - 1]);
c[ix] = c[ix] * m;
x[ix] = (x[ix] - a[ix] * x[ix - 1]) * m;
}
/* loop from X - 2 to 0 inclusive (safely testing loop condition for an unsigned integer), to perform the back substitution */
for (ix = X - 1; ix-- > 0; )
x[ix] = x[ix] - c[ix] * x[ix + 1];
}
- 本人基于Opencv的版本:
bool caltridiagonalMatrices(
cv::Mat_<double> &input_a,
cv::Mat_<double> &input_b,
cv::Mat_<double> &input_c,
cv::Mat_<double> &input_d,
cv::Mat_<double> &output_x )
{
/*
solves Ax = v where A is a tridiagonal matrix consisting of vectors input_a, input_b, input_c, and v is a vector consisting of input_d.
input_a - subdiagonal (means it is the diagonal below the main diagonal), indexed from 1 to X - 1 inclusive
input_b - the main diagonal, indexed from 0 to X - 1 inclusive
input_c - superdiagonal (means it is the diagonal above the main diagonal), indexed from 0 to X - 2 inclusive
input_d - the input vector v, indexed from 0 to X - 1 inclusive
output_x - returns the solution x. indexed from 0 to X - 1 inclusive
*/
/* the size of input_a is 1*n or n*1 */
int rows = input_a.rows;
int cols = input_a.cols;
if ( ( rows == 1 && cols > rows ) ||
(cols == 1 && rows > cols ) )
{
const int count = ( rows > cols ? rows : cols ) - 1;
output_x = cv::Mat_<double>::zeros(rows, cols);
cv::Mat_<double> cCopy, dCopy;
input_c.copyTo(cCopy);
input_d.copyTo(dCopy);
if ( input_b(0) != 0 )
{
cCopy(0) /= input_b(0);
dCopy(0) /= input_b(0);
}
else
{
return false;
}
for ( int i=1; i < count; i++ )
{
double temp = input_b(i) - input_a(i) * cCopy(i-1);
if ( temp == 0.0 )
{
return false;
}
cCopy(i) /= temp;
dCopy(i) = ( dCopy(i) - dCopy(i-1)*input_a(i) ) / temp;
}
output_x(count) = dCopy(count);
for ( int i=count-2; i > 0; i-- )
{
output_x(i) = dCopy(i) - cCopy(i)*output_x(i+1);
}
return true;
}
else
{
return false;
}
}
参考文献:https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm
Opencv 三对角线矩阵(Tridiagonal Matrix)解法之(Thomas Algorithm)的更多相关文章
- 三对角矩阵(Tridiagonal Matrices)的求法:Thomas Algorithm(TDMA)
转载http://www.cnblogs.com/xpvincent/archive/2013/01/25/2877411.html 做三次样条曲线时,需要解三对角矩阵(Tridiagonal Mat ...
- [OpenCV] Basic data types - Matrix
http://docs.opencv.org/2.4.13/ Basis 矩形 "modules/core/src/drawing.cpp" CV_IMPL void cvRect ...
- QuantStart量化交易文集
Over the last seven years more than 200 quantitative finance articles have been written by members o ...
- [LeetCode] Toeplitz Matrix 托普利兹矩阵
A matrix is Toeplitz if every diagonal from top-left to bottom-right has the same element. Now given ...
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...
- Opencv 三次样条曲线(Cubic Spline)插值
本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/47707679 1.样条曲线简介 样条曲 ...
- 蒟阵P3390 【模板】矩阵快速幂
代码如下: #include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> ...
- CUDA Samples: matrix multiplication(C = A * B)
以下CUDA sample是分别用C++和CUDA实现的两矩阵相乘运算code即C= A*B,CUDA中包含了两种核函数的实现方法,第一种方法来自于CUDA Samples\v8.0\0_Simple ...
- opencv的使用——经典大坑
视频或相机中读入的帧数不对,或有空帧 image check from cap or video: you must check wether each frame is not empty when ...
随机推荐
- [学习笔记] CS131 Computer Vision: Foundations and Applications:Lecture 4 像素和滤波器
Background reading: Forsyth and Ponce, Computer Vision Chapter 7 Image sampling and quantization Typ ...
- STM32 软件模拟 IIC 代码,标准库、HAL库可用
#ifndef _IIC_H #define _IIC_H #include "stdio.h" #include "stm32f1xx_hal.h" /* 定 ...
- C#WIFI搜索与连接
1.功能搜索WIFI并连接 2.所用工具及资源:VS2012 Managed Wifi API(即:引用ManagedWifi.dll文件地址:http://files.cnblogs.com/fil ...
- java开发必背API
1.java.io.file类,File用于管理文件或目录: 所属套件:java.io File file = new File(fileStringPath); 1)file.mk(),真的会创建一 ...
- ZOJ 3687
赤裸的带禁区的排列数,不过,难点在于如何用程序来写这个公式了.纠结了好久没想到,看了看别人的博客,用了DFS,实在妙极,比自己最初想用枚举的笨方法高明许多啊.\ http://blog.csdn.ne ...
- AJAX核心--XMLHttpRequest五步法
引言: AJAX=异步Javascript + XML,AJAX是一种用于创建高速动态网页的技术. 开门见山: 解读:AJAX使用XHTML和CSS为网页表示.DOM动态显示和交互,XML进行数据交换 ...
- Android在程序中浏览网页
本文是自己学习所做笔记,欢迎转载.但请注明出处:http://blog.csdn.net/jesson20121020 有时须要在程序中浏览一些网页.当然了能够通过调用系统的浏览器来打开浏览.可是大多 ...
- m_Orchestrate learning system---四、多看参考文档很多事情很轻松就解决了
m_Orchestrate learning system---四.多看参考文档很多事情很轻松就解决了 一.总结 一句话总结:多看参考文档啊 1.面包屑导航如何实现? 1 <ol class=& ...
- 忽略PyCharm4中特定的警告提示信息
有一种简单的方式忽略PyCharm4中的警告,光标放在下划线上,a. 等灯泡出现,点击灯泡或者b. 按下Alt和Enter键,选择'Ignore errors like this'. 或者,在设置里更 ...
- 设备综合效率OEE
设备综合效率OEE OEE(OverallEquipmentEffectiveness),即设备综合效率,也有资料表述为总体设备效率,其本质就是设备负荷时间内实际产量与理论产量的比值. TEEP(To ...