Mercurial > octave-nkf
comparison liboctave/CMatrix.cc @ 5785:6b9cec830d72
[project @ 2006-05-03 19:32:46 by dbateman]
author | dbateman |
---|---|
date | Wed, 03 May 2006 19:32:48 +0000 |
parents | ace8d8d26933 |
children | cdef72fcd206 |
comparison
equal
deleted
inserted
replaced
5784:70f7659d0fb9 | 5785:6b9cec830d72 |
---|---|
109 F77_RET_T | 109 F77_RET_T |
110 F77_FUNC (zgelss, ZGELSS) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, | 110 F77_FUNC (zgelss, ZGELSS) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, |
111 Complex*, const octave_idx_type&, Complex*, | 111 Complex*, const octave_idx_type&, Complex*, |
112 const octave_idx_type&, double*, double&, octave_idx_type&, | 112 const octave_idx_type&, double*, double&, octave_idx_type&, |
113 Complex*, const octave_idx_type&, double*, octave_idx_type&); | 113 Complex*, const octave_idx_type&, double*, octave_idx_type&); |
114 | |
115 F77_RET_T | |
116 F77_FUNC (zpotrf, ZPOTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, | |
117 Complex*, const octave_idx_type&, | |
118 octave_idx_type& F77_CHAR_ARG_LEN_DECL); | |
119 | |
120 F77_RET_T | |
121 F77_FUNC (zpocon, ZPOCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, | |
122 Complex*, const octave_idx_type&, const double&, | |
123 double&, Complex*, double*, | |
124 octave_idx_type& F77_CHAR_ARG_LEN_DECL); | |
125 | |
126 F77_RET_T | |
127 F77_FUNC (zpotrs, ZPOTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, | |
128 const octave_idx_type&, const Complex*, | |
129 const octave_idx_type&, Complex*, | |
130 const octave_idx_type&, octave_idx_type& | |
131 F77_CHAR_ARG_LEN_DECL); | |
132 | |
133 F77_RET_T | |
134 F77_FUNC (ztrcon, ZTRCON) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, | |
135 F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, | |
136 const Complex*, const octave_idx_type&, double&, | |
137 Complex*, double*, octave_idx_type& | |
138 F77_CHAR_ARG_LEN_DECL | |
139 F77_CHAR_ARG_LEN_DECL | |
140 F77_CHAR_ARG_LEN_DECL); | |
141 | |
142 F77_RET_T | |
143 F77_FUNC (ztrtrs, ZTRTRS) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, | |
144 F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, | |
145 const octave_idx_type&, const Complex*, | |
146 const octave_idx_type&, Complex*, | |
147 const octave_idx_type&, octave_idx_type& | |
148 F77_CHAR_ARG_LEN_DECL | |
149 F77_CHAR_ARG_LEN_DECL | |
150 F77_CHAR_ARG_LEN_DECL); | |
114 | 151 |
115 // Note that the original complex fft routines were not written for | 152 // Note that the original complex fft routines were not written for |
116 // double complex arguments. They have been modified by adding an | 153 // double complex arguments. They have been modified by adding an |
117 // implicit double precision (a-h,o-z) statement at the beginning of | 154 // implicit double precision (a-h,o-z) statement at the beginning of |
118 // each subroutine. | 155 // each subroutine. |
1489 | 1526 |
1490 return retval; | 1527 return retval; |
1491 } | 1528 } |
1492 | 1529 |
1493 ComplexMatrix | 1530 ComplexMatrix |
1494 ComplexMatrix::solve (const Matrix& b) const | 1531 ComplexMatrix::utsolve (MatrixType &mattype, const ComplexMatrix& b, |
1495 { | 1532 octave_idx_type& info, double& rcond, |
1496 octave_idx_type info; | 1533 solve_singularity_handler sing_handler, |
1497 double rcond; | 1534 bool calc_cond) const |
1498 return solve (b, info, rcond, 0); | 1535 { |
1499 } | 1536 ComplexMatrix retval; |
1500 | 1537 |
1501 ComplexMatrix | 1538 octave_idx_type nr = rows (); |
1502 ComplexMatrix::solve (const Matrix& b, octave_idx_type& info) const | 1539 octave_idx_type nc = cols (); |
1503 { | 1540 |
1504 double rcond; | 1541 if (nr == 0 || nc == 0 || nr != b.rows ()) |
1505 return solve (b, info, rcond, 0); | 1542 (*current_liboctave_error_handler) |
1506 } | 1543 ("matrix dimension mismatch solution of linear equations"); |
1507 | 1544 else |
1508 ComplexMatrix | 1545 { |
1509 ComplexMatrix::solve (const Matrix& b, octave_idx_type& info, double& rcond) const | 1546 volatile int typ = mattype.type (); |
1510 { | 1547 |
1511 return solve (b, info, rcond, 0); | 1548 if (typ == MatrixType::Permuted_Upper || |
1512 } | 1549 typ == MatrixType::Upper) |
1513 | 1550 { |
1514 ComplexMatrix | 1551 octave_idx_type b_nc = b.cols (); |
1515 ComplexMatrix::solve (const Matrix& b, octave_idx_type& info, double& rcond, | 1552 rcond = 1.; |
1516 solve_singularity_handler sing_handler) const | 1553 info = 0; |
1517 { | 1554 |
1518 ComplexMatrix tmp (b); | 1555 if (typ == MatrixType::Permuted_Upper) |
1519 return solve (tmp, info, rcond, sing_handler); | 1556 { |
1520 } | 1557 (*current_liboctave_error_handler) |
1521 | 1558 ("Permuted triangular matrix not implemented"); |
1522 ComplexMatrix | 1559 } |
1523 ComplexMatrix::solve (const ComplexMatrix& b) const | 1560 else |
1524 { | 1561 { |
1525 octave_idx_type info; | 1562 const Complex *tmp_data = fortran_vec (); |
1526 double rcond; | 1563 |
1527 return solve (b, info, rcond, 0); | 1564 if (calc_cond) |
1528 } | 1565 { |
1529 | 1566 char norm = '1'; |
1530 ComplexMatrix | 1567 char uplo = 'U'; |
1531 ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info) const | 1568 char dia = 'N'; |
1532 { | 1569 |
1533 double rcond; | 1570 Array<Complex> z (2 * nc); |
1534 return solve (b, info, rcond, 0); | 1571 Complex *pz = z.fortran_vec (); |
1535 } | 1572 Array<double> rz (nc); |
1536 | 1573 double *prz = rz.fortran_vec (); |
1537 ComplexMatrix | 1574 |
1538 ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcond) const | 1575 F77_XFCN (ztrcon, ZTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), |
1539 { | 1576 F77_CONST_CHAR_ARG2 (&uplo, 1), |
1540 return solve (b, info, rcond, 0); | 1577 F77_CONST_CHAR_ARG2 (&dia, 1), |
1541 } | 1578 nr, tmp_data, nr, rcond, |
1542 | 1579 pz, prz, info |
1543 ComplexMatrix | 1580 F77_CHAR_ARG_LEN (1) |
1544 ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcond, | 1581 F77_CHAR_ARG_LEN (1) |
1545 solve_singularity_handler sing_handler) const | 1582 F77_CHAR_ARG_LEN (1))); |
1583 | |
1584 if (f77_exception_encountered) | |
1585 (*current_liboctave_error_handler) | |
1586 ("unrecoverable error in ztrcon"); | |
1587 | |
1588 if (info != 0) | |
1589 info = -2; | |
1590 | |
1591 volatile double rcond_plus_one = rcond + 1.0; | |
1592 | |
1593 if (rcond_plus_one == 1.0 || xisnan (rcond)) | |
1594 { | |
1595 info = -2; | |
1596 | |
1597 if (sing_handler) | |
1598 sing_handler (rcond); | |
1599 else | |
1600 (*current_liboctave_error_handler) | |
1601 ("matrix singular to machine precision, rcond = %g", | |
1602 rcond); | |
1603 } | |
1604 } | |
1605 | |
1606 if (info == 0) | |
1607 { | |
1608 retval = b; | |
1609 Complex *result = retval.fortran_vec (); | |
1610 | |
1611 char uplo = 'U'; | |
1612 char trans = 'N'; | |
1613 char dia = 'N'; | |
1614 | |
1615 F77_XFCN (ztrtrs, ZTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), | |
1616 F77_CONST_CHAR_ARG2 (&trans, 1), | |
1617 F77_CONST_CHAR_ARG2 (&dia, 1), | |
1618 nr, b_nc, tmp_data, nr, | |
1619 result, nr, info | |
1620 F77_CHAR_ARG_LEN (1) | |
1621 F77_CHAR_ARG_LEN (1) | |
1622 F77_CHAR_ARG_LEN (1))); | |
1623 | |
1624 if (f77_exception_encountered) | |
1625 (*current_liboctave_error_handler) | |
1626 ("unrecoverable error in dtrtrs"); | |
1627 } | |
1628 } | |
1629 } | |
1630 else | |
1631 (*current_liboctave_error_handler) ("incorrect matrix type"); | |
1632 } | |
1633 | |
1634 return retval; | |
1635 } | |
1636 | |
1637 ComplexMatrix | |
1638 ComplexMatrix::ltsolve (MatrixType &mattype, const ComplexMatrix& b, | |
1639 octave_idx_type& info, double& rcond, | |
1640 solve_singularity_handler sing_handler, | |
1641 bool calc_cond) const | |
1642 { | |
1643 ComplexMatrix retval; | |
1644 | |
1645 octave_idx_type nr = rows (); | |
1646 octave_idx_type nc = cols (); | |
1647 | |
1648 if (nr == 0 || nc == 0 || nr != b.rows ()) | |
1649 (*current_liboctave_error_handler) | |
1650 ("matrix dimension mismatch solution of linear equations"); | |
1651 else | |
1652 { | |
1653 volatile int typ = mattype.type (); | |
1654 | |
1655 if (typ == MatrixType::Permuted_Lower || | |
1656 typ == MatrixType::Lower) | |
1657 { | |
1658 octave_idx_type b_nc = b.cols (); | |
1659 rcond = 1.; | |
1660 info = 0; | |
1661 | |
1662 if (typ == MatrixType::Permuted_Lower) | |
1663 { | |
1664 (*current_liboctave_error_handler) | |
1665 ("Permuted triangular matrix not implemented"); | |
1666 } | |
1667 else | |
1668 { | |
1669 const Complex *tmp_data = fortran_vec (); | |
1670 | |
1671 if (calc_cond) | |
1672 { | |
1673 char norm = '1'; | |
1674 char uplo = 'L'; | |
1675 char dia = 'N'; | |
1676 | |
1677 Array<Complex> z (2 * nc); | |
1678 Complex *pz = z.fortran_vec (); | |
1679 Array<double> rz (nc); | |
1680 double *prz = rz.fortran_vec (); | |
1681 | |
1682 F77_XFCN (ztrcon, ZTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), | |
1683 F77_CONST_CHAR_ARG2 (&uplo, 1), | |
1684 F77_CONST_CHAR_ARG2 (&dia, 1), | |
1685 nr, tmp_data, nr, rcond, | |
1686 pz, prz, info | |
1687 F77_CHAR_ARG_LEN (1) | |
1688 F77_CHAR_ARG_LEN (1) | |
1689 F77_CHAR_ARG_LEN (1))); | |
1690 | |
1691 if (f77_exception_encountered) | |
1692 (*current_liboctave_error_handler) | |
1693 ("unrecoverable error in ztrcon"); | |
1694 | |
1695 if (info != 0) | |
1696 info = -2; | |
1697 | |
1698 volatile double rcond_plus_one = rcond + 1.0; | |
1699 | |
1700 if (rcond_plus_one == 1.0 || xisnan (rcond)) | |
1701 { | |
1702 info = -2; | |
1703 | |
1704 if (sing_handler) | |
1705 sing_handler (rcond); | |
1706 else | |
1707 (*current_liboctave_error_handler) | |
1708 ("matrix singular to machine precision, rcond = %g", | |
1709 rcond); | |
1710 } | |
1711 } | |
1712 | |
1713 if (info == 0) | |
1714 { | |
1715 retval = b; | |
1716 Complex *result = retval.fortran_vec (); | |
1717 | |
1718 char uplo = 'L'; | |
1719 char trans = 'N'; | |
1720 char dia = 'N'; | |
1721 | |
1722 F77_XFCN (ztrtrs, ZTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), | |
1723 F77_CONST_CHAR_ARG2 (&trans, 1), | |
1724 F77_CONST_CHAR_ARG2 (&dia, 1), | |
1725 nr, b_nc, tmp_data, nr, | |
1726 result, nr, info | |
1727 F77_CHAR_ARG_LEN (1) | |
1728 F77_CHAR_ARG_LEN (1) | |
1729 F77_CHAR_ARG_LEN (1))); | |
1730 | |
1731 if (f77_exception_encountered) | |
1732 (*current_liboctave_error_handler) | |
1733 ("unrecoverable error in dtrtrs"); | |
1734 } | |
1735 } | |
1736 } | |
1737 else | |
1738 (*current_liboctave_error_handler) ("incorrect matrix type"); | |
1739 } | |
1740 | |
1741 return retval; | |
1742 } | |
1743 | |
1744 ComplexMatrix | |
1745 ComplexMatrix::fsolve (MatrixType &mattype, const ComplexMatrix& b, | |
1746 octave_idx_type& info, double& rcond, | |
1747 solve_singularity_handler sing_handler, | |
1748 bool calc_cond) const | |
1546 { | 1749 { |
1547 ComplexMatrix retval; | 1750 ComplexMatrix retval; |
1548 | 1751 |
1549 octave_idx_type nr = rows (); | 1752 octave_idx_type nr = rows (); |
1550 octave_idx_type nc = cols (); | 1753 octave_idx_type nc = cols (); |
1552 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) | 1755 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
1553 (*current_liboctave_error_handler) | 1756 (*current_liboctave_error_handler) |
1554 ("matrix dimension mismatch in solution of linear equations"); | 1757 ("matrix dimension mismatch in solution of linear equations"); |
1555 else | 1758 else |
1556 { | 1759 { |
1557 info = 0; | 1760 volatile int typ = mattype.type (); |
1558 | 1761 |
1559 Array<octave_idx_type> ipvt (nr); | 1762 // Calculate the norm of the matrix, for later use. |
1560 octave_idx_type *pipvt = ipvt.fortran_vec (); | 1763 double anorm = -1.; |
1561 | 1764 |
1562 ComplexMatrix atmp = *this; | 1765 if (typ == MatrixType::Hermitian) |
1563 Complex *tmp_data = atmp.fortran_vec (); | |
1564 | |
1565 Array<Complex> z (2 * nc); | |
1566 Complex *pz = z.fortran_vec (); | |
1567 Array<double> rz (2 * nc); | |
1568 double *prz = rz.fortran_vec (); | |
1569 | |
1570 // Calculate the norm of the matrix, for later use. | |
1571 double anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); | |
1572 | |
1573 F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info)); | |
1574 | |
1575 if (f77_exception_encountered) | |
1576 (*current_liboctave_error_handler) ("unrecoverable error in zgetrf"); | |
1577 else | |
1578 { | 1766 { |
1579 // Throw-away extra info LAPACK gives so as to not change output. | 1767 info = 0; |
1580 rcond = 0.0; | 1768 char job = 'L'; |
1581 if (info != 0) | 1769 ComplexMatrix atmp = *this; |
1582 { | 1770 Complex *tmp_data = atmp.fortran_vec (); |
1583 info = -2; | 1771 anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); |
1584 | 1772 |
1585 if (sing_handler) | 1773 F77_XFCN (zpotrf, ZPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, |
1586 sing_handler (rcond); | 1774 tmp_data, nr, info |
1587 else | 1775 F77_CHAR_ARG_LEN (1))); |
1588 (*current_liboctave_error_handler) | 1776 |
1589 ("matrix singular to machine precision"); | 1777 if (f77_exception_encountered) |
1590 | 1778 (*current_liboctave_error_handler) |
1591 } | 1779 ("unrecoverable error in zpotrf"); |
1592 else | 1780 else |
1593 { | 1781 { |
1594 // Now calculate the condition number for non-singular matrix. | 1782 // Throw-away extra info LAPACK gives so as to not change output. |
1595 char job = '1'; | 1783 rcond = 0.0; |
1596 F77_XFCN (zgecon, ZGECON, (F77_CONST_CHAR_ARG2 (&job, 1), | |
1597 nc, tmp_data, nr, anorm, | |
1598 rcond, pz, prz, info | |
1599 F77_CHAR_ARG_LEN (1))); | |
1600 | |
1601 if (f77_exception_encountered) | |
1602 (*current_liboctave_error_handler) | |
1603 ("unrecoverable error in zgecon"); | |
1604 | |
1605 if (info != 0) | 1784 if (info != 0) |
1606 info = -2; | |
1607 | |
1608 volatile double rcond_plus_one = rcond + 1.0; | |
1609 | |
1610 if (rcond_plus_one == 1.0 || xisnan (rcond)) | |
1611 { | 1785 { |
1786 info = -2; | |
1787 | |
1788 mattype.mark_as_unsymmetric (); | |
1789 typ = MatrixType::Full; | |
1790 } | |
1791 else | |
1792 { | |
1793 if (calc_cond) | |
1794 { | |
1795 Array<Complex> z (2 * nc); | |
1796 Complex *pz = z.fortran_vec (); | |
1797 Array<double> rz (nc); | |
1798 double *prz = rz.fortran_vec (); | |
1799 | |
1800 F77_XFCN (zpocon, ZPOCON, (F77_CONST_CHAR_ARG2 (&job, 1), | |
1801 nr, tmp_data, nr, anorm, | |
1802 rcond, pz, prz, info | |
1803 F77_CHAR_ARG_LEN (1))); | |
1804 | |
1805 if (f77_exception_encountered) | |
1806 (*current_liboctave_error_handler) | |
1807 ("unrecoverable error in zpocon"); | |
1808 | |
1809 if (info != 0) | |
1810 info = -2; | |
1811 | |
1812 volatile double rcond_plus_one = rcond + 1.0; | |
1813 | |
1814 if (rcond_plus_one == 1.0 || xisnan (rcond)) | |
1815 { | |
1816 info = -2; | |
1817 | |
1818 if (sing_handler) | |
1819 sing_handler (rcond); | |
1820 else | |
1821 (*current_liboctave_error_handler) | |
1822 ("matrix singular to machine precision, rcond = %g", | |
1823 rcond); | |
1824 } | |
1825 } | |
1826 | |
1827 if (info == 0) | |
1828 { | |
1829 retval = b; | |
1830 Complex *result = retval.fortran_vec (); | |
1831 | |
1832 octave_idx_type b_nc = b.cols (); | |
1833 | |
1834 F77_XFCN (zpotrs, ZPOTRS, (F77_CONST_CHAR_ARG2 (&job, 1), | |
1835 nr, b_nc, tmp_data, nr, | |
1836 result, b.rows(), info | |
1837 F77_CHAR_ARG_LEN (1))); | |
1838 | |
1839 if (f77_exception_encountered) | |
1840 (*current_liboctave_error_handler) | |
1841 ("unrecoverable error in zpotrs"); | |
1842 } | |
1843 else | |
1844 { | |
1845 mattype.mark_as_unsymmetric (); | |
1846 typ = MatrixType::Full; | |
1847 } | |
1848 } | |
1849 } | |
1850 } | |
1851 | |
1852 if (typ == MatrixType::Full) | |
1853 { | |
1854 info = 0; | |
1855 | |
1856 Array<octave_idx_type> ipvt (nr); | |
1857 octave_idx_type *pipvt = ipvt.fortran_vec (); | |
1858 | |
1859 ComplexMatrix atmp = *this; | |
1860 Complex *tmp_data = atmp.fortran_vec (); | |
1861 | |
1862 Array<Complex> z (2 * nc); | |
1863 Complex *pz = z.fortran_vec (); | |
1864 Array<double> rz (2 * nc); | |
1865 double *prz = rz.fortran_vec (); | |
1866 | |
1867 // Calculate the norm of the matrix, for later use. | |
1868 if (anorm < 0.) | |
1869 anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); | |
1870 | |
1871 F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info)); | |
1872 | |
1873 if (f77_exception_encountered) | |
1874 (*current_liboctave_error_handler) | |
1875 ("unrecoverable error in zgetrf"); | |
1876 else | |
1877 { | |
1878 // Throw-away extra info LAPACK gives so as to not change output. | |
1879 rcond = 0.0; | |
1880 if (info != 0) | |
1881 { | |
1612 info = -2; | 1882 info = -2; |
1613 | 1883 |
1614 if (sing_handler) | 1884 if (sing_handler) |
1615 sing_handler (rcond); | 1885 sing_handler (rcond); |
1616 else | 1886 else |
1617 (*current_liboctave_error_handler) | 1887 (*current_liboctave_error_handler) |
1618 ("matrix singular to machine precision, rcond = %g", | 1888 ("matrix singular to machine precision"); |
1619 rcond); | 1889 |
1620 } | 1890 mattype.mark_as_rectangular (); |
1621 else | 1891 } |
1892 else | |
1622 { | 1893 { |
1623 retval = b; | 1894 if (calc_cond) |
1624 Complex *result = retval.fortran_vec (); | 1895 { |
1625 | 1896 // Now calculate the condition number for |
1626 octave_idx_type b_nc = b.cols (); | 1897 // non-singular matrix. |
1627 | 1898 char job = '1'; |
1628 job = 'N'; | 1899 F77_XFCN (zgecon, ZGECON, (F77_CONST_CHAR_ARG2 (&job, 1), |
1629 F77_XFCN (zgetrs, ZGETRS, (F77_CONST_CHAR_ARG2 (&job, 1), | 1900 nc, tmp_data, nr, anorm, |
1630 nr, b_nc, tmp_data, nr, | 1901 rcond, pz, prz, info |
1631 pipvt, result, b.rows(), info | 1902 F77_CHAR_ARG_LEN (1))); |
1632 F77_CHAR_ARG_LEN (1))); | 1903 |
1633 | 1904 if (f77_exception_encountered) |
1634 if (f77_exception_encountered) | 1905 (*current_liboctave_error_handler) |
1635 (*current_liboctave_error_handler) | 1906 ("unrecoverable error in zgecon"); |
1636 ("unrecoverable error in zgetrs"); | 1907 |
1908 if (info != 0) | |
1909 info = -2; | |
1910 | |
1911 volatile double rcond_plus_one = rcond + 1.0; | |
1912 | |
1913 if (rcond_plus_one == 1.0 || xisnan (rcond)) | |
1914 { | |
1915 info = -2; | |
1916 | |
1917 if (sing_handler) | |
1918 sing_handler (rcond); | |
1919 else | |
1920 (*current_liboctave_error_handler) | |
1921 ("matrix singular to machine precision, rcond = %g", | |
1922 rcond); | |
1923 } | |
1924 } | |
1925 | |
1926 if (info == 0) | |
1927 { | |
1928 retval = b; | |
1929 Complex *result = retval.fortran_vec (); | |
1930 | |
1931 octave_idx_type b_nc = b.cols (); | |
1932 | |
1933 char job = 'N'; | |
1934 F77_XFCN (zgetrs, ZGETRS, (F77_CONST_CHAR_ARG2 (&job, 1), | |
1935 nr, b_nc, tmp_data, nr, | |
1936 pipvt, result, b.rows(), info | |
1937 F77_CHAR_ARG_LEN (1))); | |
1938 | |
1939 if (f77_exception_encountered) | |
1940 (*current_liboctave_error_handler) | |
1941 ("unrecoverable error in zgetrs"); | |
1942 } | |
1943 else | |
1944 mattype.mark_as_rectangular (); | |
1637 } | 1945 } |
1638 } | 1946 } |
1639 } | 1947 } |
1640 } | 1948 } |
1641 | 1949 |
1642 return retval; | 1950 return retval; |
1643 } | 1951 } |
1644 | 1952 |
1953 ComplexMatrix | |
1954 ComplexMatrix::solve (MatrixType &typ, const Matrix& b) const | |
1955 { | |
1956 octave_idx_type info; | |
1957 double rcond; | |
1958 return solve (typ, b, info, rcond, 0); | |
1959 } | |
1960 | |
1961 ComplexMatrix | |
1962 ComplexMatrix::solve (MatrixType &typ, const Matrix& b, | |
1963 octave_idx_type& info) const | |
1964 { | |
1965 double rcond; | |
1966 return solve (typ, b, info, rcond, 0); | |
1967 } | |
1968 | |
1969 ComplexMatrix | |
1970 ComplexMatrix::solve (MatrixType &typ, const Matrix& b, octave_idx_type& info, | |
1971 double& rcond) const | |
1972 { | |
1973 return solve (typ, b, info, rcond, 0); | |
1974 } | |
1975 | |
1976 ComplexMatrix | |
1977 ComplexMatrix::solve (MatrixType &typ, const Matrix& b, octave_idx_type& info, | |
1978 double& rcond, solve_singularity_handler sing_handler, | |
1979 bool singular_fallback) const | |
1980 { | |
1981 ComplexMatrix tmp (b); | |
1982 return solve (typ, tmp, info, rcond, sing_handler, singular_fallback); | |
1983 } | |
1984 | |
1985 ComplexMatrix | |
1986 ComplexMatrix::solve (MatrixType &typ, const ComplexMatrix& b) const | |
1987 { | |
1988 octave_idx_type info; | |
1989 double rcond; | |
1990 return solve (typ, b, info, rcond, 0); | |
1991 } | |
1992 | |
1993 ComplexMatrix | |
1994 ComplexMatrix::solve (MatrixType &typ, const ComplexMatrix& b, | |
1995 octave_idx_type& info) const | |
1996 { | |
1997 double rcond; | |
1998 return solve (typ, b, info, rcond, 0); | |
1999 } | |
2000 | |
2001 ComplexMatrix | |
2002 ComplexMatrix::solve (MatrixType &typ, const ComplexMatrix& b, | |
2003 octave_idx_type& info, double& rcond) const | |
2004 { | |
2005 return solve (typ, b, info, rcond, 0); | |
2006 } | |
2007 | |
2008 ComplexMatrix | |
2009 ComplexMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, | |
2010 octave_idx_type& info, double& rcond, | |
2011 solve_singularity_handler sing_handler, | |
2012 bool singular_fallback) const | |
2013 { | |
2014 ComplexMatrix retval; | |
2015 int typ = mattype.type (); | |
2016 | |
2017 if (typ == MatrixType::Unknown) | |
2018 typ = mattype.type (*this); | |
2019 | |
2020 // Only calculate the condition number for LU/Cholesky | |
2021 if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper) | |
2022 retval = utsolve (mattype, b, info, rcond, sing_handler, false); | |
2023 else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) | |
2024 retval = ltsolve (mattype, b, info, rcond, sing_handler, false); | |
2025 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) | |
2026 retval = fsolve (mattype, b, info, rcond, sing_handler, true); | |
2027 else if (typ != MatrixType::Rectangular) | |
2028 { | |
2029 (*current_liboctave_error_handler) ("unknown matrix type"); | |
2030 return ComplexMatrix (); | |
2031 } | |
2032 | |
2033 // Rectangular or one of the above solvers flags a singular matrix | |
2034 if (singular_fallback && mattype.type () == MatrixType::Rectangular) | |
2035 { | |
2036 octave_idx_type rank; | |
2037 retval = lssolve (b, info, rank); | |
2038 } | |
2039 | |
2040 return retval; | |
2041 } | |
2042 | |
2043 ComplexColumnVector | |
2044 ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b) const | |
2045 { | |
2046 octave_idx_type info; | |
2047 double rcond; | |
2048 return solve (typ, ComplexColumnVector (b), info, rcond, 0); | |
2049 } | |
2050 | |
2051 ComplexColumnVector | |
2052 ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b, | |
2053 octave_idx_type& info) const | |
2054 { | |
2055 double rcond; | |
2056 return solve (typ, ComplexColumnVector (b), info, rcond, 0); | |
2057 } | |
2058 | |
2059 ComplexColumnVector | |
2060 ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b, | |
2061 octave_idx_type& info, double& rcond) const | |
2062 { | |
2063 return solve (typ, ComplexColumnVector (b), info, rcond, 0); | |
2064 } | |
2065 | |
2066 ComplexColumnVector | |
2067 ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b, | |
2068 octave_idx_type& info, double& rcond, | |
2069 solve_singularity_handler sing_handler) const | |
2070 { | |
2071 return solve (typ, ComplexColumnVector (b), info, rcond, sing_handler); | |
2072 } | |
2073 | |
2074 ComplexColumnVector | |
2075 ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b) const | |
2076 { | |
2077 octave_idx_type info; | |
2078 double rcond; | |
2079 return solve (typ, b, info, rcond, 0); | |
2080 } | |
2081 | |
2082 ComplexColumnVector | |
2083 ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b, | |
2084 octave_idx_type& info) const | |
2085 { | |
2086 double rcond; | |
2087 return solve (typ, b, info, rcond, 0); | |
2088 } | |
2089 | |
2090 ComplexColumnVector | |
2091 ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b, | |
2092 octave_idx_type& info, double& rcond) const | |
2093 { | |
2094 return solve (typ, b, info, rcond, 0); | |
2095 } | |
2096 | |
2097 ComplexColumnVector | |
2098 ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b, | |
2099 octave_idx_type& info, double& rcond, | |
2100 solve_singularity_handler sing_handler) const | |
2101 { | |
2102 | |
2103 ComplexMatrix tmp (b); | |
2104 return solve (typ, tmp, info, rcond, sing_handler).column(static_cast<octave_idx_type> (0)); | |
2105 } | |
2106 | |
2107 ComplexMatrix | |
2108 ComplexMatrix::solve (const Matrix& b) const | |
2109 { | |
2110 octave_idx_type info; | |
2111 double rcond; | |
2112 return solve (b, info, rcond, 0); | |
2113 } | |
2114 | |
2115 ComplexMatrix | |
2116 ComplexMatrix::solve (const Matrix& b, octave_idx_type& info) const | |
2117 { | |
2118 double rcond; | |
2119 return solve (b, info, rcond, 0); | |
2120 } | |
2121 | |
2122 ComplexMatrix | |
2123 ComplexMatrix::solve (const Matrix& b, octave_idx_type& info, double& rcond) const | |
2124 { | |
2125 return solve (b, info, rcond, 0); | |
2126 } | |
2127 | |
2128 ComplexMatrix | |
2129 ComplexMatrix::solve (const Matrix& b, octave_idx_type& info, double& rcond, | |
2130 solve_singularity_handler sing_handler) const | |
2131 { | |
2132 ComplexMatrix tmp (b); | |
2133 return solve (tmp, info, rcond, sing_handler); | |
2134 } | |
2135 | |
2136 ComplexMatrix | |
2137 ComplexMatrix::solve (const ComplexMatrix& b) const | |
2138 { | |
2139 octave_idx_type info; | |
2140 double rcond; | |
2141 return solve (b, info, rcond, 0); | |
2142 } | |
2143 | |
2144 ComplexMatrix | |
2145 ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info) const | |
2146 { | |
2147 double rcond; | |
2148 return solve (b, info, rcond, 0); | |
2149 } | |
2150 | |
2151 ComplexMatrix | |
2152 ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcond) const | |
2153 { | |
2154 return solve (b, info, rcond, 0); | |
2155 } | |
2156 | |
2157 ComplexMatrix | |
2158 ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcond, | |
2159 solve_singularity_handler sing_handler) const | |
2160 { | |
2161 MatrixType mattype (*this); | |
2162 return solve (b, info, rcond, sing_handler); | |
2163 } | |
2164 | |
1645 ComplexColumnVector | 2165 ComplexColumnVector |
1646 ComplexMatrix::solve (const ColumnVector& b) const | 2166 ComplexMatrix::solve (const ColumnVector& b) const |
1647 { | 2167 { |
1648 octave_idx_type info; | 2168 octave_idx_type info; |
1649 double rcond; | 2169 double rcond; |
1656 double rcond; | 2176 double rcond; |
1657 return solve (ComplexColumnVector (b), info, rcond, 0); | 2177 return solve (ComplexColumnVector (b), info, rcond, 0); |
1658 } | 2178 } |
1659 | 2179 |
1660 ComplexColumnVector | 2180 ComplexColumnVector |
1661 ComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info, double& rcond) const | 2181 ComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info, |
2182 double& rcond) const | |
1662 { | 2183 { |
1663 return solve (ComplexColumnVector (b), info, rcond, 0); | 2184 return solve (ComplexColumnVector (b), info, rcond, 0); |
1664 } | 2185 } |
1665 | 2186 |
1666 ComplexColumnVector | 2187 ComplexColumnVector |
1667 ComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info, double& rcond, | 2188 ComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info, |
2189 double& rcond, | |
1668 solve_singularity_handler sing_handler) const | 2190 solve_singularity_handler sing_handler) const |
1669 { | 2191 { |
1670 return solve (ComplexColumnVector (b), info, rcond, sing_handler); | 2192 return solve (ComplexColumnVector (b), info, rcond, sing_handler); |
1671 } | 2193 } |
1672 | 2194 |
1695 ComplexColumnVector | 2217 ComplexColumnVector |
1696 ComplexMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, | 2218 ComplexMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, |
1697 double& rcond, | 2219 double& rcond, |
1698 solve_singularity_handler sing_handler) const | 2220 solve_singularity_handler sing_handler) const |
1699 { | 2221 { |
1700 ComplexColumnVector retval; | 2222 MatrixType mattype (*this); |
1701 | 2223 return solve (mattype, b, info, rcond, sing_handler); |
1702 octave_idx_type nr = rows (); | |
1703 octave_idx_type nc = cols (); | |
1704 | |
1705 if (nr == 0 || nc == 0 || nr != nc || nr != b.length ()) | |
1706 (*current_liboctave_error_handler) | |
1707 ("matrix dimension mismatch in solution of linear equations"); | |
1708 else | |
1709 { | |
1710 info = 0; | |
1711 | |
1712 Array<octave_idx_type> ipvt (nr); | |
1713 octave_idx_type *pipvt = ipvt.fortran_vec (); | |
1714 | |
1715 ComplexMatrix atmp = *this; | |
1716 Complex *tmp_data = atmp.fortran_vec (); | |
1717 | |
1718 Array<Complex> z (2 * nc); | |
1719 Complex *pz = z.fortran_vec (); | |
1720 Array<double> rz (2 * nc); | |
1721 double *prz = rz.fortran_vec (); | |
1722 | |
1723 // Calculate the norm of the matrix, for later use. | |
1724 double anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); | |
1725 | |
1726 F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info)); | |
1727 | |
1728 if (f77_exception_encountered) | |
1729 (*current_liboctave_error_handler) ("unrecoverable error in zgetrf"); | |
1730 else | |
1731 { | |
1732 // Throw-away extra info LAPACK gives so as to not change output. | |
1733 rcond = 0.0; | |
1734 if (info != 0) | |
1735 { | |
1736 info = -2; | |
1737 | |
1738 if (sing_handler) | |
1739 sing_handler (rcond); | |
1740 else | |
1741 (*current_liboctave_error_handler) | |
1742 ("matrix singular to machine precision, rcond = %g", | |
1743 rcond); | |
1744 } | |
1745 else | |
1746 { | |
1747 // Now calculate the condition number for non-singular matrix. | |
1748 char job = '1'; | |
1749 F77_XFCN (zgecon, ZGECON, (F77_CONST_CHAR_ARG2 (&job, 1), | |
1750 nc, tmp_data, nr, anorm, | |
1751 rcond, pz, prz, info | |
1752 F77_CHAR_ARG_LEN (1))); | |
1753 | |
1754 if (f77_exception_encountered) | |
1755 (*current_liboctave_error_handler) | |
1756 ("unrecoverable error in zgecon"); | |
1757 | |
1758 if (info != 0) | |
1759 info = -2; | |
1760 | |
1761 volatile double rcond_plus_one = rcond + 1.0; | |
1762 | |
1763 if (rcond_plus_one == 1.0 || xisnan (rcond)) | |
1764 { | |
1765 info = -2; | |
1766 | |
1767 if (sing_handler) | |
1768 sing_handler (rcond); | |
1769 else | |
1770 (*current_liboctave_error_handler) | |
1771 ("matrix singular to machine precision, rcond = %g", | |
1772 rcond); | |
1773 } | |
1774 else | |
1775 { | |
1776 retval = b; | |
1777 Complex *result = retval.fortran_vec (); | |
1778 | |
1779 job = 'N'; | |
1780 F77_XFCN (zgetrs, ZGETRS, (F77_CONST_CHAR_ARG2 (&job, 1), | |
1781 nr, 1, tmp_data, nr, pipvt, | |
1782 result, b.length(), info | |
1783 F77_CHAR_ARG_LEN (1))); | |
1784 | |
1785 if (f77_exception_encountered) | |
1786 (*current_liboctave_error_handler) | |
1787 ("unrecoverable error in zgetrs"); | |
1788 | |
1789 } | |
1790 } | |
1791 } | |
1792 } | |
1793 return retval; | |
1794 } | 2224 } |
1795 | 2225 |
1796 ComplexMatrix | 2226 ComplexMatrix |
1797 ComplexMatrix::lssolve (const Matrix& b) const | 2227 ComplexMatrix::lssolve (const Matrix& b) const |
1798 { | 2228 { |