123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604 |
- //
- // File: svd.cpp
- //
- // MATLAB Coder version : 5.2
- // C/C++ source code generated on : 24-Mar-2023 11:40:08
- //
- // Include Files
- #include "fun9_svd.h"
- #include "rt_nonfinite.h"
- #include "fun9_xaxpy.h"
- #include "fun9_xnrm2.h"
- #include "fun9_xrotg.h"
- #include "coder_array.h"
- #include <cmath>
- // Function Definitions
- //
- // Arguments : const ::coder::array<double, 2U> &A
- // ::coder::array<double, 2U> &U
- // ::coder::array<double, 1U> &s
- // ::coder::array<double, 2U> &V
- // Return Type : void
- //
- namespace coder {
- namespace internal {
- void svd(const ::coder::array<double, 2U> &A, ::coder::array<double, 2U> &U,
- ::coder::array<double, 1U> &s, ::coder::array<double, 2U> &V)
- {
- array<double, 2U> Vf;
- array<double, 2U> b_A;
- array<double, 1U> b_s;
- array<double, 1U> e;
- array<double, 1U> work;
- double nrm;
- double r;
- double scale;
- double sm;
- int i;
- int k;
- int minnp;
- int n;
- int ns;
- int p;
- int qjj;
- b_A.set_size(A.size(0), A.size(1));
- ns = A.size(0) * A.size(1);
- for (i = 0; i < ns; i++) {
- b_A[i] = A[i];
- }
- n = A.size(0);
- p = A.size(1);
- qjj = A.size(0) + 1;
- ns = A.size(1);
- if (qjj < ns) {
- ns = qjj;
- }
- qjj = A.size(0);
- minnp = A.size(1);
- if (qjj < minnp) {
- minnp = qjj;
- }
- b_s.set_size(ns);
- for (i = 0; i < ns; i++) {
- b_s[i] = 0.0;
- }
- e.set_size(A.size(1));
- ns = A.size(1);
- for (i = 0; i < ns; i++) {
- e[i] = 0.0;
- }
- work.set_size(A.size(0));
- ns = A.size(0);
- for (i = 0; i < ns; i++) {
- work[i] = 0.0;
- }
- U.set_size(A.size(0), minnp);
- ns = A.size(0) * minnp;
- for (i = 0; i < ns; i++) {
- U[i] = 0.0;
- }
- Vf.set_size(A.size(1), A.size(1));
- ns = A.size(1) * A.size(1);
- for (i = 0; i < ns; i++) {
- Vf[i] = 0.0;
- }
- if ((A.size(0) == 0) || (A.size(1) == 0)) {
- int ii;
- qjj = A.size(0);
- if (qjj >= minnp) {
- qjj = minnp;
- }
- for (ii = 0; ii < qjj; ii++) {
- U[ii + U.size(0) * ii] = 1.0;
- }
- i = A.size(1);
- for (ii = 0; ii < i; ii++) {
- Vf[ii + Vf.size(0) * ii] = 1.0;
- }
- } else {
- double snorm;
- int ii;
- int jj;
- int m;
- int nct;
- int nctp1;
- int nmq;
- int nrt;
- int pmq;
- int q;
- int qp1;
- int qq;
- if (A.size(1) > 2) {
- qjj = A.size(1) - 2;
- } else {
- qjj = 0;
- }
- nrt = A.size(0);
- if (qjj < nrt) {
- nrt = qjj;
- }
- if (A.size(0) > 1) {
- qjj = A.size(0) - 1;
- } else {
- qjj = 0;
- }
- nct = A.size(1);
- if (qjj < nct) {
- nct = qjj;
- }
- nctp1 = nct + 1;
- if (nct > nrt) {
- i = nct;
- } else {
- i = nrt;
- }
- for (q = 0; q < i; q++) {
- boolean_T apply_transform;
- qp1 = q + 2;
- qq = (q + n * q) + 1;
- nmq = (n - q) - 1;
- apply_transform = false;
- if (q + 1 <= nct) {
- nrm = blas::xnrm2(nmq + 1, b_A, qq);
- if (nrm > 0.0) {
- apply_transform = true;
- if (b_A[qq - 1] < 0.0) {
- r = -nrm;
- b_s[q] = -nrm;
- } else {
- r = nrm;
- b_s[q] = nrm;
- }
- if (std::abs(r) >= 1.0020841800044864E-292) {
- nrm = 1.0 / r;
- ii = qq + nmq;
- for (k = qq; k <= ii; k++) {
- b_A[k - 1] = nrm * b_A[k - 1];
- }
- } else {
- ii = qq + nmq;
- for (k = qq; k <= ii; k++) {
- b_A[k - 1] = b_A[k - 1] / b_s[q];
- }
- }
- b_A[qq - 1] = b_A[qq - 1] + 1.0;
- b_s[q] = -b_s[q];
- } else {
- b_s[q] = 0.0;
- }
- }
- for (jj = qp1; jj <= p; jj++) {
- qjj = q + n * (jj - 1);
- if (apply_transform) {
- nrm = 0.0;
- if (nmq + 1 >= 1) {
- for (k = 0; k <= nmq; k++) {
- nrm += b_A[(qq + k) - 1] * b_A[qjj + k];
- }
- }
- nrm = -(nrm / b_A[q + b_A.size(0) * q]);
- if ((nmq + 1 >= 1) && (!(nrm == 0.0))) {
- for (k = 0; k <= nmq; k++) {
- ii = qjj + k;
- b_A[ii] = b_A[ii] + nrm * b_A[(qq + k) - 1];
- }
- }
- }
- e[jj - 1] = b_A[qjj];
- }
- if (q + 1 <= nct) {
- for (ii = q + 1; ii <= n; ii++) {
- U[(ii + U.size(0) * q) - 1] = b_A[(ii + b_A.size(0) * q) - 1];
- }
- }
- if (q + 1 <= nrt) {
- pmq = p - q;
- nrm = blas::xnrm2(pmq - 1, e, q + 2);
- if (nrm == 0.0) {
- e[q] = 0.0;
- } else {
- if (e[q + 1] < 0.0) {
- e[q] = -nrm;
- } else {
- e[q] = nrm;
- }
- nrm = e[q];
- if (std::abs(e[q]) >= 1.0020841800044864E-292) {
- nrm = 1.0 / e[q];
- ii = q + pmq;
- for (k = qp1; k <= ii; k++) {
- e[k - 1] = nrm * e[k - 1];
- }
- } else {
- ii = q + pmq;
- for (k = qp1; k <= ii; k++) {
- e[k - 1] = e[k - 1] / nrm;
- }
- }
- e[q + 1] = e[q + 1] + 1.0;
- e[q] = -e[q];
- if (q + 2 <= n) {
- for (ii = qp1; ii <= n; ii++) {
- work[ii - 1] = 0.0;
- }
- for (jj = qp1; jj <= p; jj++) {
- nrm = e[jj - 1];
- ns = (q + n * (jj - 1)) + 2;
- if ((nmq >= 1) && (!(nrm == 0.0))) {
- ii = nmq - 1;
- for (k = 0; k <= ii; k++) {
- qjj = (q + k) + 1;
- work[qjj] = work[qjj] + nrm * b_A[(ns + k) - 1];
- }
- }
- }
- for (jj = qp1; jj <= p; jj++) {
- nrm = -e[jj - 1] / e[q + 1];
- ns = (q + n * (jj - 1)) + 2;
- if ((nmq >= 1) && (!(nrm == 0.0))) {
- ii = nmq - 1;
- for (k = 0; k <= ii; k++) {
- qjj = (ns + k) - 1;
- b_A[qjj] = b_A[qjj] + nrm * work[(q + k) + 1];
- }
- }
- }
- }
- }
- for (ii = qp1; ii <= p; ii++) {
- Vf[(ii + Vf.size(0) * q) - 1] = e[ii - 1];
- }
- }
- }
- if (A.size(1) < A.size(0) + 1) {
- m = A.size(1) - 1;
- } else {
- m = A.size(0);
- }
- if (nct < A.size(1)) {
- b_s[nct] = b_A[nct + b_A.size(0) * nct];
- }
- if (A.size(0) < m + 1) {
- b_s[m] = 0.0;
- }
- if (nrt + 1 < m + 1) {
- e[nrt] = b_A[nrt + b_A.size(0) * m];
- }
- e[m] = 0.0;
- if (nct + 1 <= minnp) {
- for (jj = nctp1; jj <= minnp; jj++) {
- for (ii = 0; ii < n; ii++) {
- U[ii + U.size(0) * (jj - 1)] = 0.0;
- }
- U[(jj + U.size(0) * (jj - 1)) - 1] = 1.0;
- }
- }
- for (q = nct; q >= 1; q--) {
- qp1 = q + 1;
- ns = n - q;
- qq = (q + n * (q - 1)) - 1;
- if (b_s[q - 1] != 0.0) {
- for (jj = qp1; jj <= minnp; jj++) {
- qjj = q + n * (jj - 1);
- nrm = 0.0;
- if (ns + 1 >= 1) {
- for (k = 0; k <= ns; k++) {
- nrm += U[qq + k] * U[(qjj + k) - 1];
- }
- }
- nrm = -(nrm / U[qq]);
- blas::xaxpy(ns + 1, nrm, qq + 1, U, qjj);
- }
- for (ii = q; ii <= n; ii++) {
- U[(ii + U.size(0) * (q - 1)) - 1] =
- -U[(ii + U.size(0) * (q - 1)) - 1];
- }
- U[qq] = U[qq] + 1.0;
- for (ii = 0; ii <= q - 2; ii++) {
- U[ii + U.size(0) * (q - 1)] = 0.0;
- }
- } else {
- for (ii = 0; ii < n; ii++) {
- U[ii + U.size(0) * (q - 1)] = 0.0;
- }
- U[qq] = 1.0;
- }
- }
- for (q = p; q >= 1; q--) {
- if ((q <= nrt) && (e[q - 1] != 0.0)) {
- qp1 = q + 1;
- pmq = p - q;
- ns = q + p * (q - 1);
- for (jj = qp1; jj <= p; jj++) {
- qjj = q + p * (jj - 1);
- nrm = 0.0;
- if (pmq >= 1) {
- for (k = 0; k < pmq; k++) {
- nrm += Vf[ns + k] * Vf[qjj + k];
- }
- }
- nrm = -(nrm / Vf[ns]);
- if ((pmq >= 1) && (!(nrm == 0.0))) {
- i = pmq - 1;
- for (k = 0; k <= i; k++) {
- ii = qjj + k;
- Vf[ii] = Vf[ii] + nrm * Vf[ns + k];
- }
- }
- }
- }
- for (ii = 0; ii < p; ii++) {
- Vf[ii + Vf.size(0) * (q - 1)] = 0.0;
- }
- Vf[(q + Vf.size(0) * (q - 1)) - 1] = 1.0;
- }
- nctp1 = m;
- nmq = 0;
- snorm = 0.0;
- for (q = 0; q <= m; q++) {
- if (b_s[q] != 0.0) {
- nrm = std::abs(b_s[q]);
- r = b_s[q] / nrm;
- b_s[q] = nrm;
- if (q + 1 < m + 1) {
- e[q] = e[q] / r;
- }
- if (q + 1 <= n) {
- ns = n * q;
- i = ns + n;
- for (k = ns + 1; k <= i; k++) {
- U[k - 1] = r * U[k - 1];
- }
- }
- }
- if ((q + 1 < m + 1) && (e[q] != 0.0)) {
- nrm = std::abs(e[q]);
- r = nrm / e[q];
- e[q] = nrm;
- b_s[q + 1] = b_s[q + 1] * r;
- ns = p * (q + 1);
- i = ns + p;
- for (k = ns + 1; k <= i; k++) {
- Vf[k - 1] = r * Vf[k - 1];
- }
- }
- snorm = std::fmax(snorm, std::fmax(std::abs(b_s[q]), std::abs(e[q])));
- }
- while ((m + 1 > 0) && (nmq < 75)) {
- boolean_T exitg1;
- ii = m;
- exitg1 = false;
- while (!(exitg1 || (ii == 0))) {
- nrm = std::abs(e[ii - 1]);
- if ((nrm <= 2.2204460492503131E-16 *
- (std::abs(b_s[ii - 1]) + std::abs(b_s[ii]))) ||
- (nrm <= 1.0020841800044864E-292) ||
- ((nmq > 20) && (nrm <= 2.2204460492503131E-16 * snorm))) {
- e[ii - 1] = 0.0;
- exitg1 = true;
- } else {
- ii--;
- }
- }
- if (ii == m) {
- ns = 4;
- } else {
- qjj = m + 1;
- ns = m + 1;
- exitg1 = false;
- while ((!exitg1) && (ns >= ii)) {
- qjj = ns;
- if (ns == ii) {
- exitg1 = true;
- } else {
- nrm = 0.0;
- if (ns < m + 1) {
- nrm = std::abs(e[ns - 1]);
- }
- if (ns > ii + 1) {
- nrm += std::abs(e[ns - 2]);
- }
- r = std::abs(b_s[ns - 1]);
- if ((r <= 2.2204460492503131E-16 * nrm) ||
- (r <= 1.0020841800044864E-292)) {
- b_s[ns - 1] = 0.0;
- exitg1 = true;
- } else {
- ns--;
- }
- }
- }
- if (qjj == ii) {
- ns = 3;
- } else if (qjj == m + 1) {
- ns = 1;
- } else {
- ns = 2;
- ii = qjj;
- }
- }
- switch (ns) {
- case 1: {
- r = e[m - 1];
- e[m - 1] = 0.0;
- for (k = m; k >= ii + 1; k--) {
- blas::xrotg(&b_s[k - 1], &r, &sm, &scale);
- if (k > ii + 1) {
- double b;
- b = e[k - 2];
- r = -scale * b;
- e[k - 2] = b * sm;
- }
- if (p >= 1) {
- qjj = p * (k - 1);
- pmq = p * m;
- for (qp1 = 0; qp1 < p; qp1++) {
- double temp;
- qq = pmq + qp1;
- ns = qjj + qp1;
- temp = sm * Vf[ns] + scale * Vf[qq];
- Vf[qq] = sm * Vf[qq] - scale * Vf[ns];
- Vf[ns] = temp;
- }
- }
- }
- } break;
- case 2: {
- r = e[ii - 1];
- e[ii - 1] = 0.0;
- for (k = ii + 1; k <= m + 1; k++) {
- double b;
- blas::xrotg(&b_s[k - 1], &r, &sm, &scale);
- b = e[k - 1];
- r = -scale * b;
- e[k - 1] = b * sm;
- if (n >= 1) {
- qjj = n * (k - 1);
- pmq = n * (ii - 1);
- for (qp1 = 0; qp1 < n; qp1++) {
- double temp;
- qq = pmq + qp1;
- ns = qjj + qp1;
- temp = sm * U[ns] + scale * U[qq];
- U[qq] = sm * U[qq] - scale * U[ns];
- U[ns] = temp;
- }
- }
- }
- } break;
- case 3: {
- double b;
- double temp;
- nrm = b_s[m - 1];
- r = e[m - 1];
- scale = std::fmax(
- std::fmax(std::fmax(std::fmax(std::abs(b_s[m]), std::abs(nrm)),
- std::abs(r)),
- std::abs(b_s[ii])),
- std::abs(e[ii]));
- sm = b_s[m] / scale;
- nrm /= scale;
- r /= scale;
- temp = b_s[ii] / scale;
- b = ((nrm + sm) * (nrm - sm) + r * r) / 2.0;
- nrm = sm * r;
- nrm *= nrm;
- if ((b != 0.0) || (nrm != 0.0)) {
- r = std::sqrt(b * b + nrm);
- if (b < 0.0) {
- r = -r;
- }
- r = nrm / (b + r);
- } else {
- r = 0.0;
- }
- r += (temp + sm) * (temp - sm);
- nrm = temp * (e[ii] / scale);
- for (k = ii + 1; k <= m; k++) {
- blas::xrotg(&r, &nrm, &sm, &scale);
- if (k > ii + 1) {
- e[k - 2] = r;
- }
- b = e[k - 1];
- nrm = b_s[k - 1];
- e[k - 1] = sm * b - scale * nrm;
- r = scale * b_s[k];
- b_s[k] = b_s[k] * sm;
- if (p >= 1) {
- qjj = p * (k - 1);
- pmq = p * k;
- for (qp1 = 0; qp1 < p; qp1++) {
- qq = pmq + qp1;
- ns = qjj + qp1;
- temp = sm * Vf[ns] + scale * Vf[qq];
- Vf[qq] = sm * Vf[qq] - scale * Vf[ns];
- Vf[ns] = temp;
- }
- }
- b_s[k - 1] = sm * nrm + scale * b;
- blas::xrotg(&b_s[k - 1], &r, &sm, &scale);
- r = sm * e[k - 1] + scale * b_s[k];
- b_s[k] = -scale * e[k - 1] + sm * b_s[k];
- nrm = scale * e[k];
- e[k] = e[k] * sm;
- if ((k < n) && (n >= 1)) {
- qjj = n * (k - 1);
- pmq = n * k;
- for (qp1 = 0; qp1 < n; qp1++) {
- qq = pmq + qp1;
- ns = qjj + qp1;
- temp = sm * U[ns] + scale * U[qq];
- U[qq] = sm * U[qq] - scale * U[ns];
- U[ns] = temp;
- }
- }
- }
- e[m - 1] = r;
- nmq++;
- } break;
- default: {
- if (b_s[ii] < 0.0) {
- b_s[ii] = -b_s[ii];
- ns = p * ii;
- i = ns + p;
- for (k = ns + 1; k <= i; k++) {
- Vf[k - 1] = -Vf[k - 1];
- }
- }
- qp1 = ii + 1;
- while ((ii + 1 < nctp1 + 1) && (b_s[ii] < b_s[qp1])) {
- double temp;
- nrm = b_s[ii];
- b_s[ii] = b_s[qp1];
- b_s[qp1] = nrm;
- if (ii + 1 < p) {
- qjj = p * ii;
- pmq = p * (ii + 1);
- for (k = 0; k < p; k++) {
- qq = qjj + k;
- temp = Vf[qq];
- i = pmq + k;
- Vf[qq] = Vf[i];
- Vf[i] = temp;
- }
- }
- if (ii + 1 < n) {
- qjj = n * ii;
- pmq = n * (ii + 1);
- for (k = 0; k < n; k++) {
- qq = qjj + k;
- temp = U[qq];
- i = pmq + k;
- U[qq] = U[i];
- U[i] = temp;
- }
- }
- ii = qp1;
- qp1++;
- }
- nmq = 0;
- m--;
- } break;
- }
- }
- }
- s.set_size(minnp);
- V.set_size(A.size(1), minnp);
- for (k = 0; k < minnp; k++) {
- s[k] = b_s[k];
- for (ns = 0; ns < p; ns++) {
- V[ns + V.size(0) * k] = Vf[ns + Vf.size(0) * k];
- }
- }
- }
- } // namespace internal
- } // namespace coder
- //
- // File trailer for svd.cpp
- //
- // [EOF]
- //
|