您好,欢迎来到刀刀网。
搜索
您的当前位置:首页QR分解C程序

QR分解C程序

来源:刀刀网

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "./QRdecomposition.h"


#define dim		3

// 初始化矩阵  
void initializeMatrix(double* matrix, int rows, int cols) 
{
	int i = 0; 
	for(i = 0; i < rows * cols; i++)
	{
		matrix[i] = i + 1;  // 用1到rows*cols的值初始化矩阵  
	}
}


// 打印矩阵  
void printMatrix(double* matrix, int rows, int cols)
{
	int i = 0;
	int j = 0; 
	for(i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			printf("%.3f ", matrix[i * cols + j]);
		}
		printf("\n");
	}
}



int main()
{
	int res = 0;
	double A[dim][dim] = {0};
	double A1[dim][dim] = {0};

	double Q[dim][dim] = {0};
	double R[dim][dim] = {0};

	//初始化矩阵A 
	initializeMatrix(&A[0][0], dim, dim);
	
	//打印矩阵A
	printf("Martix A:\n");
	printMatrix(&A[0][0], dim, dim);
	printf("\n");

	//QR分解函数
	res = qrDecomposition(dim, &A[0][0], &Q[0][0], &R[0][0]);
	if(res != 0)
	{
		printf("error:input dim > MAX_SIZE!\n");
		return -1;	
	}

	//矩阵与矩阵相乘
	cw_multiply(dim, dim, dim, &Q[0][0], &R[0][0], &A1[0][0]);

	//打印矩阵Q 
	printf("Martix Q:\n");
	printMatrix(&Q[0][0], dim, dim);
	printf("\n");
	
	//打印矩阵R	
	printf("Martix R:\n");
	printMatrix(&R[0][0], dim, dim);
	printf("\n");	
	
	//打印结果A1 
	printf("Martix A1:\n");
	printMatrix(&A1[0][0], dim, dim);
	
	return 0;
}

#include <string.h>
#include <math.h>
#include "QRdecomposition.h"
/************************************************************************************************************************
*  版权所有(C)2024,重庆长安工业(集团)有限责任公司。
*  
*  文件名称 :      QRdecomposition.c
*  内容摘要 :      QR分解
*  其他说明 :      无
*  当前版本 :      V1.00
*  作    者 :      yf、yhz
*  完成日期 :      20241024
*  修改记录 :      
*  修改日期 :      
*  版 本 号 :
*  修 改 人 :      
*  修改内容 :
*************************************************************************************************************************/

/*
 * description:
 * 生成单位矩阵
 * input:
 * int n            矩阵大小
 * output:
 * double *matrix   单位矩阵首地址
 * return:
 * 无
*/
void cw_identityMatrix(int n, double *matrix)
{
    int i = 0;
    int j = 0;
    for(i = 0; i < n; i++)
    {
        for(j = 0; j < n; j++)
        {
            matrix[i*n + j] = (i == j) ? 1.0 : 0.0;
        }
    }
}

/*
 * description:
 * 两矩阵相乘
 * input:
 * int n            矩阵1行数
 * int m            矩阵1列数
 * int p            矩阵2列数
 * double *matrix1  矩阵1首地址
 * double *matrix2  矩阵2首地址
 * output:
 * double *result   结果矩阵首地址
 * return:
 * 无
 */
void cw_multiply(int n, int m, int p, double *matrix1, double *matrix2, double *result)
{
    int i = 0;
    int j = 0;
    int k = 0;
    for(i = 0; i < n; i++)
    {
        for(j = 0; j < p; j++)
        {
            result[i*p + j] = 0;
            for(k = 0; k < m; k++)
            {
                result[i*p + j] += matrix1[i*m + k] * matrix2[k*p + j];
            }
        }
    }
}

/*
 * description:
 * 矢量和标量相乘
 * input:
 * double *a 矢量首地址
 * double  b 标量值
 * int     m 矢量长度
 * output:
 * double *c 结果矢量首地址
 * return:
 * int		0:正常   其他:异常
*/
int cw_vecMulsca(double *a, double b, int m, double *c)
{
    int i = 0;

    if(a == NULL)
    {
        return -1;
    }
    if(c == NULL)
    {
        return -2;
    }
    if(m < 0)
    {
        return -3;
    }

    for(i = 0; i < m; i++)
    {
        c[i] = a[i] * b;
    }

    return 0;
}


/*
 * description:
 * QR分解算法
 * input:
 * int     n 矩阵维数
 * double *A 矩阵A首地址
  * 
 * output:
 * double *Q 结果正交矩阵Q首地址
 * double *R 结果上三角矩阵R首地址
 * return:
 * int		0:正常   其他:异常
*/
int qrDecomposition(int n, double *A, double *Q, double *R)
{
	int i = 0;
	int j = 0;
	int k = 0;
	double norm = 0.0;
	double w[MAX_SIZE] = {0.0};
	double x[MAX_SIZE] = {0.0};
	double E[MAX_SIZE*MAX_SIZE] = {0.0};
	double F[MAX_SIZE*MAX_SIZE] = {0.0};
	double P[MAX_SIZE*MAX_SIZE] = {0.0};
	double P1[MAX_SIZE*MAX_SIZE] = {0.0};
	double Y[MAX_SIZE*MAX_SIZE] = {0.0};

	if(n > MAX_SIZE)
	{
		return -1;	
	}

	cw_identityMatrix(n, E);             //单位矩阵E
	cw_identityMatrix(n, P1);            //单位矩阵P1

	for(k = 0; k < (n-1); k++)
	{
		norm = 0;
		for(i = k; i < n; i++)
		{
			norm += A[i*n + k]*A[i*n + k];
		}
		norm = sqrt(norm);             //求向量的范数

		if(A[k*n + k] > 0)
		{
			norm = -norm;
		}

		R[k*n + k] = -norm;

		for(i = 0; i < n; i++)
		{
			if(i < k)
			{
				w[i] = 0;
				R[i*n + k] = A[i*n + k];
			}
			else if(i == k)
			{
				w[i] = A[k*n + k] + norm;
			}
			else
			{
				w[i] = A[i*n + k];
			}
		}

		norm = 0;
		for(i = 0; i < n; i++)
		{
			norm += w[i]*w[i];
		}

		norm = sqrt(norm);
		if(fabs(norm) > 1e-6)
		{
			for(i = 0; i < n; i++)
			{
				w[i] = w[i]/norm;             //向量归一化
			}
		}

		cw_vecMulsca(w, 2.0, n, x);          
		cw_multiply(n, 1, n, x, w, F);       

		for(i = 0; i < n; i++)
		{
			for(j = 0; j < n; j++)
			{
				P[i*n + j] = E[i*n + j] - F[i*n + j];
			}
		}

		cw_multiply(n, n, n, P, A, Y);
		memcpy(&A[0], &Y[0], n*n*sizeof(double));

		cw_multiply(n, n, n, P1, P, Y);
		memcpy(&P1[0], &Y[0], n*n*sizeof(double));
		memcpy(&Q[0], &P1[0], n*n*sizeof(double));

		for(i = 0; i < n; i++)
		{
			R[i*n + (n-1)] = A[i*n + (n-1)];
		}
	}
	
	return 0;
}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- gamedaodao.com 版权所有 湘ICP备2022005869号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务