00001 #include <stdio.h>
00002 #include "sp_matrix.h"
00003
00004
00005 MATRIX create_matrix (int rows, int cols)
00006
00007
00008
00009
00010 {
00011 MATRIX m;
00012
00013 MROWS (m) = rows;
00014 MCOLS (m) = cols;
00015
00016 {
00017 int i, j;
00018
00019 for (i = 0; i < MROWS (m); i++)
00020 for (j = 0; j < MCOLS (m); j++)
00021 MDATA (m, i, j) = 0;
00022 }
00023
00024 return m;
00025 }
00026
00027
00028 void initialize_matrix (MATRIX *m, int rows, int cols)
00029
00030
00031
00032
00033 {
00034 MROWS (*m) = rows;
00035 MCOLS (*m) = cols;
00036
00037 {
00038 int i, j;
00039
00040 for (i = 0; i < MROWS (*m); i++)
00041 for (j = 0; j < MCOLS (*m); j++)
00042 MDATA (*m, i, j) = 0;
00043 }
00044
00045 }
00046
00047
00048
00049 void print_matrix (char *message, MATRIX const *m)
00050
00051
00052
00053
00054 {
00055 int i, j;
00056
00057 printf ("%s\n",message);
00058 printf("%d %d \n",MROWS (*m),MCOLS (*m));
00059 if ((MROWS (*m) <= MAX_ROWS) && (MCOLS (*m) <= MAX_COLS))
00060 for (i = 0; i < MROWS (*m); i++)
00061 {
00062 for (j = 0; j < MCOLS (*m); j++)
00063 printf ("%10.5f ", MDATA (*m, i, j));
00064 printf ("\n");
00065 }
00066 else printf ("Dimension incorrecta!");
00067 printf ("\n");
00068 }
00069
00070
00071 VECTOR create_vector (int elements)
00072
00073
00074
00075
00076 {
00077 VECTOR v;
00078
00079 VELEMENTS (v) = elements;
00080
00081 {
00082 int i;
00083
00084 for (i = 0; i < VELEMENTS (v); i++)
00085 VDATA (v, i) = 0;
00086 }
00087
00088 return v;
00089 }
00090
00091
00092 void initialize_vector (VECTOR *v, int elements)
00093
00094
00095
00096
00097 {
00098 VELEMENTS (*v) = elements;
00099
00100 {
00101 int i;
00102
00103 for (i = 0; i < VELEMENTS (*v); i++)
00104 VDATA (*v, i) = 0;
00105 }
00106 }
00107
00108
00109 void print_vector (char *message, VECTOR const *v)
00110
00111
00112
00113
00114 {
00115 int i;
00116
00117 printf ("%s\n",message);
00118 if (VELEMENTS (*v) <= MAX_ROWS)
00119 for (i = 0; i < VELEMENTS (*v); i++)
00120 {
00121 printf ("%f ", VDATA (*v, i));
00122 printf ("\n");
00123 }
00124 else printf ("Dimension incorrecta!");
00125 printf ("\n");
00126 }
00127
00128
00129 float cross_product (MATRIX const *m, int f1, int c1, int f2, int c2)
00130
00131
00132
00133 {
00134 return MDATA (*m, f1, c1) * MDATA (*m, f2, c2) - MDATA (*m, f1, c2) * MDATA (*m, f2, c1);
00135 }
00136
00137
00138 int determinant (MATRIX const *m, float *result)
00139
00140
00141 {
00142 if (!M_SQUARE (*m))
00143 {
00144 printf ("ERROR (determinant): MATRIX must be square!\n");
00145 print_matrix ("MATRIX:", m);
00146 return -1;
00147 }
00148 else
00149 {
00150
00151 if (MROWS (*m) == 1)
00152 *result = MDATA (*m, 0, 0);
00153 else if (MROWS (*m) == 2)
00154 *result = cross_product (m, 0, 0, 1, 1);
00155 else
00156 *result = MDATA (*m, 0, 0) * cross_product (m, 1, 1, 2, 2)
00157 - MDATA (*m, 0, 1) * cross_product (m, 1, 0, 2, 2)
00158 + MDATA (*m, 0, 2) * cross_product (m, 1, 0, 2, 1);
00159
00160
00161 return 1;
00162 }
00163 }
00164
00165
00166 int inverse_matrix (MATRIX const *m, MATRIX *n)
00167
00168
00169
00170 {
00171 if (!M_SQUARE (*m))
00172 {
00173 printf ("ERROR (inverse_matrix): MATRIX must be square!\n");
00174 print_matrix ("MATRIX:", m);
00175 n->cols=0; n->rows=0;
00176 return -1;
00177 }
00178 else
00179 {
00180 float det;
00181 int res;
00182
00183 res = determinant (m,&det);
00184
00185 if (res == -1)
00186 {
00187 printf ("ERROR (inverse_matrix): singular MATRIX!\n");
00188 print_matrix ("MATRIX:", m);
00189 return -1;
00190 }
00191 else
00192 {
00193 initialize_matrix (n, MROWS (*m), MCOLS (*m));
00194 if (MROWS (*m) == 1)
00195 {
00196 MDATA (*n, 0, 0) = 1 / det ;
00197 }
00198 else if (MROWS (*m) == 2)
00199 {
00200 MDATA (*n, 0, 0) = MDATA (*m, 1, 1) / det ;
00201 MDATA (*n, 0, 1) = -MDATA (*m, 0, 1) / det ;
00202 MDATA (*n, 1, 0) = -MDATA (*m, 1, 0) / det ;
00203 MDATA (*n, 1, 1) = MDATA (*m, 0, 0) / det ;
00204 }
00205 else
00206 {
00207 MDATA (*n, 0, 0) = cross_product (m, 1, 1, 2, 2) / det ;
00208 MDATA (*n, 0, 1) = -cross_product (m, 0, 1, 2, 2) / det ;
00209 MDATA (*n, 0, 2) = cross_product (m, 0, 1, 1, 2) / det ;
00210 MDATA (*n, 1, 0) = -cross_product (m, 1, 0, 2, 2) / det ;
00211 MDATA (*n, 1, 1) = cross_product (m, 0, 0, 2, 2) / det ;
00212 MDATA (*n, 1, 2) = -cross_product (m, 0, 0, 1, 2) / det ;
00213 MDATA (*n, 2, 0) = cross_product (m, 1, 0, 2, 1) / det ;
00214 MDATA (*n, 2, 1) = -cross_product (m, 0, 0, 2, 1) / det ;
00215 MDATA (*n, 2, 2) = cross_product (m, 0, 0, 1, 1) / det ;
00216 }
00217 }
00218 }
00219 return 1;
00220 }
00221
00222
00223 int multiply_matrix_vector (MATRIX const *m, VECTOR const *v, VECTOR *r)
00224
00225
00226
00227
00228 {
00229 if (! (MV_COMPAT_DIM (*m, *v)))
00230 {
00231 printf ("ERROR (multiply_matrix_vector): MATRIX and VECTOR dimensions incompatible!\n");
00232 print_matrix ("MATRIX:", m);
00233 print_vector ("VECTOR:", v);
00234 return -1;
00235 }
00236 else
00237 {
00238 int i, j;
00239 float datum;
00240
00241 VELEMENTS (*r) = MROWS (*m);
00242
00243 for (i = 0; i < MROWS (*m); i++)
00244 {
00245 datum = 0;
00246 for (j = 0; j < VELEMENTS (*v); j++)
00247 datum = datum + MDATA (*m, i, j) * VDATA (*v, j);
00248 VDATA (*r, i) = datum;
00249 }
00250 }
00251 return 1;
00252 }
00253