12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070 |
- /*******************************************************************************
- Copyright 2021 anonimous <shkolnick-kun@gmail.com> and contributors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions
- and limitations under the License.
- ******************************************************************************/
- #include "yafl_math.h"
- /* We need some way of printing human readable statuses */
- char * yafl_fail_dsc(yaflStatusEn status)
- {
- switch (status & 0xff0)
- {
- #define CASE_DSC(err) do { \
- case err: \
- { \
- return #err; \
- } \
- } while (0)
- CASE_DSC(YAFL_ST_INV_ARG_1);
- CASE_DSC(YAFL_ST_INV_ARG_2);
- CASE_DSC(YAFL_ST_INV_ARG_3);
- CASE_DSC(YAFL_ST_INV_ARG_4);
- CASE_DSC(YAFL_ST_INV_ARG_5);
- CASE_DSC(YAFL_ST_INV_ARG_6);
- CASE_DSC(YAFL_ST_INV_ARG_7);
- CASE_DSC(YAFL_ST_INV_ARG_8);
- CASE_DSC(YAFL_ST_INV_ARG_9);
- CASE_DSC(YAFL_ST_INV_ARG_10);
- CASE_DSC(YAFL_ST_INV_ARG_11);
- CASE_DSC(YAFL_ST_INV_ARG_12);
- #undef CASE_DSC
- default:
- {
- return "Internal error!!!";
- }
- }
- }
- #define YAFL_DO_VXN(name, op) \
- yaflStatusEn name(yaflInt sz, yaflFloat *res, yaflFloat *v, yaflFloat n) \
- { \
- yaflInt k; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(v, YAFL_ST_INV_ARG_3); \
- \
- for (k = 0; k < sz; k++) \
- { \
- res[k] op v[k] * n; \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_VXN(yafl_math_set_vxn, =)
- YAFL_DO_VXN(yafl_math_add_vxn, +=)
- YAFL_DO_VXN(yafl_math_sub_vxn, -=)
- #define YAFL_DO_VRN(name, op) \
- yaflStatusEn name(yaflInt sz, yaflFloat *res, yaflFloat *v, yaflFloat n) \
- { \
- yaflStatusEn status; \
- yaflInt k; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(v, YAFL_ST_INV_ARG_3); \
- \
- status = YAFL_ST_OK; \
- if (n > 0.0) \
- { \
- if (n < YAFL_EPS) \
- { \
- n = YAFL_EPS; \
- status = YAFL_ST_R; \
- } \
- } \
- else \
- { \
- if (n > -YAFL_EPS) \
- { \
- n = -YAFL_EPS; \
- status = YAFL_ST_R; \
- } \
- } \
- \
- for (k = 0; k < sz; k++) \
- { \
- res[k] op v[k] / n; \
- } \
- return status; \
- }
- YAFL_DO_VRN(yafl_math_set_vrn, =)
- YAFL_DO_VRN(yafl_math_add_vrn, +=)
- YAFL_DO_VRN(yafl_math_sub_vrn, -=)
- #define YAFL_DO_VXV(name, op) \
- yaflStatusEn name(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b)\
- { \
- yaflInt k; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_3); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_4); \
- \
- for (k = 0; k < sz; k++) \
- { \
- res[k] op a[k] * b[k]; \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_VXV(yafl_math_set_vxv, =)
- YAFL_DO_VXV(yafl_math_add_vxv, +=)
- YAFL_DO_VXV(yafl_math_sub_vxv, -=)
- #define YAFL_DO_VRV(name, op) \
- yaflStatusEn name(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b)\
- { \
- yaflInt k; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_3); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_4); \
- \
- for (k = 0; k < sz; k++) \
- { \
- res[k] op a[k] / b[k]; \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_VRV(yafl_math_set_vrv, =)
- YAFL_DO_VRV(yafl_math_add_vrv, +=)
- YAFL_DO_VRV(yafl_math_sub_vrv, -=)
- yaflStatusEn yafl_math_vtv(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b)
- {
- yaflInt k;
- yaflFloat r;
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2);
- YAFL_CHECK(a, YAFL_ST_INV_ARG_3);
- YAFL_CHECK(b, YAFL_ST_INV_ARG_4);
- r = a[0] * b[0];
- for (k = 1; k < sz; k++)
- {
- r += a[k] * b[k];
- }
- *res = r;
- return YAFL_ST_OK;
- }
- #define YAFL_DO_VVT(name, op) \
- yaflStatusEn name(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b) \
- { \
- yaflInt j; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_3); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_4); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_5); \
- \
- for (j = 0; j < nr; j++) \
- { \
- yaflInt k; \
- yaflInt ncj; \
- yaflFloat aj; \
- \
- ncj = nc * j; \
- aj = a[j]; \
- \
- for (k = 0; k < nc; k++) \
- { \
- res[ncj + k] op aj * b[k]; \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_VVT(yafl_math_set_vvt, =)
- YAFL_DO_VVT(yafl_math_add_vvt, +=)
- YAFL_DO_VVT(yafl_math_sub_vvt, -=)
- #define YAFL_DO_VVTXN(name, op) \
- yaflStatusEn name(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b, yaflFloat n) \
- { \
- yaflInt j; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_3); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_4); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_5); \
- \
- for (j = 0; j < nr; j++) \
- { \
- yaflInt k; \
- yaflInt ncj; \
- yaflFloat aj; \
- \
- ncj = nc * j; \
- aj = a[j] * n; \
- \
- for (k = 0; k < nc; k++) \
- { \
- res[ncj + k] op aj * b[k]; \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_VVTXN(yafl_math_set_vvtxn, =)
- YAFL_DO_VVTXN(yafl_math_add_vvtxn, +=)
- YAFL_DO_VVTXN(yafl_math_sub_vvtxn, -=)
- #define YAFL_DO_MV(name, op1, op2) \
- yaflStatusEn name(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b) \
- { \
- yaflInt j; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_3); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_4); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_5); \
- \
- for (j = 0; j < nr; j++) \
- { \
- yaflInt k; \
- yaflInt ncj; \
- yaflFloat resj; \
- \
- ncj = nc * j; \
- resj = res[j]; \
- resj op1 a[ncj] * b[0]; \
- \
- for (k = 1; k < nc; k++) \
- { \
- resj op2 a[ncj + k] * b[k]; \
- } \
- res[j] = resj; \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_MV(yafl_math_set_mv, =, +=)
- YAFL_DO_MV(yafl_math_add_mv, +=, +=)
- YAFL_DO_MV(yafl_math_sub_mv, -=, -=)
- #define YAFL_DO_VTM(name, op1, op2) \
- yaflStatusEn name(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b) \
- { \
- yaflInt j; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_3); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_4); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_5); \
- \
- for (j = 0; j < nc; j++) \
- { \
- res[j] op1 a[0] * b[j]; \
- } \
- \
- for (j = 1; j < nr; j++) \
- { \
- yaflInt k; \
- yaflInt ncj; \
- yaflFloat aj; \
- \
- ncj = nc * j; \
- aj = a[j]; \
- \
- for (k = 0; k < nc; k++) \
- { \
- res[k] op2 aj * b[ncj + k]; \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_VTM(yafl_math_set_vtm, =, +=)
- YAFL_DO_VTM(yafl_math_add_vtm, +=, +=)
- YAFL_DO_VTM(yafl_math_sub_vtm, -=, -=)
- /*This is right as it is OMP friendly style*/
- #define YAFL_DO_MM(name, op1, op2) \
- yaflStatusEn name(yaflInt nr, yaflInt ncr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b) \
- { \
- yaflInt i; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_4); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_5); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_6); \
- \
- for (i = 0; i < nr; i++) \
- { \
- yaflInt j; \
- yaflInt k; \
- yaflInt nci; \
- yaflInt ncri; \
- \
- nci = nc * i; \
- ncri = ncr * i; \
- \
- for (k = 0; k < nc; k++) \
- { \
- res[nci + k] op1 a[ncri] * b[k]; \
- } \
- \
- for (j = 1; j < ncr; j++) \
- { \
- yaflInt ncj; \
- yaflFloat aij; \
- \
- ncj = nc * j; \
- aij = a[ncri + j]; \
- \
- for (k = 0; k < nc; k++) \
- { \
- res[nci + k] op2 aij * b[ncj + k]; \
- } \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_MM(yafl_math_set_mm, =, +=)
- YAFL_DO_MM(yafl_math_add_mm, +=, +=)
- YAFL_DO_MM(yafl_math_sub_mm, -=, -=)
- #define YAFL_DO_VTU(name, op1, op2) \
- yaflStatusEn name(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b) \
- { \
- yaflInt j; \
- yaflInt szj; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_3); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_4); \
- \
- for (j = 0; j < sz; j++) \
- { \
- res[j] op1 a[j]; \
- } \
- \
- for (szj = 0, j = 1; j < sz; szj += j++) \
- { \
- yaflInt k; \
- yaflFloat resj; \
- \
- resj = res[j]; \
- for (k = 0; k < j; k++) \
- { \
- resj op2 a[k] * b[k + szj]; \
- } \
- res[j] = resj; \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_VTU(yafl_math_set_vtu, =, +=)
- YAFL_DO_VTU(yafl_math_add_vtu, +=, +=)
- YAFL_DO_VTU(yafl_math_sub_vtu, -=, -=)
- #define YAFL_DO_UV(name, op1, op2) \
- yaflStatusEn name(yaflInt sz, yaflFloat *res, yaflFloat *a, yaflFloat *b) \
- { \
- yaflInt j; \
- yaflInt szj; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_3); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_4); \
- \
- for (j = 0; j < sz; j++) \
- { \
- res[j] op1 b[j]; \
- } \
- \
- for (szj = 0, j = 1; j < sz; szj += j++) \
- { \
- yaflInt k; \
- yaflFloat bj; \
- \
- bj = b[j]; \
- for (k = 0; k < j; k++) \
- { \
- res[k] op2 a[k + szj] * bj; \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_UV(yafl_math_set_uv, =, +=)
- YAFL_DO_UV(yafl_math_add_uv, +=, +=)
- YAFL_DO_UV(yafl_math_sub_uv, -=, -=)
- /*This is right as it is OMP friendly style*/
- #define YAFL_DO_MU(name, op1, op2) \
- yaflStatusEn name(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *a, yaflFloat *b) \
- { \
- yaflInt i; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_3); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_4); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_5); \
- \
- for (i = 0; i < nr; i++) \
- { \
- yaflInt j; \
- yaflInt nci; \
- yaflInt ncj; \
- \
- nci = nc * i; \
- \
- for (j = 0; j < nc; j++) \
- { \
- res[nci + j] op1 a[nci + j]; \
- } \
- \
- for (ncj = 0, j = 1; j < nc; ncj += j++) \
- { \
- yaflInt k; \
- yaflFloat resij; \
- \
- resij = res[nci + j]; \
- for (k = 0; k < j; k++) \
- { \
- resij op2 a[nci + k] * b[k + ncj]; \
- } \
- res[nci + j] = resij; \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_MU(yafl_math_set_mu, =, +=)
- YAFL_DO_MU(yafl_math_add_mu, +=, +=)
- YAFL_DO_MU(yafl_math_sub_mu, -=, -=)
- yaflStatusEn yafl_math_set_u(yaflInt sz, yaflFloat *res, yaflFloat *u)
- {
- yaflInt i;
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2);
- YAFL_CHECK(u, YAFL_ST_INV_ARG_3);
- for (i = 0; i < sz; i++)
- {
- yaflInt szi;
- yaflInt j;
- szi = sz * i;
- for (j = 0; j < i; j++)
- {
- res[szi + j] = 0.0;
- }
- res[szi + j] = 1.0;
- for (j++; j < sz; j++)
- {
- res[szi + j] = u[i + ((j - 1) * j) / 2];
- }
- }
- return YAFL_ST_OK;
- }
- #define YAFL_DO_U(name, op) \
- yaflStatusEn name(yaflInt sz, yaflFloat *res, yaflFloat *u) \
- { \
- yaflInt i; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(u, YAFL_ST_INV_ARG_3); \
- \
- for (i = 0; i < sz; i++) \
- { \
- yaflInt szi; \
- yaflInt j; \
- \
- res[(sz + 1) * i] op 1.0; \
- \
- szi = sz * i; \
- for (j = i + 1; j < sz; j++) \
- { \
- res[szi + j] op u[i + ((j - 1) * j) / 2]; \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_U(yafl_math_add_u, +=)
- YAFL_DO_U(yafl_math_sub_u, -=)
- #define YAFL_DO_BM(name, op) \
- yaflStatusEn name(yaflInt nc, yaflFloat *res, yaflInt sr, yaflInt sc, yaflFloat *a) \
- { \
- yaflInt j; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_4); \
- \
- for (j = 0; j < sr; j++) \
- { \
- yaflInt k; \
- yaflInt ncj; \
- yaflInt scj; \
- \
- ncj = nc * j; \
- scj = sc * j; \
- \
- for (k = 0; k < sc; k++) \
- { \
- res[ncj + k] op a[scj + k]; \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_BM(yafl_math_bset_m, =)
- YAFL_DO_BM(yafl_math_badd_m, +=)
- YAFL_DO_BM(yafl_math_bsub_m, -=)
- yaflStatusEn yafl_math_bset_u(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *u)
- {
- yaflInt i;
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2);
- YAFL_CHECK(u, YAFL_ST_INV_ARG_4);
- for (i = 0; i < sz; i++)
- {
- yaflInt nci;
- yaflInt j;
- nci = nc * i;
- for (j = 0; j < i; j++)
- {
- res[nci + j] = 0.0;
- }
- res[nci + j] = 1.0;
- for (j++; j < sz; j++)
- {
- res[nci + j] = u[i + ((j - 1) * j) / 2];
- }
- }
- return YAFL_ST_OK;
- }
- #define YAFL_DO_BU(name, op) \
- yaflStatusEn name(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *u) \
- { \
- yaflInt i; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(u, YAFL_ST_INV_ARG_4); \
- \
- for (i = 0; i < sz; i++) \
- { \
- yaflInt nci; \
- yaflInt j; \
- \
- res[(nc + 1) * i] op 1.0; \
- \
- nci = nc * i; \
- for (j = i + 1; j < sz; j++) \
- { \
- res[nci + j] op u[i + ((j - 1) * j) / 2]; \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_BU(yafl_math_badd_u, +=)
- YAFL_DO_BU(yafl_math_bsub_u, -=)
- yaflStatusEn yafl_math_bset_ut(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *u)
- {
- yaflInt i;
- yaflInt szi;
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2);
- YAFL_CHECK(u, YAFL_ST_INV_ARG_4);
- for (szi = 0, i = 0; i < sz; szi += i++)
- {
- yaflInt nci;
- yaflInt j;
- nci = nc * i;
- for (j = 0; j < i; j++)
- {
- res[nci + j] = u[j + szi];
- }
- res[nci + j] = 1.0;
- for (j++; j < sz; j++)
- {
- res[nci + j] = 0.0;
- }
- }
- return YAFL_ST_OK;
- }
- #define YAFL_DO_BUT(name, op) \
- yaflStatusEn name(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *u) \
- { \
- yaflInt i; \
- yaflInt szi; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(u, YAFL_ST_INV_ARG_4); \
- \
- for (szi = 0, i = 0; i < sz; szi += i++) \
- { \
- yaflInt nci; \
- yaflInt j; \
- \
- nci = nc * i; \
- for (j = 0; j < i; j++) \
- { \
- res[nci + j] op u[j + szi]; \
- } \
- \
- res[nci + j] op 1.0; \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_BUT(yafl_math_badd_ut, +=)
- YAFL_DO_BUT(yafl_math_bsub_ut, -=)
- #define YAFL_DO_BV(name, op) \
- yaflStatusEn name(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *v) \
- { \
- yaflInt i; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(v, YAFL_ST_INV_ARG_4); \
- \
- for (i = 0; i < sz; i++) \
- { \
- res[nc * i] op v[i]; \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_BV(yafl_math_bset_v, =)
- YAFL_DO_BV(yafl_math_badd_v, +=)
- YAFL_DO_BV(yafl_math_bsub_v, -=)
- #define YAFL_DO_BVVT(name, op) \
- yaflStatusEn name(yaflInt nc, yaflFloat *res, yaflInt sz, yaflFloat *a, yaflFloat *b) \
- { \
- yaflInt j; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_4); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_5); \
- \
- for (j = 0; j < sz; j++) \
- { \
- yaflInt k; \
- yaflInt ncj; \
- yaflFloat aj; \
- \
- ncj = nc * j; \
- aj = a[j]; \
- \
- for (k = 0; k < sz; k++) \
- { \
- res[ncj + k] op aj * b[k]; \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_BVVT(yafl_math_bset_vvt, =)
- YAFL_DO_BVVT(yafl_math_badd_vvt, +=)
- YAFL_DO_BVVT(yafl_math_bsub_vvt, -=)
- #define YAFL_DO_BMU(name, op1, op2) \
- yaflStatusEn name(yaflInt rnc, yaflFloat *res, yaflInt nr, yaflInt nc, yaflFloat *a, yaflFloat *b) \
- { \
- yaflInt i; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_5); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_6); \
- YAFL_CHECK(rnc >= nc, YAFL_ST_INV_ARG_1); \
- \
- for (i = 0; i < nr; i++) \
- { \
- yaflInt j; \
- yaflInt nci; \
- yaflInt rnci; \
- yaflInt ncj; \
- \
- nci = nc * i; \
- rnci = rnc * i; \
- \
- for (j = 0; j < nc; j++) \
- { \
- res[rnci + j] op1 a[nci + j]; \
- } \
- \
- for (ncj = 0, j = 1; j < nc; ncj += j++) \
- { \
- yaflInt k; \
- yaflFloat resij; \
- \
- resij = res[rnci + j]; \
- for (k = 0; k < j; k++) \
- { \
- resij op2 a[nci + k] * b[k + ncj]; \
- } \
- res[rnci + j] = resij; \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_BMU(yafl_math_bset_mu, =, +=)
- YAFL_DO_BMU(yafl_math_badd_mu, +=, +=)
- YAFL_DO_BMU(yafl_math_bsub_mu, -=, -=)
- #define YAFL_DO_BBU(name, op1, op2) \
- yaflStatusEn name(yaflInt rnc, yaflFloat *res, yaflInt nr, yaflInt nc, yaflInt anc, yaflFloat *a, yaflFloat *b) \
- { \
- yaflInt i; \
- \
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2); \
- YAFL_CHECK(a, YAFL_ST_INV_ARG_6); \
- YAFL_CHECK(b, YAFL_ST_INV_ARG_7); \
- YAFL_CHECK(rnc >= nc, YAFL_ST_INV_ARG_1); \
- YAFL_CHECK(anc >= nc, YAFL_ST_INV_ARG_5); \
- \
- for (i = 0; i < nr; i++) \
- { \
- yaflInt j; \
- yaflInt anci; \
- yaflInt rnci; \
- yaflInt ncj; \
- \
- anci = anc * i; \
- rnci = rnc * i; \
- \
- for (j = 0; j < nc; j++) \
- { \
- res[rnci + j] op1 a[anci + j]; \
- } \
- \
- for (ncj = 0, j = 1; j < nc; ncj += j++) \
- { \
- yaflInt k; \
- yaflFloat resij; \
- \
- resij = res[rnci + j]; \
- for (k = 0; k < j; k++) \
- { \
- resij op2 a[anci + k] * b[k + ncj]; \
- } \
- res[rnci + j] = resij; \
- } \
- } \
- return YAFL_ST_OK; \
- }
- YAFL_DO_BBU(yafl_math_bset_bu, =, +=)
- YAFL_DO_BBU(yafl_math_badd_bu, +=, +=)
- YAFL_DO_BBU(yafl_math_bsub_bu, -=, -=)
- yaflStatusEn yafl_math_ruv(yaflInt sz, yaflFloat *res, yaflFloat *u)
- {
- yaflInt j;
- yaflInt szj;
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2);
- YAFL_CHECK(u, YAFL_ST_INV_ARG_3);
- for (j = sz - 1, szj = ((j - 1) * j) / 2; j > 0; szj -= --j)
- /*for (j = sz - 1; j > 0; j--)*/
- {
- yaflInt i;
- yaflFloat resj;
- /*yaflInt szj;
- szj = ((j - 1)*j)/2;*/
- resj = res[j];
- for (i = j - 1; i >= 0; i--)
- {
- res[i] -= u[i + szj] * resj;
- }
- }
- return YAFL_ST_OK;
- }
- yaflStatusEn yafl_math_rutv(yaflInt sz, yaflFloat *res, yaflFloat *u)
- {
- yaflInt j;
- YAFL_CHECK(res, YAFL_ST_INV_ARG_2);
- YAFL_CHECK(u, YAFL_ST_INV_ARG_3);
- for (j = 0; j < sz - 1; j++)
- {
- yaflInt i;
- yaflFloat resj;
- resj = res[j];
- for (i = j + 1; i < sz; i++)
- {
- yaflInt szi;
- szi = ((i - 1)*i)/2;
- res[i] -= u[szi + j] * resj;
- }
- }
- return YAFL_ST_OK;
- }
- yaflStatusEn yafl_math_rum(yaflInt nr, yaflInt nc, yaflFloat *res, yaflFloat *u)
- {
- yaflInt j;
- yaflInt nrj;
- YAFL_CHECK(res, YAFL_ST_INV_ARG_3);
- YAFL_CHECK(u, YAFL_ST_INV_ARG_4);
- for (j = nr - 1, nrj = ((j - 1) * j) / 2; j > 0; nrj -= --j)
- {
- yaflInt ncj;
- yaflInt i;
- ncj = nc * j;
- for (i = j - 1; i >= 0; i--)
- {
- yaflInt k;
- yaflInt nci;
- yaflFloat uij;
- nci = nc * i;
- uij = u[i + nrj];
- for (k = nc - 1; k >= 0; k--)
- {
- res[nci + k] -= uij * res[ncj + k];
- }
- }
- }
- return YAFL_ST_OK;
- }
- yaflStatusEn yafl_math_mwgsu(yaflInt nr, yaflInt nc, yaflFloat *res_u, yaflFloat *res_d, yaflFloat *w, yaflFloat *d)
- {
- yaflStatusEn status = YAFL_ST_OK;
- yaflInt j;
- yaflInt nrj;
- YAFL_CHECK(res_u, YAFL_ST_INV_ARG_3);
- YAFL_CHECK(res_d, YAFL_ST_INV_ARG_4);
- YAFL_CHECK(w, YAFL_ST_INV_ARG_5);
- YAFL_CHECK(d, YAFL_ST_INV_ARG_6);
- for (j = nr - 1, nrj = ((j - 1) * j) / 2; j >= 0; nrj -= --j)
- {
- yaflInt ncj;
- yaflInt k;
- yaflFloat res_dj;
- yaflFloat wjk;
- ncj = nc * j;
- /*res_d[j] = w[j].dot(d * w[j])*/
- wjk = w[ncj + nc - 1];
- wjk *= wjk;
- res_dj = wjk * d[nc - 1];
- for (k = nc - 2; k >= 0; k--)
- {
- wjk = w[ncj + k];
- wjk *= wjk;
- res_dj += wjk * d[k];
- }
- /*Bad Eigenvalue workaround*/
- if (res_dj < YAFL_EPS)
- {
- res_d[j] = YAFL_EPS;
- for (k = j - 1; k >= 0; k--)
- {
- res_u[k + nrj] = 0;
- }
- status |= YAFL_ST_MSK_REGULARIZED;
- continue;
- }
- /*Good Eigenvalue*/
- res_d[j] = res_dj;
- for (k = j - 1; k >= 0; k--)
- {
- yaflInt nck;
- yaflInt i;
- yaflFloat res_ukj;
- nck = nc * k;
- /* res_u[k,j] = w[k].dot(d * w[j])/res_d[j] */
- res_ukj = w[nck] * d[0] * w[ncj] / res_dj;
- for (i = 1; i < nc; i++)
- {
- res_ukj += w[nck + i] * d[i] * w[ncj + i] / res_dj;
- }
- res_u[k + nrj] = res_ukj;
- /* w[k] -= res_u[k,j] * w[j] */
- w[nck + nc - 1] -= res_ukj * w[ncj + nc - 1];
- for (i = nc - 2; i >= 0; i--)
- {
- w[nck + i] -= res_ukj * w[ncj + i];
- }
- }
- }
- return status;
- }
- yaflStatusEn yafl_math_udu_up(yaflInt sz, yaflFloat *res_u, yaflFloat *res_d, yaflFloat alpha, yaflFloat *v)
- {
- yaflStatusEn status = YAFL_ST_OK;
- yaflInt j;
- yaflInt szj;
- YAFL_CHECK(res_u, YAFL_ST_INV_ARG_2);
- YAFL_CHECK(res_d, YAFL_ST_INV_ARG_3);
- YAFL_CHECK(v, YAFL_ST_INV_ARG_5);
- YAFL_CHECK(alpha >= 0, YAFL_ST_INV_ARG_4);
- for (j = sz - 1, szj = ((j - 1) * j) / 2; j >= 0; szj -= --j)
- {
- yaflInt k;
- yaflFloat pj;
- yaflFloat dj;
- yaflFloat res_dj;
- yaflFloat betaj;
- dj = res_d[j];
- pj = v[j];
- res_dj = dj + alpha * pj * pj;
- if (res_dj < YAFL_EPS)
- {
- res_dj = YAFL_EPS;
- status |= YAFL_ST_MSK_REGULARIZED;
- }
- betaj = alpha * pj / res_dj;
- /*Update res_d[j]*/
- res_d[j] = res_dj;
- /*Update res_u[:j,j]*/
- for (k = j - 1; k >= 0; k--)
- {
- /*Buffer vars*/
- yaflFloat ukj;
- yaflFloat vk;
- ukj = res_u[k + szj];
- vk = v[k] - pj * ukj;
- v[k] = vk;
- res_u[k + szj] = ukj + betaj * vk;
- }
- alpha *= dj / res_dj;
- }
- return status;
- }
- yaflStatusEn yafl_math_udu_down(yaflInt sz, yaflFloat *res_u, yaflFloat *res_d, yaflFloat alpha, yaflFloat *v)
- {
- yaflStatusEn status = YAFL_ST_OK;
- yaflInt j;
- yaflInt szj;
- yaflFloat pj;
- yaflFloat dj;
- YAFL_CHECK(res_u, YAFL_ST_INV_ARG_2);
- YAFL_CHECK(res_d, YAFL_ST_INV_ARG_3);
- YAFL_CHECK(v, YAFL_ST_INV_ARG_5);
- YAFL_CHECK(alpha >= 0, YAFL_ST_INV_ARG_4);
- /*Solve U*p = v*/
- yafl_math_ruv(sz, v, res_u);
- /*Compute alpha0*/
- pj = v[0];
- dj = pj * pj / res_d[0];
- for (j = 1; j < sz; j++)
- {
- if (res_d[j] < YAFL_EPS)
- {
- res_d[j] = YAFL_EPS;
- status |= YAFL_ST_MSK_REGULARIZED;
- }
- pj = v[j];
- dj += pj * pj / res_d[j];
- }
- dj = 1 - alpha * dj;
- if (dj < YAFL_EPS)
- {
- dj = YAFL_EPS;
- status |= YAFL_ST_MSK_REGULARIZED;
- }
- alpha /= dj;
- /*Conmpute update*/
- for (szj = 0, j = 0; j < sz; szj += j++)
- {
- yaflInt k;
- yaflFloat res_dj;
- yaflFloat betaj;
- dj = res_d[j];
- pj = v[j]; /*We don't need to do v[j] = pj; as it was done in #L774*/
- res_dj = dj * dj / (dj + alpha * pj * pj);
- /*No need to check dj or res_d[j] as it was set big enough in #L783*/
- betaj = alpha * pj / dj; /*Sign "-" will be used in #L825*/
- /*Update res_d[j]*/
- res_d[j] = res_dj;
- for (k = 0; k < j; k++)
- {
- /*Buffer vars*/
- yaflFloat ukj;
- yaflFloat vk;
- ukj = res_u[k + szj];
- vk = v[k];
- res_u[k + szj] = ukj - betaj * vk;
- v[k] = vk + pj * ukj;
- }
- alpha *= res_dj / dj;
- }
- return status;
- }
|