yafl_math.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /*******************************************************************************
  2. Copyright 2021 anonimous <shkolnick-kun@gmail.com> and contributors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing,
  8. software distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions
  11. and limitations under the License.
  12. ******************************************************************************/
  13. #ifndef YAFL_MATH_H
  14. #define YAFL_MATH_H
  15. /*Config file must be included at first place*/
  16. #include <yafl_config.h>
  17. #define _YAFL_CHECK(cond, err, file, func, line) \
  18. do { \
  19. if (YAFL_UNLIKELY(!(cond))) \
  20. { \
  21. YAFL_DBG("YAFL:The expression (%s) is false in \n function: %s", \
  22. #cond, func); \
  23. YAFL_DBG("\n file: %s\n line: %d\n will return: %s\n", \
  24. file, line, #err); \
  25. return err; \
  26. } \
  27. } while (0)
  28. #define YAFL_CHECK(cond, err) _YAFL_CHECK(cond, err, __FILE__, __func__, __LINE__)
  29. typedef enum {
  30. /*Warning flag masks*/
  31. YAFL_ST_MSK_REGULARIZED = 0x01,
  32. YAFL_ST_MSK_GLITCH_SMALL = 0x02,
  33. YAFL_ST_MSK_GLITCH_LARGE = 0x04,
  34. YAFL_ST_MSK_ANOMALY = 0x08,
  35. /*Everything is OK*/
  36. YAFL_ST_OK = 0x00,
  37. /*Warning statuses (see Warning flag masks)*/
  38. YAFL_ST_R = 0x01,
  39. YAFL_ST_S = 0x02,
  40. YAFL_ST_SR = 0x03,
  41. YAFL_ST_L = 0x04,
  42. YAFL_ST_LR = 0x05,
  43. YAFL_ST_SL = 0x06,
  44. YAFL_ST_SLR = 0x07,
  45. YAFL_ST_A = 0x08,
  46. YAFL_ST_AR = 0x09,
  47. YAFL_ST_SA = 0x0a,
  48. YAFL_ST_SAR = 0x0b,
  49. YAFL_ST_LA = 0x0c,
  50. YAFL_ST_LAR = 0x0d,
  51. YAFL_ST_SLA = 0x0e,
  52. YAFL_ST_SLAR = 0x0f,
  53. /*Error threshold value (greater values are errors)*/
  54. YAFL_ST_ERR_THR = 0x010,
  55. /*Invalid argument numer*/
  56. YAFL_ST_INV_ARG_1 = 0x100,
  57. YAFL_ST_INV_ARG_2 = 0x110,
  58. YAFL_ST_INV_ARG_3 = 0x120,
  59. YAFL_ST_INV_ARG_4 = 0x130,
  60. YAFL_ST_INV_ARG_5 = 0x140,
  61. YAFL_ST_INV_ARG_6 = 0x150,
  62. YAFL_ST_INV_ARG_7 = 0x160,
  63. YAFL_ST_INV_ARG_8 = 0x170,
  64. YAFL_ST_INV_ARG_9 = 0x180,
  65. YAFL_ST_INV_ARG_10 = 0x190,
  66. YAFL_ST_INV_ARG_11 = 0x1a0,
  67. YAFL_ST_INV_ARG_12 = 0x1b0
  68. } yaflStatusEn;
  69. /* We need some way of printing human readable statuses */
  70. char * yafl_fail_dsc(yaflStatusEn status);
  71. #define _YAFL_TRY(status, exp, file, func, line) \
  72. do { \
  73. (status) |= (exp); \
  74. if (YAFL_UNLIKELY(YAFL_ST_ERR_THR <= (status))) \
  75. { \
  76. YAFL_DBG("YAFL:The expression (%s) gave an error in \n function: %s", \
  77. #exp, func); \
  78. YAFL_DBG("\n file: %s\n line: %d\n will return: %s\n", \
  79. file, line, yafl_fail_dsc(status)); \
  80. return status; \
  81. } \
  82. } while (0)
  83. #define YAFL_TRY(status, exp) _YAFL_TRY(status, exp, __FILE__, __func__, __LINE__)
  84. /*=======================================================================================
  85. Basic operations
  86. =======================================================================================*/
  87. /*
  88. Notation:
  89. [nN] - number
  90. [vV] - vector
  91. [mM] - matrix
  92. [bB] - matrix block
  93. [dD] - diagonal matrix
  94. [uU] - upper triangular unit matrix
  95. [lL] - lower triangular unit matrix
  96. res - result of operation
  97. <*>[tT] - transposed *, e.g. vt is transposed vector
  98. <*>[rR] - reversed *, e.d. rn is 1/n
  99. x - multiplication
  100. sz - size of a vector or a square/triangular matrix
  101. WARNING: Only a few functions/macros may be used for in place processing!!!
  102. --------------------------------------------------------------------------------------------------------
  103. Function/Macro (May be used for in place processing) NumPy expr
  104. ------------------------------------------------------------------------------------------------------*/
  105. yaflStatusEn yafl_math_set_vxn(yaflInt sz, yaflFloat *res, yaflFloat *v, yaflFloat n); /* res = n*v */
  106. yaflStatusEn yafl_math_add_vxn(yaflInt sz, yaflFloat *res, yaflFloat *v, yaflFloat n); /* res += n*v */
  107. yaflStatusEn yafl_math_sub_vxn(yaflInt sz, yaflFloat *res, yaflFloat *v, yaflFloat n); /* res -= n*v */
  108. yaflStatusEn yafl_math_set_vrn(yaflInt sz, yaflFloat *res, yaflFloat *v, yaflFloat n); /* res = v/n */
  109. yaflStatusEn yafl_math_add_vrn(yaflInt sz, yaflFloat *res, yaflFloat *v, yaflFloat n); /* res += v/n */
  110. yaflStatusEn yafl_math_sub_vrn(yaflInt sz, yaflFloat *res, yaflFloat *v, yaflFloat n); /* res -= v/n */
  111. yaflStatusEn yafl_math_set_vxv(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res = a*b */
  112. yaflStatusEn yafl_math_add_vxv(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res += a*b */
  113. yaflStatusEn yafl_math_sub_vxv(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res -= a*b */
  114. yaflStatusEn yafl_math_set_vrv(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res = a/b */
  115. yaflStatusEn yafl_math_add_vrv(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res += a/b */
  116. yaflStatusEn yafl_math_sub_vrv(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res -= a/b */
  117. #define YAFL_MATH_SET_DV yafl_math_set_vxv /* res = d.dot(v) */
  118. #define YAFL_MATH_ADD_DV yafl_math_add_vxv /* res += d.dot(v) */
  119. #define YAFL_MATH_SUB_DV yafl_math_sub_vxv /* res -= d.dot(v) */
  120. #define YAFL_MATH_SET_RDV(sz, res, a, b) yafl_math_set_vrv(sz, res, b, a) /* res = (1/d).dot(v)*/
  121. #define YAFL_MATH_ADD_RDV(sz, res, a, b) yafl_math_add_vrv(sz, res, b, a) /* res += (1/d).dot(v)*/
  122. #define YAFL_MATH_SUB_RDV(sz, res, a, b) yafl_math_sub_vrv(sz, res, b, a) /* res += (1/d).dot(v)*/
  123. #define YAFL_MATH_SET_VTD yafl_math_set_vxv /* res = v.T.dot(d) */
  124. #define YAFL_MATH_ADD_VTD yafl_math_add_vxv /* res += v.T.dot(d) */
  125. #define YAFL_MATH_SUB_VTD yafl_math_sub_vxv /* res -= v.T.dot(d) */
  126. #define YAFL_MATH_SET_VTRD(sz, res, a, b) yafl_math_set_vrv(sz, res, b, a) /* res = v.T.dot(1/d)*/
  127. #define YAFL_MATH_ADD_VTRD(sz, res, a, b) yafl_math_add_vrv(sz, res, b, a) /* res += v.T.dot(1/d)*/
  128. #define YAFL_MATH_SUB_VTRD(sz, res, a, b) yafl_math_sub_vrv(sz, res, b, a) /* res += v.T.dot(1/d)*/
  129. /*
  130. m - rectangular matrix
  131. v - vector
  132. nc - number of columns in a matrix
  133. nr - number of rows in a matrix
  134. -----------------------------------------------------------------------------------------------------------------------------------------------
  135. Function/Macro NumPy expr
  136. ---------------------------------------------------------------------------------------------------------------------------------------------*/
  137. yaflStatusEn yafl_math_vtv(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* a.T.dot(b) */
  138. yaflStatusEn yafl_math_set_vvt(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res = outer(a, b) */
  139. yaflStatusEn yafl_math_add_vvt(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res += outer(a, b) */
  140. yaflStatusEn yafl_math_sub_vvt(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res -= outer(a, b) */
  141. yaflStatusEn yafl_math_set_vvtxn(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b, yaflFloat n); /* res = outer(a, b) * n */
  142. yaflStatusEn yafl_math_add_vvtxn(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b, yaflFloat n); /* res += outer(a, b) * n */
  143. yaflStatusEn yafl_math_sub_vvtxn(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b, yaflFloat n); /* res -= outer(a, b) * n */
  144. /*
  145. m - rectangular matrix
  146. v - vector
  147. nc - number of columns in a matrix
  148. nr - number of rows in a matrix
  149. ----------------------------------------------------------------------------------------------------------------------------------------
  150. Function/Macro NumPy expr
  151. --------------------------------------------------------------------------------------------------------------------------------------*/
  152. yaflStatusEn yafl_math_set_mv(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res = a.dot(b) */
  153. yaflStatusEn yafl_math_add_mv(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res += a.dot(b) */
  154. yaflStatusEn yafl_math_sub_mv(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res -= a.dot(b) */
  155. yaflStatusEn yafl_math_set_vtm(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res = a.T.dot(b) */
  156. yaflStatusEn yafl_math_add_vtm(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res += a.T.dot(b) */
  157. yaflStatusEn yafl_math_sub_vtm(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res -= a.T.dot(b) */
  158. /*ncr - number of columns of in @a and of rows in @b*/
  159. yaflStatusEn yafl_math_set_mm(yaflInt nr, yaflInt ncr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res = a.dot(b) */
  160. yaflStatusEn yafl_math_add_mm(yaflInt nr, yaflInt ncr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res += a.dot(b) */
  161. yaflStatusEn yafl_math_sub_mm(yaflInt nr, yaflInt ncr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res -= a.dot(b) */
  162. /*
  163. m - rectangular matrix
  164. u - upper triangular unit matrix
  165. v - vector
  166. --------------------------------------------------------------------------------------------------------------------------
  167. Function/Macro NumPy expr
  168. ------------------------------------------------------------------------------------------------------------------------*/
  169. yaflStatusEn yafl_math_set_vtu(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res = a.T.dot(b) */
  170. yaflStatusEn yafl_math_add_vtu(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res += a.T.dot(b) */
  171. yaflStatusEn yafl_math_sub_vtu(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res -= a.T.dot(b) */
  172. yaflStatusEn yafl_math_set_uv(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res = a.dot(b) */
  173. yaflStatusEn yafl_math_add_uv(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res += a.dot(b) */
  174. yaflStatusEn yafl_math_sub_uv(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res -= a.dot(b) */
  175. yaflStatusEn yafl_math_set_mu(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res = a.dot(b) */
  176. yaflStatusEn yafl_math_add_mu(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res += a.dot(b) */
  177. yaflStatusEn yafl_math_sub_mu(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b); /* res -= a.dot(b) */
  178. yaflStatusEn yafl_math_set_u(yaflInt sz, yaflFloat *res, yaflFloat *u); /* res = u */
  179. yaflStatusEn yafl_math_add_u(yaflInt sz, yaflFloat *res, yaflFloat *u); /* res += u */
  180. yaflStatusEn yafl_math_sub_u(yaflInt sz, yaflFloat *res, yaflFloat *u); /* res -= u */
  181. /*Matrix row size and block start address*/
  182. #define YAFL_BLK_PTR(m,nc,r,c) ((yaflFloat *)m + nc * r + c)
  183. #define YAFL_BLK(m,nc,r,c) nc, YAFL_BLK_PTR(m,nc,r,c)
  184. /*For test purposes...*/
  185. static inline yaflFloat * _yafl_blk_ptr(yaflFloat * m, yaflInt nc, yaflInt r, yaflInt c)
  186. {
  187. return YAFL_BLK_PTR(m,nc,r,c);
  188. }
  189. /*
  190. Block operations:
  191. m - rectangular matrix
  192. u - upper triangular unit matrix
  193. v - vector
  194. ------------------------------------------------------------------------------------------------------------------------
  195. Function/Macro NumPy expr
  196. ----------------------------------------------------------------------------------------------------------------------*/
  197. yaflStatusEn yafl_math_bset_m(yaflInt nc, yaflFloat *res, yaflInt sr, yaflInt sc, yaflFloat *a); /* res[:sr, :sc] = a */
  198. yaflStatusEn yafl_math_badd_m(yaflInt nc, yaflFloat *res, yaflInt sr, yaflInt sc, yaflFloat *a); /* res[:sr, :sc] += a */
  199. yaflStatusEn yafl_math_bsub_m(yaflInt nc, yaflFloat *res, yaflInt sr, yaflInt sc, yaflFloat *a); /* res[:sr, :sc] -= a */
  200. #define YAFL_MATH_BSET_M(nc, r, c, m, sr, sc, a) yafl_math_bset_u(YAFL_BLK(m,nc,r,c), sr, sc, a) /* m[r:r+sz, c:c+sz] = a */
  201. #define YAFL_MATH_BADD_M(nc, r, c, m, sr, sc, a) yafl_math_badd_u(YAFL_BLK(m,nc,r,c), sr, sc, a) /* m[r:r+sz, c:c+sz] += a */
  202. #define YAFL_MATH_BSUB_M(nc, r, c, m, sr, sc, a) yafl_math_bsub_u(YAFL_BLK(m,nc,r,c), sr, sc, a) /* m[r:r+sz, c:c+sz] -= a */
  203. yaflStatusEn yafl_math_bset_u(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *u); /* res[:sz, :sz] = u */
  204. yaflStatusEn yafl_math_badd_u(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *u); /* res[:sz, :sz] += u */
  205. yaflStatusEn yafl_math_bsub_u(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *u); /* res[:sz, :sz] -= u */
  206. #define YAFL_MATH_BSET_U(nc, r, c, m, sz, u) yafl_math_bset_u(YAFL_BLK(m,nc,r,c), sz, u) /* m[r:r+sz, c:c+sz] = u */
  207. #define YAFL_MATH_BADD_U(nc, r, c, m, sz, u) yafl_math_badd_u(YAFL_BLK(m,nc,r,c), sz, u) /* m[r:r+sz, c:c+sz] += u */
  208. #define YAFL_MATH_BSUB_U(nc, r, c, m, sz, u) yafl_math_bsub_u(YAFL_BLK(m,nc,r,c), sz, u) /* m[r:r+sz, c:c+sz] -= u */
  209. yaflStatusEn yafl_math_bset_ut(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *u); /* res[:sz, :sz] = u.T */
  210. yaflStatusEn yafl_math_badd_ut(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *u); /* res[:sz, :sz] += u.T */
  211. yaflStatusEn yafl_math_bsub_ut(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *u); /* res[:sz, :sz] -= u.T */
  212. #define YAFL_MATH_BSET_UT(nc, r, c, m, sz, u) yafl_math_bset_u(YAFL_BLK(m,nc,r,c), sz, u) /* m[r:r+sz, c:c+sz] = u.T */
  213. #define YAFL_MATH_BADD_UT(nc, r, c, m, sz, u) yafl_math_badd_u(YAFL_BLK(m,nc,r,c), sz, u) /* m[r:r+sz, c:c+sz] += u.T */
  214. #define YAFL_MATH_BSUB_UT(nc, r, c, m, sz, u) yafl_math_bsub_u(YAFL_BLK(m,nc,r,c), sz, u) /* m[r:r+sz, c:c+sz] -= u.T */
  215. yaflStatusEn yafl_math_bset_v(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *v); /* res[:sz, 0] = v */
  216. yaflStatusEn yafl_math_badd_v(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *v); /* res[:sz, 0] += v */
  217. yaflStatusEn yafl_math_bsub_v(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *v); /* res[:sz, 0] -= v */
  218. #define YAFL_MATH_BSET_V(nc, r, c, m, sz, v) yafl_math_bset_v(YAFL_BLK(m,nc,r,c), sz, v) /* m[r:r+sz, c] = v */
  219. #define YAFL_MATH_BADD_V(nc, r, c, m, sz, v) yafl_math_badd_v(YAFL_BLK(m,nc,r,c), sz, v) /* m[r:r+sz, c] += v */
  220. #define YAFL_MATH_BSUB_V(nc, r, c, m, sz, v) yafl_math_bsub_v(YAFL_BLK(m,nc,r,c), sz, v) /* m[r:r+sz, c] -= v */
  221. /*
  222. Block operations:
  223. m - rectangular matrix
  224. v - vector
  225. -------------------------------------------------------------------------------------------------------------------------------------------
  226. Function/Macro NumPy expr
  227. -----------------------------------------------------------------------------------------------------------------------------------------*/
  228. yaflStatusEn yafl_math_bset_vvt(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *a, yaflFloat *b); /* res[:sz, :sz] = outer(a, b) */
  229. yaflStatusEn yafl_math_badd_vvt(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *a, yaflFloat *b); /* res[:sz, :sz] += outer(a, b) */
  230. yaflStatusEn yafl_math_bsub_vvt(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *a, yaflFloat *b); /* res[:sz, :sz] -= outer(a, b) */
  231. #define YAFL_MATH_BSET_VVT(nc, r, c, m, sz, a, b) yafl_math_bset_vvt(YAFL_BLK(m,nc,r,c), sz, a, b) /* m[r:r+sz, c:c+sz] = outer(a, b) */
  232. #define YAFL_MATH_BADD_VVT(nc, r, c, m, sz, a, b) yafl_math_badd_vvt(YAFL_BLK(m,nc,r,c), sz, a, b) /* m[r:r+sz, c:c+sz] += outer(a, b) */
  233. #define YAFL_MATH_BSUB_VVT(nc, r, c, m, sz, a, b) yafl_math_bsub_vvt(YAFL_BLK(m,nc,r,c), sz, a, b) /* m[r:r+sz, c:c+sz] -= outer(a, b) */
  234. /*
  235. Block operations:
  236. m - rectangular matrix
  237. u - upper triangular unit matrix
  238. rnc - number of columns in result matrices
  239. ----------------------------------------------------------------------------------------------------------------------------------------------------
  240. Function/Macro NumPy expr
  241. --------------------------------------------------------------------------------------------------------------------------------------------------*/
  242. yaflStatusEn yafl_math_bset_mu(yaflInt rnc, yaflFloat *res, yaflInt nr, yaflInt nc, yaflFloat *a, yaflFloat *b); /* res[:nr, :nc] = a.dot(b) */
  243. yaflStatusEn yafl_math_badd_mu(yaflInt rnc, yaflFloat *res, yaflInt nr, yaflInt nc, yaflFloat *a, yaflFloat *b); /* res[:nr, :nc] += a.dot(b) */
  244. yaflStatusEn yafl_math_bsub_mu(yaflInt rnc, yaflFloat *res, yaflInt nr, yaflInt nc, yaflFloat *a, yaflFloat *b); /* res[:nr, :nc] -= a.dot(b) */
  245. #define YAFL_MATH_BSET_MU(rnc, r, c, m, nr, nc, a, b) yafl_math_bset_mu(YAFL_BLK(m,rnc,r,c), nr, nc, a, b) /* m[r:r+nr, c:c+nc] = a.dot(b) */
  246. #define YAFL_MATH_BADD_MU(rnc, r, c, m, nr, nc, a, b) yafl_math_badd_mu(YAFL_BLK(m,rnc,r,c), nr, nc, a, b) /* m[r:r+nr, c:c+nc] += a.dot(b) */
  247. #define YAFL_MATH_BSUB_MU(rnc, r, c, m, nr, nc, a, b) yafl_math_bsub_mu(YAFL_BLK(m,rnc,r,c), nr, nc, a, b) /* m[r:r+nr, c:c+nc] -= a.dot(b) */
  248. /*
  249. Block operations:
  250. u - upper triangular unit matrix
  251. rnc - number of columns in result matrices
  252. anc - number of columns in a matrices blocks
  253. Warning:
  254. Matrix blocks a and res must not overlap!
  255. ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  256. Function/Macro NumPy expr
  257. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
  258. yaflStatusEn yafl_math_bset_bu(yaflInt rnc, yaflFloat *res, yaflInt nr, yaflInt nc, yaflInt anc, yaflFloat *a, yaflFloat *b); /* res[:nr, :nc] = a[:nr, :nc].dot(b) */
  259. yaflStatusEn yafl_math_badd_bu(yaflInt rnc, yaflFloat *res, yaflInt nr, yaflInt nc, yaflInt anc, yaflFloat *a, yaflFloat *b); /* res[:nr, :nc] += a[:nr, :nc].dot(b) */
  260. yaflStatusEn yafl_math_bsub_bu(yaflInt rnc, yaflFloat *res, yaflInt nr, yaflInt nc, yaflInt anc, yaflFloat *a, yaflFloat *b); /* res[:nr, :nc] -= a[:nr, :nc].dot(b) */
  261. #define YAFL_MATH_BSET_BU(rnc, r, c, m, nr, nc, anc, ar, ac, a, b) yafl_math_bset_bu(YAFL_BLK(m,rnc,r,c), nr, nc, YAFL_BLK(a,anc,ar,ac), b) /* m[r:r+nr, c:c+nc] = a[ar:ar+nr, ac:ac+nc].dot(b) */
  262. #define YAFL_MATH_BADD_BU(rnc, r, c, m, nr, nc, anc, ar, ac, a, b) yafl_math_badd_bu(YAFL_BLK(m,rnc,r,c), nr, nc, YAFL_BLK(a,anc,ar,ac), b) /* m[r:r+nr, c:c+nc] += a[ar:ar+nr, ac:ac+nc].dot(b) */
  263. #define YAFL_MATH_BSUB_BU(rnc, r, c, m, nr, nc, anc, ar, ac, a, b) yafl_math_bsub_bu(YAFL_BLK(m,rnc,r,c), nr, nc, YAFL_BLK(a,anc,ar,ac), b) /* m[r:r+nr, c:c+nc] -= a[ar:ar+nr, ac:ac+nc].dot(b) */
  264. /*
  265. Back substitution:
  266. m - rectangular matrix
  267. u - upper triangular unit matrix
  268. v - vector
  269. ------------------------------------------------------------------------------------------------------------------
  270. Function/Macro NumPy expr
  271. ----------------------------------------------------------------------------------------------------------------*/
  272. /*res is vector*/
  273. yaflStatusEn yafl_math_ruv(yaflInt sz, yaflFloat *res, yaflFloat *u); /*res = linalg.inv(u).dot(res)*/
  274. yaflStatusEn yafl_math_rutv(yaflInt sz, yaflFloat *res, yaflFloat *u); /*res = linalg.inv(u.T).dot(res)*/
  275. /*res is matrix*/
  276. yaflStatusEn yafl_math_rum(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *u); /*res = linalg.inv(u).dot(res)*/
  277. /*
  278. Modified Weighted Gram-Schmidt update (for UDU' decomposition)
  279. Does in place:
  280. res_u, res_d = MWGS(w,d)
  281. Warning:
  282. Matrix w is not valid after call.
  283. */
  284. yaflStatusEn yafl_math_mwgsu(yaflInt nr, yaflInt nc, yaflFloat *res_u, yaflFloat *res_d, yaflFloat *w, yaflFloat *d);
  285. /*
  286. Rank 1 UDU' update.
  287. Based on:
  288. 1. Gill, Murray, and Wright, "Practical Optimization", p42.
  289. 2. Bierman, "Factorization Methods for Discrete Sequential Estimation", p44.
  290. Does in place:
  291. p = u.dot(d.dot(u.T))
  292. p += alpha * outer(v,v.T)
  293. u,d = udu(p)
  294. Warning:
  295. Vector v is not valid after call.
  296. TODO: add doc with derivation!
  297. */
  298. yaflStatusEn yafl_math_udu_up(yaflInt sz, yaflFloat *res_u, yaflFloat *res_d, yaflFloat alpha, yaflFloat *v);
  299. /*
  300. Rank 1 UDU' downdate.
  301. Based on:
  302. 1. Gill, Murray, and Wright, "Practical Optimization", p43.
  303. 2. Bierman, "Factorization Methods for Discrete Sequential Estimation", p44.
  304. Does in place:
  305. p = u.dot(d.dot(u.T))
  306. p -= alpha * outer(v,v.T)
  307. u,d = udu(p)
  308. Warning:
  309. Vector v is not valid after call.
  310. TODO: add doc with derivation!
  311. */
  312. yaflStatusEn yafl_math_udu_down(yaflInt sz, yaflFloat *res_u, yaflFloat *res_d, yaflFloat alpha, yaflFloat *v);
  313. #endif // YAFL_MATH_H