本文使用Visual Studio2022 版本 运用blitz和Qt库运行。
先介绍blitz路径设置方法:
1、blitz_gcc_test 链接:https://pan.baidu.com/s/1MNDU6XUP5N2Mgk2XeJuZfw
提取码:yieu
2、blitz路径设置:右击项目名称选择属性
选择C++目录中的包含目录
复制blitz文件路径后添加确定即可
3、Qt下载及环境设置教程:
先点击拓展—>管理拓展——>联机——>搜索qt下载安装(下载时关闭软件)
qmake安装包 链接:https://pan.baidu.com/s/1CaDywvqcEkuy30ugWZUbWw
提取码:dxzi
安装之后点击拓展——>qt vs tools——>options——>versions添加qmake路径到文件
添加qmake路径到文件
复制qmake文件路径,点击我的电脑——>属性——>高级系统设置——>环境变量——>系统变量——>path(双击)——>把qmake路径粘贴后确定 环境配置完成
5、代码
注意设置读写文件路径
#include <QtCore/QCoreApplication>
#include <blitz/array.h>
#include <Qtcore/QFile>
#include <QTextStream>
#include <fstream>
using namespace blitz;
void getRowColumnCount(const QString filename, int* rowCount, int* columnCount) {
QFile file(filename);
file.open(QIODevice::ReadOnly | QIODevice::Text);
*rowCount = 0;
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
(*rowCount)++;
}
file.seek(0);
QString line = in.readLine();
line.replace(","," ");
QStringList list = line.split(QRegExp("\\s+"));
*columnCount = list.size();
}
void readFile(const QString filename, int rowCount, int columnCount, Array<double, 2> a) {
QFile file(filename);
file.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream in(&file);
for (int i = 0; i < rowCount; i++)
{
QString line = in.readLine();
line.replace(",", " ");
QStringList list = line.split(QRegExp("\\s+"));
for (int j = 0; j < columnCount; j++)
{
a(i, j) = list[j].toDouble();
}
}
}
void writeFile(const char filename[], double* x, int n) {
ofstream outfile(filename, ios::out);
for (int i = 0; i < n; i++)
{
outfile <<*(x + i) ;
outfile << endl;
}
outfile.close();
}
void LDL(int n, double* a, double* b, double* x)//LDL法,参数依次:阶数 系数矩阵a 常数矩阵b
{
double* U = new double[n * n];
double* y = new double[n];
double* z = new double[n];
double* L = new double[n * n];
double* D = new double[n];
for (int i = 0; i < n; i++)//用LU先算出L U
{
for (int j = 0; j < n; j++)
{
*(U + i * n + j) = 0;//暂时全部赋值为0
if (i == j)
{
*(L + i * n + j) = 1;//对角线赋值为1
}
else
{
*(L + i * n + j) = 0;//其他暂时赋值为0
}
}
}
for (int k = 0; k < n; k++)//计算u和l矩阵的值
{
for (int j = k; j < n; j++)
{
*(U + k * n + j) = *(a + k * n + j);//第一行
for (int r = 0; r < k; r++)//接下来由L的前一列算u的下一行
{
*(U + k * n + j) = *(U + k * n + j) - (*(L + k * n + r) * (*(U + r * n + j)));
}
}
for (int i = k + 1; i < n; i++)//计算L的列
{
*(L + i * n + k) = *(a + i * n + k);
for (int r = 0; r < k; r++)
{
*(L + i * n + k) = *(L + i * n + k) - (*(L + i * n + r) * (*(U + r * n + k)));
}
*(L + i * n + k) = *(L + i * n + k) / (*(U + k * n + k));
}
}
for (int i = 0; i < n; i++)//把D赋值
{
*(D + i) = *(U + i * n + i);
}
for (int i = 0; i < n; i++)//由Lz=b算z
{
*(z + i) = *(b + i);
for (int j = 0; j < i; j++)
{
*(z + i) = *(z + i) - *(L + i * n + j) * (*(z + j));
}
}
for (int i = 0; i < n; i++)//算y
{
*(y + i) = *(z + i) / (*(D + i));
}
double* temp = new double[n * n];
for (int i = 0; i < n; i++)//这里实现对L的转置
{
for (int j = 0; j < n; j++)
{
*(temp + i * n + j) = *(L + j * n + i);
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
*(L + i * n + j) = *(temp + i * n + j);
}
}
delete[]temp;//释放
for (int i = n - 1; i >= 0; i--)//最后算x
{
*(x + i) = *(y + i);
for (int j = i + 1; j < n; j++)
{
*(x + i) = *(x + i) - *(L + i * n + j) * (*(x + j));
}
}
for (int i = 0; i < n; i++)
{
cout << "解为:\n";
cout << *(x + i) << endl;
}
delete[]U;
delete[]y;
delete[]z;
delete[]L;
delete[]D;
}
int main(int argc, char *argv[])
{
int rowCount;
int columnCount;
char rfilename[] = "d:/a.txt";
char wfilename[] = "d:/x_cpp.txt";
getRowColumnCount(rfilename, &rowCount, &columnCount);
Array<double, 2> a(rowCount, columnCount);
readFile(rfilename, rowCount, columnCount, a);
std::cout << a;
double A[2*2];
double b[2];
int k = 0;
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < columnCount-1; j++)
{
A[k] = (double)a(i, j);
k++;
}
b[i] = (double)a(i, columnCount - 1);
}
double* x = new double[rowCount];
LDL(rowCount, A, b, x);
writeFile(wfilename, x, rowCount);
return 0;
}