/* * File : vecmat.c * * [DEFINE DESCRIPTION = Matrix/vector operators for NSL] * * Andrew H. Fagg * 5/10/91 * * Useful library routines for work in NSL. * Includes : * Matrix, Vector manipulation. * * */ #include "nsl_include.h" #include <stream.h> #include <math.h> #include "alib.h" /* * nsl_matrix vec_mult_vec_trans(nsl_vector& vecA, nsl_vector& vecB) * * T * Return = A * B * */ nsl_matrix vec_mult_vec_trans(nsl_vector& vecA, nsl_vector& vecB) { int An, Bn; int i, j; An = vecA.get_xn(); Bn = vecB.get_xn(); nsl_matrix out(Bn, An); for(i = 0; i < An; ++i) for(j = 0; j < Bn; ++j) out.elem(j, i) = vecA.elem(i) * vecB.elem(j); return out; } /* * nsl_vector mat_mult_col_vec(nsl_matrix& mat, nsl_vector& vec) * * Computes C = M * V * * Where C and V are both column vectors and M is a matrix. * */ nsl_vector mat_mult_col_vec(nsl_matrix& mat, nsl_vector& vec) { int xn; int yn; int vxn; int i, j; xn = mat.get_xn(); yn = mat.get_yn(); vxn = vec.get_xn(); if(xn != vxn) { cout << "mat_mult_col_vec : dimension mismatch.\n"; cout << xn sp << yn sp << vxn nl; exit(0); } nsl_vector out(yn); for(i = 0; i < yn; ++i) { out.elem(i) = 0.0; for(j = 0; j < xn; ++j) out.elem(i) += vec.elem(j) * mat.elem(j,i); } return out; } /* * nsl_vector mat_trans_mult_col_vec(nsl_matrix& mat, nsl_vector& vec) * * T * Computes C = M * V * * Where C and V are column vectors. * */ nsl_vector mat_trans_mult_col_vec(nsl_matrix& mat, nsl_vector& vec) { int xn; int yn; int vxn; int i, j; xn = mat.get_xn(); yn = mat.get_yn(); vxn = vec.get_xn(); if(yn != vxn) { cout << "mat_mult_col_vec : dimension mismatch.\n"; cout << xn sp << yn sp << vxn nl; exit(0); } nsl_vector out(xn); for(i = 0; i < xn; ++i) { out.elem(i) = 0.0; for(j = 0; j < yn; ++j) out.elem(i) += vec.elem(j) * mat.elem(i,j); } return out; } /* * void extract_col_vector(nsl_matrix& mat, int col, nsl_vector& vec) * * Copy the <col>th column of <mat> into <vec>. * */ void extract_col_vector(nsl_matrix& mat, int col, nsl_vector& vec) { int row; int xn, yn; xn = vec.get_xn(); yn = mat.get_xn(); if(xn != yn) { cout << "extract_col_vector() : dimension error : " << vec.get_xn() << ", " << mat.get_xn() << "x" << mat.get_yn() nl; exit(0); } for(row = 0; row < xn; ++row) { vec.elem(row) = mat.elem(row, col); } } /* * void extract_row_vector(nsl_matrix& mat, int row, nsl_vector& vec) * * Copy the <row>th row of <mat> into <vec>. * */ void extract_row_vector(nsl_matrix& mat, int row, nsl_vector& vec) { int col; int xn, yn; xn = vec.get_xn(); yn = mat.get_yn(); if(xn != yn) { cout << "extract_row_vector() : dimension error : " << vec.get_xn() << ", " << mat.get_xn() << "x" << mat.get_yn() nl; exit(0); } for(col = 0; col < xn; ++col) { vec.elem(col) = mat.elem(row, col); } } /* * void insert_vector(nsl_matrix& mat, int col, nsl_vector& vec) * * Copy <vec> into the <col>th column of <mat>. * */ void insert_col_vector(nsl_matrix& mat, int col, nsl_vector& vec) { int row; int xn, yn; xn = vec.get_xn(); yn = mat.get_xn(); if(xn != yn) { cout << "insert_col_vector() : dimension error : " << vec.get_xn() << ", " << mat.get_xn() << "x" << mat.get_yn() nl; exit(0); } for(row = 0; row < xn; ++row) { mat.elem(row, col) = vec.elem(row); } } /* * void insert_row_vector(nsl_matrix& mat, int row, nsl_vector& vec) * * Copy <vec> into the <row>th row of <mat>. * */ void insert_row_vector(nsl_matrix& mat, int row, nsl_vector& vec) { int col; int xn, yn; xn = vec.get_xn(); yn = mat.get_yn(); if(xn != yn) { cout << "insert_row_vector() : dimension error : " << vec.get_xn() << ", " << mat.get_xn() << "x" << mat.get_yn() nl; exit(0); } for(col = 0; col < xn; ++col) { mat.elem(row, col) = vec.elem(col); } } nsl_data dot(nsl_vector& v1, nsl_vector& v2) { int xn1, xn2; nsl_data out; if(&v1 == NULL || &v2 == NULL) { out.elem() = 0; return out; } xn1 = v1.get_xn(); xn2 = v2.get_xn(); if(xn1 != xn2) { cout << "dot() : dimension error : " << xn1 << ", " << xn2 nl; exit(0); } nsl_vector temp = v1 ^ v2; out = temp.sum(); return out; } void normal_row(nsl_matrix& mat, int L_mode) { int i,j; int a,b; float count; a = mat.get_xn(); b = mat.get_yn(); switch(L_mode) { case L1 : for(j = 0; j < a; ++j) { count = 0.0; for(i = 0; i < b; ++i) count += fabs(mat.elem(j,i)); if(count > 0.0001) for(i = 0; i < b; ++i) mat.elem(j,i) = mat.elem(j,i)/count; } break; case L2 : for(j = 0; j < a; ++j) { count = 0.0; for(i = 0; i < b; ++i) count += Square(mat.elem(j,i)); count = sqrt(count); if(count > 0.0001) for(i = 0; i < b; ++i) mat.elem(j,i) = mat.elem(j,i)/count; } break; } } void normal_col(nsl_matrix& mat, int L_mode) { int i,j; int a,b; float count; a = mat.get_xn(); b = mat.get_yn(); switch(L_mode) { case L1 : for(i = 0; i < b; ++i) { count = 0.0; for(j = 0; j < a; ++j) count += fabs(mat.elem(j,i)); if(count > 0.0001) for(j = 0; j < a; ++j) mat.elem(j,i) = mat.elem(j,i)/count; } break; case L2 : for(i = 0; i < b; ++i) { count = 0.0; for(j = 0; j < a; ++j) count += Square(mat.elem(j,i)); count = sqrt(count); if(count > 0.0001) for(j = 0; j < a; ++j) mat.elem(j,i) = mat.elem(j,i)/count; } break; } }