| 1507 | { |
| 1508 | |
| 1509 | static void _SVDcompute( InputArray _aarr, OutputArray _w, |
| 1510 | OutputArray _u, OutputArray _vt, int flags ) |
| 1511 | { |
| 1512 | Mat src = _aarr.getMat(); |
| 1513 | int m = src.rows, n = src.cols; |
| 1514 | int type = src.type(); |
| 1515 | bool compute_uv = _u.needed() || _vt.needed(); |
| 1516 | bool full_uv = (flags & SVD::FULL_UV) != 0; |
| 1517 | |
| 1518 | CV_Assert( type == CV_32F || type == CV_64F ); |
| 1519 | |
| 1520 | if( flags & SVD::NO_UV ) |
| 1521 | { |
| 1522 | _u.release(); |
| 1523 | _vt.release(); |
| 1524 | compute_uv = full_uv = false; |
| 1525 | } |
| 1526 | |
| 1527 | bool at = false; |
| 1528 | if( m < n ) |
| 1529 | { |
| 1530 | std::swap(m, n); |
| 1531 | at = true; |
| 1532 | } |
| 1533 | |
| 1534 | int urows = full_uv ? m : n; |
| 1535 | size_t esz = src.elemSize(), astep = alignSize(m*esz, 16), vstep = alignSize(n*esz, 16); |
| 1536 | AutoBuffer<uchar> _buf(urows*astep + n*vstep + n*esz + 32); |
| 1537 | uchar* buf = alignPtr((uchar*)_buf, 16); |
| 1538 | Mat temp_a(n, m, type, buf, astep); |
| 1539 | Mat temp_w(n, 1, type, buf + urows*astep); |
| 1540 | Mat temp_u(urows, m, type, buf, astep), temp_v; |
| 1541 | |
| 1542 | if( compute_uv ) |
| 1543 | temp_v = Mat(n, n, type, alignPtr(buf + urows*astep + n*esz, 16), vstep); |
| 1544 | |
| 1545 | if( urows > n ) |
| 1546 | temp_u = Scalar::all(0); |
| 1547 | |
| 1548 | if( !at ) |
| 1549 | transpose(src, temp_a); |
| 1550 | else |
| 1551 | src.copyTo(temp_a); |
| 1552 | |
| 1553 | if( type == CV_32F ) |
| 1554 | { |
| 1555 | JacobiSVD(temp_a.ptr<float>(), temp_u.step, temp_w.ptr<float>(), |
| 1556 | temp_v.ptr<float>(), temp_v.step, m, n, compute_uv ? urows : 0); |
| 1557 | } |
| 1558 | else |
| 1559 | { |
| 1560 | JacobiSVD(temp_a.ptr<double>(), temp_u.step, temp_w.ptr<double>(), |
| 1561 | temp_v.ptr<double>(), temp_v.step, m, n, compute_uv ? urows : 0); |
| 1562 | } |
| 1563 | if(_w.needed()) temp_w.copyTo(_w); |
| 1564 | if( compute_uv ) |
| 1565 | { |
| 1566 | if( !at ) |