test_tools_les.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. /*****************************************************************************
  2. *
  3. * MODULE: Grass Gmath Library
  4. * AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
  5. * soerengebbert <at> gmx <dot> de
  6. *
  7. * PURPOSE: functions to manage linear equation systems
  8. * part of the gmath library
  9. *
  10. * COPYRIGHT: (C) 2000 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. *****************************************************************************/
  17. #include "test_gmath_lib.h"
  18. #include <stdlib.h>
  19. #include <math.h>
  20. /*!
  21. * \brief Allocate memory for a (not) quadratic linear equation system which includes the Matrix A, vector x and vector b
  22. *
  23. * This function calls #G_math_alloc_les_param
  24. *
  25. * \param rows int
  26. * \param cols int
  27. * \param type int
  28. * \return G_math_les *
  29. *
  30. * */
  31. G_math_les *G_math_alloc_nquad_les(int rows, int cols, int type)
  32. {
  33. return G_math_alloc_les_param(rows, cols, type, 2);
  34. }
  35. /*!
  36. * \brief Allocate memory for a (not) quadratic linear equation system which includes the Matrix A and vector x
  37. *
  38. * This function calls #G_math_alloc_les_param
  39. *
  40. * \param rows int
  41. * \param cols int
  42. * \param type int
  43. * \return G_math_les *
  44. *
  45. * */
  46. G_math_les *G_math_alloc_nquad_les_Ax(int rows, int cols, int type)
  47. {
  48. return G_math_alloc_les_param(rows, cols, type, 1);
  49. }
  50. /*!
  51. * \brief Allocate memory for a (not) quadratic linear equation system which includes the Matrix A
  52. *
  53. * This function calls #G_math_alloc_les_param
  54. *
  55. * \param rows int
  56. * \param cols int
  57. * \param type int
  58. * \return G_math_les *
  59. *
  60. * */
  61. G_math_les *G_math_alloc_nquad_les_A(int rows, int cols, int type)
  62. {
  63. return G_math_alloc_les_param(rows, cols, type, 0);
  64. }
  65. /*!
  66. * \brief Allocate memory for a (not) quadratic linear equation system which includes the Matrix A, vector x and vector b
  67. *
  68. * This function calls #G_math_alloc_les_param
  69. *
  70. * \param rows int
  71. * \param cols int
  72. * \param type int
  73. * \return G_math_les *
  74. *
  75. * */
  76. G_math_les *G_math_alloc_nquad_les_Ax_b(int rows, int cols, int type)
  77. {
  78. return G_math_alloc_les_param(rows, cols, type, 2);
  79. }
  80. /*!
  81. * \brief Allocate memory for a quadratic linear equation system which includes the Matrix A, vector x and vector b
  82. *
  83. * This function calls #G_math_alloc_les_param
  84. *
  85. * \param rows int
  86. * \param type int
  87. * \return G_math_les *
  88. *
  89. * */
  90. G_math_les *G_math_alloc_les(int rows, int type)
  91. {
  92. return G_math_alloc_les_param(rows, rows, type, 2);
  93. }
  94. /*!
  95. * \brief Allocate memory for a quadratic linear equation system which includes the Matrix A and vector x
  96. *
  97. * This function calls #G_math_alloc_les_param
  98. *
  99. * \param rows int
  100. * \param type int
  101. * \return G_math_les *
  102. *
  103. * */
  104. G_math_les *G_math_alloc_les_Ax(int rows, int type)
  105. {
  106. return G_math_alloc_les_param(rows, rows, type, 1);
  107. }
  108. /*!
  109. * \brief Allocate memory for a quadratic linear equation system which includes the Matrix A
  110. *
  111. * This function calls #G_math_alloc_les_param
  112. *
  113. * \param rows int
  114. * \param type int
  115. * \return G_math_les *
  116. *
  117. * */
  118. G_math_les *G_math_alloc_les_A(int rows, int type)
  119. {
  120. return G_math_alloc_les_param(rows, rows, type, 0);
  121. }
  122. /*!
  123. * \brief Allocate memory for a quadratic linear equation system which includes the Matrix A, vector x and vector b
  124. *
  125. * This function calls #G_math_alloc_les_param
  126. *
  127. * \param rows int
  128. * \param type int
  129. * \return G_math_les *
  130. *
  131. * */
  132. G_math_les *G_math_alloc_les_Ax_b(int rows, int type)
  133. {
  134. return G_math_alloc_les_param(rows, rows, type, 2);
  135. }
  136. /*!
  137. * \brief Allocate memory for a quadratic or not quadratic linear equation system
  138. *
  139. * The type of the linear equation system must be G_MATH_NORMAL_LES for
  140. * a regular quadratic matrix or G_MATH_SPARSE_LES for a sparse matrix
  141. *
  142. * <p>
  143. * In case of G_MATH_NORMAL_LES
  144. *
  145. * A quadratic matrix of size rows*rows*sizeof(double) will allocated
  146. *
  147. * <p>
  148. * In case of G_MATH_SPARSE_LES
  149. *
  150. * a vector of size row will be allocated, ready to hold additional allocated sparse vectors.
  151. * each sparse vector may have a different size.
  152. *
  153. * Parameter parts defines which parts of the les should be allocated.
  154. * The number of columns and rows defines if the matrix is quadratic.
  155. *
  156. * \param rows int
  157. * \param cols int
  158. * \param type int
  159. * \param parts int -- 2 = A, x and b; 1 = A and x; 0 = A allocated
  160. * \return G_math_les *
  161. *
  162. * */
  163. G_math_les *G_math_alloc_les_param(int rows, int cols, int type, int parts)
  164. {
  165. G_math_les *les;
  166. if (type == G_MATH_SPARSE_LES)
  167. G_debug(
  168. 2,
  169. "Allocate memory for a sparse linear equation system with %i rows\n",
  170. rows);
  171. else
  172. G_debug(
  173. 2,
  174. "Allocate memory for a regular linear equation system with %i rows and %i cols\n",
  175. rows, cols);
  176. les = (G_math_les *) G_calloc(1, sizeof(G_math_les));
  177. les->x = NULL;
  178. les->b = NULL;
  179. if (parts > 0)
  180. {
  181. les->x = (double *)G_calloc(cols, sizeof(double));
  182. }
  183. if (parts > 1)
  184. {
  185. les->b = (double *)G_calloc(cols, sizeof(double));
  186. }
  187. les->A = NULL;
  188. les->data = NULL;
  189. les->Asp = NULL;
  190. les->rows = rows;
  191. les->cols = cols;
  192. les->symm = 0;
  193. les->bandwidth = cols;
  194. if (rows == cols)
  195. les->quad = 1;
  196. else
  197. les->quad = 0;
  198. if (type == G_MATH_SPARSE_LES)
  199. {
  200. les->Asp = (G_math_spvector **) G_calloc(rows,
  201. sizeof(G_math_spvector *));
  202. les->type = G_MATH_SPARSE_LES;
  203. }
  204. else
  205. {
  206. les->A = G_alloc_matrix(rows, cols);
  207. /*save the start pointer of the matrix*/
  208. les->data = les->A[0];
  209. les->type = G_MATH_NORMAL_LES;
  210. }
  211. return les;
  212. }
  213. /***************** Floating point version ************************/
  214. G_math_f_les *G_math_alloc_f_les(int rows, int type)
  215. {
  216. return G_math_alloc_f_les_param(rows, rows, type, 2);
  217. }
  218. G_math_f_les *G_math_alloc_f_nquad_les_A(int rows, int cols, int type)
  219. {
  220. return G_math_alloc_f_les_param(rows, cols, type, 0);
  221. }
  222. G_math_f_les *G_math_alloc_f_les_param(int rows, int cols, int type, int parts)
  223. {
  224. G_math_f_les *les;
  225. G_debug(
  226. 2,
  227. "Allocate memory for a regular float linear equation system with %i rows\n",
  228. rows);
  229. les = (G_math_f_les *) G_calloc(1, sizeof(G_math_f_les));
  230. les->x = NULL;
  231. les->b = NULL;
  232. if (parts > 0)
  233. {
  234. les->x = (float *)G_calloc(cols, sizeof(float));
  235. }
  236. if (parts > 1)
  237. {
  238. les->b = (float *)G_calloc(cols, sizeof(float));
  239. }
  240. les->A = NULL;
  241. les->data = NULL;
  242. les->rows = rows;
  243. les->cols = cols;
  244. les->symm = 0;
  245. les->bandwidth = cols;
  246. if (rows == cols)
  247. les->quad = 1;
  248. else
  249. les->quad = 0;
  250. les->A = G_alloc_fmatrix(rows, cols);
  251. /*save the start pointer of the matrix*/
  252. les->data = les->A[0];
  253. les->type = G_MATH_NORMAL_LES;
  254. return les;
  255. }
  256. /*!
  257. * \brief Adds a sparse vector to a sparse linear equation system at position row
  258. *
  259. * Return 1 for success and -1 for failure
  260. *
  261. * \param les G_math_les *
  262. * \param spvector G_math_spvector *
  263. * \param row int
  264. * \return int 0 success, -1 failure
  265. *
  266. * */
  267. int G_math_add_spvector_to_les(G_math_les * les, G_math_spvector * spvector,
  268. int row)
  269. {
  270. if (les != NULL)
  271. {
  272. if (les->type != G_MATH_SPARSE_LES)
  273. return -1;
  274. if (les->rows > row)
  275. {
  276. G_debug(
  277. 5,
  278. "Add sparse vector %p to the sparse linear equation system at row %i\n",
  279. spvector, row);
  280. les->Asp[row] = spvector;
  281. }
  282. else
  283. return -1;
  284. }
  285. else
  286. {
  287. return -1;
  288. }
  289. return 1;
  290. }
  291. /*!
  292. *
  293. * \brief prints the linear equation system to stdout
  294. *
  295. * <p>
  296. * Format:
  297. * A*x = b
  298. *
  299. * <p>
  300. * Example
  301. \verbatim
  302. 2 1 1 1 * 2 = 0.1
  303. 1 2 0 0 * 3 = 0.2
  304. 1 0 2 0 * 3 = 0.2
  305. 1 0 0 2 * 2 = 0.1
  306. \endverbatim
  307. *
  308. * \param les G_math_les *
  309. * \return void
  310. *
  311. * */
  312. void G_math_print_les(G_math_les * les)
  313. {
  314. int i, j, k, out;
  315. if (les->type == G_MATH_SPARSE_LES)
  316. {
  317. for (i = 0; i < les->rows; i++)
  318. {
  319. for (j = 0; j < les->cols; j++)
  320. {
  321. out = 0;
  322. for (k = 0; k < les->Asp[i]->cols; k++)
  323. {
  324. if (les->Asp[i]->index[k] == j)
  325. {
  326. fprintf(stdout, "%4.5f ", les->Asp[i]->values[k]);
  327. out = 1;
  328. }
  329. }
  330. if (!out)
  331. fprintf(stdout, "%4.5f ", 0.0);
  332. }
  333. if (les->x)
  334. fprintf(stdout, " * %4.5f", les->x[i]);
  335. if (les->b)
  336. fprintf(stdout, " = %4.5f ", les->b[i]);
  337. fprintf(stdout, "\n");
  338. }
  339. }
  340. else
  341. {
  342. for (i = 0; i < les->rows; i++)
  343. {
  344. for (j = 0; j < les->cols; j++)
  345. {
  346. fprintf(stdout, "%4.5f ", les->A[i][j]);
  347. }
  348. if (les->x)
  349. fprintf(stdout, " * %4.5f", les->x[i]);
  350. if (les->b)
  351. fprintf(stdout, " = %4.5f ", les->b[i]);
  352. fprintf(stdout, "\n");
  353. }
  354. }
  355. return;
  356. }
  357. /*!
  358. * \brief Release the memory of the linear equation system
  359. *
  360. * \param les G_math_les *
  361. * \return void
  362. *
  363. * */
  364. void G_math_free_les(G_math_les * les)
  365. {
  366. int i;
  367. if (les->type == G_MATH_SPARSE_LES)
  368. G_debug(2, "Releasing memory of a sparse linear equation system\n");
  369. else
  370. G_debug(2, "Releasing memory of a regular linear equation system\n");
  371. if (les)
  372. {
  373. if (les->x)
  374. G_free(les->x);
  375. if (les->b)
  376. G_free(les->b);
  377. if (les->type == G_MATH_SPARSE_LES)
  378. {
  379. if (les->Asp)
  380. {
  381. for (i = 0; i < les->rows; i++)
  382. if (les->Asp[i])
  383. G_math_free_spvector(les->Asp[i]);
  384. G_free(les->Asp);
  385. }
  386. }
  387. else
  388. {
  389. /*We don't know if the rows have been changed by pivoting,
  390. * so we restore the data pointer*/
  391. les->A[0] = les->data;
  392. G_free_matrix(les->A);
  393. }
  394. free(les);
  395. }
  396. return;
  397. }
  398. /*!
  399. * \brief Release the memory of the float linear equation system
  400. *
  401. * \param les G_math_f_les *
  402. * \return void
  403. *
  404. * */
  405. void G_math_free_f_les(G_math_f_les * les)
  406. {
  407. G_debug(2, "Releasing memory of a regular float linear equation system\n");
  408. if (les)
  409. {
  410. if (les->x)
  411. G_free(les->x);
  412. if (les->b)
  413. G_free(les->b);
  414. /*We don't know if the rows have been changed by pivoting,
  415. * so we restore the data pointer*/
  416. les->A[0] = les->data;
  417. G_free_fmatrix(les->A);
  418. free(les);
  419. }
  420. return;
  421. }