📄 matrix.c
字号:
/* * * QccPack: Quantization, compression, and coding libraries * Copyright (C) 1997-2009 James E. Fowler * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * */#include "libQccPack.h"QccMatrix QccMatrixAlloc(int num_rows, int num_cols){ QccMatrix matrix; int row; if ((num_rows <= 0) || (num_cols <= 0)) return(NULL); if ((matrix = (QccMatrix)malloc(sizeof(QccVector)*num_rows)) == NULL) { QccErrorAddMessage("(QccMatrixAlloc): Error allocating memory"); return(NULL); } for (row = 0; row < num_rows; row++) if ((matrix[row] = QccVectorAlloc(num_cols)) == NULL) { QccErrorAddMessage("(QccMatrixAlloc): Error allocating memory"); QccFree(matrix); return(NULL); } return(matrix);}void QccMatrixFree(QccMatrix matrix, int num_rows){ int row; if (matrix != NULL) { for (row = 0; row < num_rows; row++) QccVectorFree(matrix[row]); QccFree(matrix); }}int QccMatrixZero(QccMatrix matrix, int num_rows, int num_cols){ int row, col; if (matrix == NULL) return(0); for (row = 0; row < num_rows; row++) for (col = 0; col < num_cols; col++) matrix[row][col] = 0; return(0);}QccMatrix QccMatrixResize(QccMatrix matrix, int num_rows, int num_cols, int new_num_rows, int new_num_cols){ int row; QccMatrix new_matrix; if (matrix == NULL) { if ((new_matrix = QccMatrixAlloc(new_num_rows, new_num_cols)) == NULL) { QccErrorAddMessage("(QccMatrixResize): Error calling QccMatrixAlloc()"); return(NULL); } QccMatrixZero(matrix, new_num_rows, new_num_cols); return(new_matrix); } if ((num_rows < 0) || (new_num_rows < 0) || (num_cols < 0) || (new_num_cols < 0)) return(matrix); if ((new_num_rows == num_rows) && (new_num_cols == num_cols)) return(matrix); if (new_num_rows != num_rows) { if ((new_matrix = (QccMatrix)realloc(matrix, sizeof(QccVector) * new_num_rows)) == NULL) { QccErrorAddMessage("(QccMatrixResize): Error reallocating memory"); return(NULL); } for (row = num_rows; row < new_num_rows; row++) { if ((new_matrix[row] = QccVectorAlloc(new_num_cols)) == NULL) { QccErrorAddMessage("(QccMatrixAlloc): Error QccVectorAlloc()"); QccFree(new_matrix); return(NULL); } QccVectorZero(new_matrix[row], new_num_cols); } } else new_matrix = matrix; for (row = 0; row < num_rows; row++) if ((new_matrix[row] = QccVectorResize(new_matrix[row], num_cols, new_num_cols)) == NULL) { QccErrorAddMessage("(QccMatrixAlloc): Error calling QccVectorResize()"); QccFree(new_matrix); return(NULL); } return(new_matrix);}int QccMatrixCopy(QccMatrix matrix1, const QccMatrix matrix2, int num_rows, int num_cols){ int row, col; if ((matrix1 == NULL) || (matrix2 == NULL) || (num_rows <= 0) || (num_cols <= 0)) return(0); for (row = 0; row < num_rows; row++) for (col = 0; col < num_cols; col++) matrix1[row][col] = matrix2[row][col]; return(0);}double QccMatrixMaxValue(const QccMatrix matrix, int num_rows, int num_cols){ int row; double max_value = -MAXDOUBLE; double tmp; if (matrix != NULL) for (row = 0; row < num_rows; row++) { tmp = QccVectorMaxValue(matrix[row], num_cols, NULL); if (tmp > max_value) max_value = tmp; } return(max_value);}double QccMatrixMinValue(const QccMatrix matrix, int num_rows, int num_cols){ int row; double min_value = MAXDOUBLE; double tmp; if (matrix != NULL) for (row = 0; row < num_rows; row++) { tmp = QccVectorMinValue(matrix[row], num_cols, NULL); if (tmp < min_value) min_value = tmp; } return(min_value);}int QccMatrixPrint(const QccMatrix matrix, int num_rows, int num_cols){ int row, col; if (matrix == NULL) return(0); for (row = 0; row < num_rows; row++) { for (col = 0; col < num_cols; col++) printf("%g ", matrix[row][col]); printf("\n"); } return(0);}int QccMatrixRowExchange(QccMatrix matrix, int num_cols, int row1, int row2){ int col; double temp; if (matrix == NULL) return(0); for (col = 0; col < num_cols; col++) { temp = matrix[row1][col]; matrix[row1][col] = matrix[row2][col]; matrix[row2][col] = temp; } return(0);}int QccMatrixColExchange(QccMatrix matrix, int num_rows, int col1, int col2){ int row; double temp; if (matrix == NULL) return(0); for (row = 0; row < num_rows; row++) { temp = matrix[row][col1]; matrix[row][col1] = matrix[row][col2]; matrix[row][col2] = temp; } return(0);}int QccMatrixIdentity(QccMatrix matrix, int num_rows, int num_cols){ int row; if (matrix == NULL) return(0); QccMatrixZero(matrix, num_rows, num_cols); for (row = 0; row < num_rows; row++) matrix[row][row] = 1; return(0);}int QccMatrixTranspose(const QccMatrix matrix1, QccMatrix matrix2, int num_rows, int num_cols){ int row, col; if (matrix1 == NULL) return(0); if (matrix2 == NULL) return(0); for (row = 0; row < num_rows; row++) for (col = 0; col < num_cols; col++) matrix2[col][row] = matrix1[row][col]; return(0);}int QccMatrixAdd(QccMatrix matrix1, const QccMatrix matrix2, int num_rows, int num_cols){ int row; if (matrix1 == NULL) return(0); if (matrix2 == NULL) return(0); for (row = 0; row < num_rows; row++) if (QccVectorAdd(matrix1[row], matrix2[row], num_cols)) { QccErrorAddMessage("(QccMatrixAdd): Error calling QccVectorAdd()"); return(1); } return(0);}int QccMatrixSubtract(QccMatrix matrix1, const QccMatrix matrix2, int num_rows, int num_cols){ int row; if (matrix1 == NULL) return(0); if (matrix2 == NULL) return(0); for (row = 0; row < num_rows; row++) if (QccVectorSubtract(matrix1[row], matrix2[row], num_cols)) { QccErrorAddMessage("(QccMatrixSubtract): Error calling QccVectorSubtract()"); return(1); } return(0);}double QccMatrixMean(const QccMatrix matrix, int num_rows, int num_cols){ double sum = 0.0; int row, col; for (row = 0; row < num_rows; row++) for (col = 0; col < num_cols; col++) sum += matrix[row][col]; sum /= num_rows * num_cols; return(sum);}double QccMatrixVariance(const QccMatrix matrix, int num_rows, int num_cols){ double variance = 0.0; double mean; int row, col; mean = QccMatrixMean(matrix, num_rows, num_cols); for (row = 0; row < num_rows; row++) for (col = 0; col < num_cols; col++) variance += (matrix[row][col] - mean) * (matrix[row][col] - mean); variance /= (num_rows * num_cols); return(variance);}double QccMatrixMaxSignalPower(const QccMatrix matrix, int num_rows, int num_cols){ int current_row, component; double max_power = -1; double power; for (current_row = 0; current_row < num_rows; current_row++) { power = 0; for (component = 0; component < num_cols; component++) power += matrix[current_row][component]* matrix[current_row][component]; if (power > max_power) max_power = power; } return(max_power); }int QccMatrixVectorMultiply(const QccMatrix matrix, const QccVector vector1, QccVector vector2, int num_rows, int num_cols){ int row; if (matrix == NULL) return(0); if (vector1 == NULL) return(0); if (vector2 == NULL) return(0); for (row = 0; row < num_rows; row++) vector2[row] = QccVectorDotProduct(matrix[row], vector1, num_cols); return(0);}int QccMatrixMultiply(const QccMatrix matrix1, int num_rows1, int num_cols1, const QccMatrix matrix2, int num_rows2, int num_cols2, QccMatrix matrix3){ int row, col; int index; if (matrix1 == NULL) return(0); if (matrix2 == NULL) return(0); if (matrix3 == NULL) return(0); if (num_cols1 != num_rows2) { QccErrorAddMessage("(QccMatrixMultiply): Inner matrix dimensions do not agree"); return(1); } for (row = 0; row < num_rows1; row++) for (col = 0; col < num_cols2; col++) { matrix3[row][col] = 0; for (index = 0; index < num_cols1; index++) matrix3[row][col] += matrix1[row][index] * matrix2[index][col]; } return(0);}int QccMatrixDCT(const QccMatrix input_block, QccMatrix output_block,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -