fun9_svd.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. //
  2. // File: svd.cpp
  3. //
  4. // MATLAB Coder version : 5.2
  5. // C/C++ source code generated on : 24-Mar-2023 11:40:08
  6. //
  7. // Include Files
  8. #include "fun9_svd.h"
  9. #include "rt_nonfinite.h"
  10. #include "fun9_xaxpy.h"
  11. #include "fun9_xnrm2.h"
  12. #include "fun9_xrotg.h"
  13. #include "coder_array.h"
  14. #include <cmath>
  15. // Function Definitions
  16. //
  17. // Arguments : const ::coder::array<double, 2U> &A
  18. // ::coder::array<double, 2U> &U
  19. // ::coder::array<double, 1U> &s
  20. // ::coder::array<double, 2U> &V
  21. // Return Type : void
  22. //
  23. namespace coder {
  24. namespace internal {
  25. void svd(const ::coder::array<double, 2U> &A, ::coder::array<double, 2U> &U,
  26. ::coder::array<double, 1U> &s, ::coder::array<double, 2U> &V)
  27. {
  28. array<double, 2U> Vf;
  29. array<double, 2U> b_A;
  30. array<double, 1U> b_s;
  31. array<double, 1U> e;
  32. array<double, 1U> work;
  33. double nrm;
  34. double r;
  35. double scale;
  36. double sm;
  37. int i;
  38. int k;
  39. int minnp;
  40. int n;
  41. int ns;
  42. int p;
  43. int qjj;
  44. b_A.set_size(A.size(0), A.size(1));
  45. ns = A.size(0) * A.size(1);
  46. for (i = 0; i < ns; i++) {
  47. b_A[i] = A[i];
  48. }
  49. n = A.size(0);
  50. p = A.size(1);
  51. qjj = A.size(0) + 1;
  52. ns = A.size(1);
  53. if (qjj < ns) {
  54. ns = qjj;
  55. }
  56. qjj = A.size(0);
  57. minnp = A.size(1);
  58. if (qjj < minnp) {
  59. minnp = qjj;
  60. }
  61. b_s.set_size(ns);
  62. for (i = 0; i < ns; i++) {
  63. b_s[i] = 0.0;
  64. }
  65. e.set_size(A.size(1));
  66. ns = A.size(1);
  67. for (i = 0; i < ns; i++) {
  68. e[i] = 0.0;
  69. }
  70. work.set_size(A.size(0));
  71. ns = A.size(0);
  72. for (i = 0; i < ns; i++) {
  73. work[i] = 0.0;
  74. }
  75. U.set_size(A.size(0), minnp);
  76. ns = A.size(0) * minnp;
  77. for (i = 0; i < ns; i++) {
  78. U[i] = 0.0;
  79. }
  80. Vf.set_size(A.size(1), A.size(1));
  81. ns = A.size(1) * A.size(1);
  82. for (i = 0; i < ns; i++) {
  83. Vf[i] = 0.0;
  84. }
  85. if ((A.size(0) == 0) || (A.size(1) == 0)) {
  86. int ii;
  87. qjj = A.size(0);
  88. if (qjj >= minnp) {
  89. qjj = minnp;
  90. }
  91. for (ii = 0; ii < qjj; ii++) {
  92. U[ii + U.size(0) * ii] = 1.0;
  93. }
  94. i = A.size(1);
  95. for (ii = 0; ii < i; ii++) {
  96. Vf[ii + Vf.size(0) * ii] = 1.0;
  97. }
  98. } else {
  99. double snorm;
  100. int ii;
  101. int jj;
  102. int m;
  103. int nct;
  104. int nctp1;
  105. int nmq;
  106. int nrt;
  107. int pmq;
  108. int q;
  109. int qp1;
  110. int qq;
  111. if (A.size(1) > 2) {
  112. qjj = A.size(1) - 2;
  113. } else {
  114. qjj = 0;
  115. }
  116. nrt = A.size(0);
  117. if (qjj < nrt) {
  118. nrt = qjj;
  119. }
  120. if (A.size(0) > 1) {
  121. qjj = A.size(0) - 1;
  122. } else {
  123. qjj = 0;
  124. }
  125. nct = A.size(1);
  126. if (qjj < nct) {
  127. nct = qjj;
  128. }
  129. nctp1 = nct + 1;
  130. if (nct > nrt) {
  131. i = nct;
  132. } else {
  133. i = nrt;
  134. }
  135. for (q = 0; q < i; q++) {
  136. boolean_T apply_transform;
  137. qp1 = q + 2;
  138. qq = (q + n * q) + 1;
  139. nmq = (n - q) - 1;
  140. apply_transform = false;
  141. if (q + 1 <= nct) {
  142. nrm = blas::xnrm2(nmq + 1, b_A, qq);
  143. if (nrm > 0.0) {
  144. apply_transform = true;
  145. if (b_A[qq - 1] < 0.0) {
  146. r = -nrm;
  147. b_s[q] = -nrm;
  148. } else {
  149. r = nrm;
  150. b_s[q] = nrm;
  151. }
  152. if (std::abs(r) >= 1.0020841800044864E-292) {
  153. nrm = 1.0 / r;
  154. ii = qq + nmq;
  155. for (k = qq; k <= ii; k++) {
  156. b_A[k - 1] = nrm * b_A[k - 1];
  157. }
  158. } else {
  159. ii = qq + nmq;
  160. for (k = qq; k <= ii; k++) {
  161. b_A[k - 1] = b_A[k - 1] / b_s[q];
  162. }
  163. }
  164. b_A[qq - 1] = b_A[qq - 1] + 1.0;
  165. b_s[q] = -b_s[q];
  166. } else {
  167. b_s[q] = 0.0;
  168. }
  169. }
  170. for (jj = qp1; jj <= p; jj++) {
  171. qjj = q + n * (jj - 1);
  172. if (apply_transform) {
  173. nrm = 0.0;
  174. if (nmq + 1 >= 1) {
  175. for (k = 0; k <= nmq; k++) {
  176. nrm += b_A[(qq + k) - 1] * b_A[qjj + k];
  177. }
  178. }
  179. nrm = -(nrm / b_A[q + b_A.size(0) * q]);
  180. if ((nmq + 1 >= 1) && (!(nrm == 0.0))) {
  181. for (k = 0; k <= nmq; k++) {
  182. ii = qjj + k;
  183. b_A[ii] = b_A[ii] + nrm * b_A[(qq + k) - 1];
  184. }
  185. }
  186. }
  187. e[jj - 1] = b_A[qjj];
  188. }
  189. if (q + 1 <= nct) {
  190. for (ii = q + 1; ii <= n; ii++) {
  191. U[(ii + U.size(0) * q) - 1] = b_A[(ii + b_A.size(0) * q) - 1];
  192. }
  193. }
  194. if (q + 1 <= nrt) {
  195. pmq = p - q;
  196. nrm = blas::xnrm2(pmq - 1, e, q + 2);
  197. if (nrm == 0.0) {
  198. e[q] = 0.0;
  199. } else {
  200. if (e[q + 1] < 0.0) {
  201. e[q] = -nrm;
  202. } else {
  203. e[q] = nrm;
  204. }
  205. nrm = e[q];
  206. if (std::abs(e[q]) >= 1.0020841800044864E-292) {
  207. nrm = 1.0 / e[q];
  208. ii = q + pmq;
  209. for (k = qp1; k <= ii; k++) {
  210. e[k - 1] = nrm * e[k - 1];
  211. }
  212. } else {
  213. ii = q + pmq;
  214. for (k = qp1; k <= ii; k++) {
  215. e[k - 1] = e[k - 1] / nrm;
  216. }
  217. }
  218. e[q + 1] = e[q + 1] + 1.0;
  219. e[q] = -e[q];
  220. if (q + 2 <= n) {
  221. for (ii = qp1; ii <= n; ii++) {
  222. work[ii - 1] = 0.0;
  223. }
  224. for (jj = qp1; jj <= p; jj++) {
  225. nrm = e[jj - 1];
  226. ns = (q + n * (jj - 1)) + 2;
  227. if ((nmq >= 1) && (!(nrm == 0.0))) {
  228. ii = nmq - 1;
  229. for (k = 0; k <= ii; k++) {
  230. qjj = (q + k) + 1;
  231. work[qjj] = work[qjj] + nrm * b_A[(ns + k) - 1];
  232. }
  233. }
  234. }
  235. for (jj = qp1; jj <= p; jj++) {
  236. nrm = -e[jj - 1] / e[q + 1];
  237. ns = (q + n * (jj - 1)) + 2;
  238. if ((nmq >= 1) && (!(nrm == 0.0))) {
  239. ii = nmq - 1;
  240. for (k = 0; k <= ii; k++) {
  241. qjj = (ns + k) - 1;
  242. b_A[qjj] = b_A[qjj] + nrm * work[(q + k) + 1];
  243. }
  244. }
  245. }
  246. }
  247. }
  248. for (ii = qp1; ii <= p; ii++) {
  249. Vf[(ii + Vf.size(0) * q) - 1] = e[ii - 1];
  250. }
  251. }
  252. }
  253. if (A.size(1) < A.size(0) + 1) {
  254. m = A.size(1) - 1;
  255. } else {
  256. m = A.size(0);
  257. }
  258. if (nct < A.size(1)) {
  259. b_s[nct] = b_A[nct + b_A.size(0) * nct];
  260. }
  261. if (A.size(0) < m + 1) {
  262. b_s[m] = 0.0;
  263. }
  264. if (nrt + 1 < m + 1) {
  265. e[nrt] = b_A[nrt + b_A.size(0) * m];
  266. }
  267. e[m] = 0.0;
  268. if (nct + 1 <= minnp) {
  269. for (jj = nctp1; jj <= minnp; jj++) {
  270. for (ii = 0; ii < n; ii++) {
  271. U[ii + U.size(0) * (jj - 1)] = 0.0;
  272. }
  273. U[(jj + U.size(0) * (jj - 1)) - 1] = 1.0;
  274. }
  275. }
  276. for (q = nct; q >= 1; q--) {
  277. qp1 = q + 1;
  278. ns = n - q;
  279. qq = (q + n * (q - 1)) - 1;
  280. if (b_s[q - 1] != 0.0) {
  281. for (jj = qp1; jj <= minnp; jj++) {
  282. qjj = q + n * (jj - 1);
  283. nrm = 0.0;
  284. if (ns + 1 >= 1) {
  285. for (k = 0; k <= ns; k++) {
  286. nrm += U[qq + k] * U[(qjj + k) - 1];
  287. }
  288. }
  289. nrm = -(nrm / U[qq]);
  290. blas::xaxpy(ns + 1, nrm, qq + 1, U, qjj);
  291. }
  292. for (ii = q; ii <= n; ii++) {
  293. U[(ii + U.size(0) * (q - 1)) - 1] =
  294. -U[(ii + U.size(0) * (q - 1)) - 1];
  295. }
  296. U[qq] = U[qq] + 1.0;
  297. for (ii = 0; ii <= q - 2; ii++) {
  298. U[ii + U.size(0) * (q - 1)] = 0.0;
  299. }
  300. } else {
  301. for (ii = 0; ii < n; ii++) {
  302. U[ii + U.size(0) * (q - 1)] = 0.0;
  303. }
  304. U[qq] = 1.0;
  305. }
  306. }
  307. for (q = p; q >= 1; q--) {
  308. if ((q <= nrt) && (e[q - 1] != 0.0)) {
  309. qp1 = q + 1;
  310. pmq = p - q;
  311. ns = q + p * (q - 1);
  312. for (jj = qp1; jj <= p; jj++) {
  313. qjj = q + p * (jj - 1);
  314. nrm = 0.0;
  315. if (pmq >= 1) {
  316. for (k = 0; k < pmq; k++) {
  317. nrm += Vf[ns + k] * Vf[qjj + k];
  318. }
  319. }
  320. nrm = -(nrm / Vf[ns]);
  321. if ((pmq >= 1) && (!(nrm == 0.0))) {
  322. i = pmq - 1;
  323. for (k = 0; k <= i; k++) {
  324. ii = qjj + k;
  325. Vf[ii] = Vf[ii] + nrm * Vf[ns + k];
  326. }
  327. }
  328. }
  329. }
  330. for (ii = 0; ii < p; ii++) {
  331. Vf[ii + Vf.size(0) * (q - 1)] = 0.0;
  332. }
  333. Vf[(q + Vf.size(0) * (q - 1)) - 1] = 1.0;
  334. }
  335. nctp1 = m;
  336. nmq = 0;
  337. snorm = 0.0;
  338. for (q = 0; q <= m; q++) {
  339. if (b_s[q] != 0.0) {
  340. nrm = std::abs(b_s[q]);
  341. r = b_s[q] / nrm;
  342. b_s[q] = nrm;
  343. if (q + 1 < m + 1) {
  344. e[q] = e[q] / r;
  345. }
  346. if (q + 1 <= n) {
  347. ns = n * q;
  348. i = ns + n;
  349. for (k = ns + 1; k <= i; k++) {
  350. U[k - 1] = r * U[k - 1];
  351. }
  352. }
  353. }
  354. if ((q + 1 < m + 1) && (e[q] != 0.0)) {
  355. nrm = std::abs(e[q]);
  356. r = nrm / e[q];
  357. e[q] = nrm;
  358. b_s[q + 1] = b_s[q + 1] * r;
  359. ns = p * (q + 1);
  360. i = ns + p;
  361. for (k = ns + 1; k <= i; k++) {
  362. Vf[k - 1] = r * Vf[k - 1];
  363. }
  364. }
  365. snorm = std::fmax(snorm, std::fmax(std::abs(b_s[q]), std::abs(e[q])));
  366. }
  367. while ((m + 1 > 0) && (nmq < 75)) {
  368. boolean_T exitg1;
  369. ii = m;
  370. exitg1 = false;
  371. while (!(exitg1 || (ii == 0))) {
  372. nrm = std::abs(e[ii - 1]);
  373. if ((nrm <= 2.2204460492503131E-16 *
  374. (std::abs(b_s[ii - 1]) + std::abs(b_s[ii]))) ||
  375. (nrm <= 1.0020841800044864E-292) ||
  376. ((nmq > 20) && (nrm <= 2.2204460492503131E-16 * snorm))) {
  377. e[ii - 1] = 0.0;
  378. exitg1 = true;
  379. } else {
  380. ii--;
  381. }
  382. }
  383. if (ii == m) {
  384. ns = 4;
  385. } else {
  386. qjj = m + 1;
  387. ns = m + 1;
  388. exitg1 = false;
  389. while ((!exitg1) && (ns >= ii)) {
  390. qjj = ns;
  391. if (ns == ii) {
  392. exitg1 = true;
  393. } else {
  394. nrm = 0.0;
  395. if (ns < m + 1) {
  396. nrm = std::abs(e[ns - 1]);
  397. }
  398. if (ns > ii + 1) {
  399. nrm += std::abs(e[ns - 2]);
  400. }
  401. r = std::abs(b_s[ns - 1]);
  402. if ((r <= 2.2204460492503131E-16 * nrm) ||
  403. (r <= 1.0020841800044864E-292)) {
  404. b_s[ns - 1] = 0.0;
  405. exitg1 = true;
  406. } else {
  407. ns--;
  408. }
  409. }
  410. }
  411. if (qjj == ii) {
  412. ns = 3;
  413. } else if (qjj == m + 1) {
  414. ns = 1;
  415. } else {
  416. ns = 2;
  417. ii = qjj;
  418. }
  419. }
  420. switch (ns) {
  421. case 1: {
  422. r = e[m - 1];
  423. e[m - 1] = 0.0;
  424. for (k = m; k >= ii + 1; k--) {
  425. blas::xrotg(&b_s[k - 1], &r, &sm, &scale);
  426. if (k > ii + 1) {
  427. double b;
  428. b = e[k - 2];
  429. r = -scale * b;
  430. e[k - 2] = b * sm;
  431. }
  432. if (p >= 1) {
  433. qjj = p * (k - 1);
  434. pmq = p * m;
  435. for (qp1 = 0; qp1 < p; qp1++) {
  436. double temp;
  437. qq = pmq + qp1;
  438. ns = qjj + qp1;
  439. temp = sm * Vf[ns] + scale * Vf[qq];
  440. Vf[qq] = sm * Vf[qq] - scale * Vf[ns];
  441. Vf[ns] = temp;
  442. }
  443. }
  444. }
  445. } break;
  446. case 2: {
  447. r = e[ii - 1];
  448. e[ii - 1] = 0.0;
  449. for (k = ii + 1; k <= m + 1; k++) {
  450. double b;
  451. blas::xrotg(&b_s[k - 1], &r, &sm, &scale);
  452. b = e[k - 1];
  453. r = -scale * b;
  454. e[k - 1] = b * sm;
  455. if (n >= 1) {
  456. qjj = n * (k - 1);
  457. pmq = n * (ii - 1);
  458. for (qp1 = 0; qp1 < n; qp1++) {
  459. double temp;
  460. qq = pmq + qp1;
  461. ns = qjj + qp1;
  462. temp = sm * U[ns] + scale * U[qq];
  463. U[qq] = sm * U[qq] - scale * U[ns];
  464. U[ns] = temp;
  465. }
  466. }
  467. }
  468. } break;
  469. case 3: {
  470. double b;
  471. double temp;
  472. nrm = b_s[m - 1];
  473. r = e[m - 1];
  474. scale = std::fmax(
  475. std::fmax(std::fmax(std::fmax(std::abs(b_s[m]), std::abs(nrm)),
  476. std::abs(r)),
  477. std::abs(b_s[ii])),
  478. std::abs(e[ii]));
  479. sm = b_s[m] / scale;
  480. nrm /= scale;
  481. r /= scale;
  482. temp = b_s[ii] / scale;
  483. b = ((nrm + sm) * (nrm - sm) + r * r) / 2.0;
  484. nrm = sm * r;
  485. nrm *= nrm;
  486. if ((b != 0.0) || (nrm != 0.0)) {
  487. r = std::sqrt(b * b + nrm);
  488. if (b < 0.0) {
  489. r = -r;
  490. }
  491. r = nrm / (b + r);
  492. } else {
  493. r = 0.0;
  494. }
  495. r += (temp + sm) * (temp - sm);
  496. nrm = temp * (e[ii] / scale);
  497. for (k = ii + 1; k <= m; k++) {
  498. blas::xrotg(&r, &nrm, &sm, &scale);
  499. if (k > ii + 1) {
  500. e[k - 2] = r;
  501. }
  502. b = e[k - 1];
  503. nrm = b_s[k - 1];
  504. e[k - 1] = sm * b - scale * nrm;
  505. r = scale * b_s[k];
  506. b_s[k] = b_s[k] * sm;
  507. if (p >= 1) {
  508. qjj = p * (k - 1);
  509. pmq = p * k;
  510. for (qp1 = 0; qp1 < p; qp1++) {
  511. qq = pmq + qp1;
  512. ns = qjj + qp1;
  513. temp = sm * Vf[ns] + scale * Vf[qq];
  514. Vf[qq] = sm * Vf[qq] - scale * Vf[ns];
  515. Vf[ns] = temp;
  516. }
  517. }
  518. b_s[k - 1] = sm * nrm + scale * b;
  519. blas::xrotg(&b_s[k - 1], &r, &sm, &scale);
  520. r = sm * e[k - 1] + scale * b_s[k];
  521. b_s[k] = -scale * e[k - 1] + sm * b_s[k];
  522. nrm = scale * e[k];
  523. e[k] = e[k] * sm;
  524. if ((k < n) && (n >= 1)) {
  525. qjj = n * (k - 1);
  526. pmq = n * k;
  527. for (qp1 = 0; qp1 < n; qp1++) {
  528. qq = pmq + qp1;
  529. ns = qjj + qp1;
  530. temp = sm * U[ns] + scale * U[qq];
  531. U[qq] = sm * U[qq] - scale * U[ns];
  532. U[ns] = temp;
  533. }
  534. }
  535. }
  536. e[m - 1] = r;
  537. nmq++;
  538. } break;
  539. default: {
  540. if (b_s[ii] < 0.0) {
  541. b_s[ii] = -b_s[ii];
  542. ns = p * ii;
  543. i = ns + p;
  544. for (k = ns + 1; k <= i; k++) {
  545. Vf[k - 1] = -Vf[k - 1];
  546. }
  547. }
  548. qp1 = ii + 1;
  549. while ((ii + 1 < nctp1 + 1) && (b_s[ii] < b_s[qp1])) {
  550. double temp;
  551. nrm = b_s[ii];
  552. b_s[ii] = b_s[qp1];
  553. b_s[qp1] = nrm;
  554. if (ii + 1 < p) {
  555. qjj = p * ii;
  556. pmq = p * (ii + 1);
  557. for (k = 0; k < p; k++) {
  558. qq = qjj + k;
  559. temp = Vf[qq];
  560. i = pmq + k;
  561. Vf[qq] = Vf[i];
  562. Vf[i] = temp;
  563. }
  564. }
  565. if (ii + 1 < n) {
  566. qjj = n * ii;
  567. pmq = n * (ii + 1);
  568. for (k = 0; k < n; k++) {
  569. qq = qjj + k;
  570. temp = U[qq];
  571. i = pmq + k;
  572. U[qq] = U[i];
  573. U[i] = temp;
  574. }
  575. }
  576. ii = qp1;
  577. qp1++;
  578. }
  579. nmq = 0;
  580. m--;
  581. } break;
  582. }
  583. }
  584. }
  585. s.set_size(minnp);
  586. V.set_size(A.size(1), minnp);
  587. for (k = 0; k < minnp; k++) {
  588. s[k] = b_s[k];
  589. for (ns = 0; ns < p; ns++) {
  590. V[ns + V.size(0) * k] = Vf[ns + Vf.size(0) * k];
  591. }
  592. }
  593. }
  594. } // namespace internal
  595. } // namespace coder
  596. //
  597. // File trailer for svd.cpp
  598. //
  599. // [EOF]
  600. //