1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666 IMPLICIT NONE
1667
1668 INTEGER :: INFO, LDA, LDW, M, N, RANK, MAXRANK
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680 INTEGER :: TOL_OPT
1681 REAL :: TOLEPS
1682 INTEGER :: JPVT(*)
1683 REAL :: RWORK(*)
1684 COMPLEX :: A(LDA,*), TAU(*)
1685 COMPLEX :: WORK(LDW,*)
1686 LOGICAL :: ISLR
1687 REAL :: TOLEPS_EFF, TRUNC_ERR
1688 INTEGER, PARAMETER :: INB=1, inbmin=2
1689 INTEGER :: J, JB, MINMN, NB
1690 INTEGER :: OFFSET, ITEMP
1691 INTEGER :: LSTICC, PVT, K, RK
1692 REAL :: TEMP, TEMP2, TOL3Z
1693 COMPLEX :: AKK
1694 LOGICAL INADMISSIBLE
1695 REAL, PARAMETER :: RZERO=0.0e+0, rone=1.0e+0
1696 COMPLEX :: ZERO
1697 COMPLEX :: ONE
1698 parameter( one = ( 1.0e+0, 0.0e+0 ) )
1699 parameter( zero = ( 0.0e+0, 0.0e+0 ) )
1700 REAL :: slamch
1701 INTEGER :: ilaenv, isamax
1706 REAL, EXTERNAL :: scnrm2
1707 REAL, EXTERNAL :: snrm2
1708 info = 0
1709 islr = .false.
1710 IF( m.LT.0 ) THEN
1711 info = -1
1712 ELSE IF( n.LT.0 ) THEN
1713 info = -2
1714 ELSE IF( lda.LT.
max( 1, m ) )
THEN
1715 info = -4
1716 END IF
1717 IF( info.EQ.0 ) THEN
1718 IF( ldw.LT.n ) THEN
1719 info = -8
1720 END IF
1721 END IF
1722 IF( info.NE.0 ) THEN
1723 WRITE(*,999) -info
1724 RETURN
1725 END IF
1727 IF( minmn.EQ.0 ) THEN
1728 rank = 0
1729 RETURN
1730 END IF
1731 nb =
ilaenv( inb,
'CGEQRF',
' ', m, n, -1, -1 )
1732 SELECT CASE(abs(tol_opt))
1733 CASE(1)
1734 toleps_eff = toleps
1735 CASE(2)
1736
1737 CASE DEFAULT
1738 write(*,*) 'Internal error in CMUMPS_TRUNCATED_RRQR: TOL_OPT =',
1739 & tol_opt
1741 END SELECT
1742 toleps_eff = toleps
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754 DO j = 1, n
1755
1756 rwork( j ) =
scnrm2( m, a( 1, j ), 1 )
1757
1758 rwork( n + j ) = rwork( j )
1759 jpvt(j) = j
1760 END DO
1761 IF (tol_opt.LT.0) THEN
1762
1763
1764 trunc_err =
snrm2( n, rwork( 1 ), 1 )
1765 ENDIF
1766 offset = 0
1767 tol3z = sqrt(
slamch(
'Epsilon'))
1768 DO
1769 jb =
min(nb,minmn-offset)
1770 lsticc = 0
1771 k = 0
1772 DO
1773 IF(k.EQ.jb) EXIT
1774 k = k+1
1775 rk = offset+k
1776
1777 pvt = ( rk-1 ) +
isamax( n-rk+1, rwork( rk ), 1 )
1778 IF (rk.EQ.1) THEN
1779
1780 IF (abs(tol_opt).EQ.2) toleps_eff = rwork(pvt)*toleps
1781 ENDIF
1782 IF (tol_opt.GT.0) THEN
1783
1784 trunc_err = rwork(pvt)
1785
1786
1787 ENDIF
1788 IF(trunc_err.LT.toleps_eff) THEN
1789 rank = rk-1
1790 islr = .true.
1791 RETURN
1792 ENDIF
1793 inadmissible = (rk.GT.maxrank)
1794 IF (inadmissible) THEN
1795 rank = rk
1796 info = rk
1797 islr = .false.
1798 RETURN
1799 END IF
1800 IF( pvt.NE.rk ) THEN
1801 CALL cswap( m, a( 1, pvt ), 1, a( 1, rk ), 1 )
1802
1803
1804 CALL cswap( k-1, work( pvt-offset, 2 ), ldw,
1805 & work( k, 2 ), ldw )
1806 itemp = jpvt(pvt)
1807 jpvt(pvt) = jpvt(rk)
1808 jpvt(rk) = itemp
1809
1810
1811 rwork(pvt) = rwork(rk)
1812 rwork(n+pvt) = rwork(n+rk)
1813 END IF
1814
1815
1816 IF( k.GT.1 ) THEN
1817 DO j = 1, k-1
1818
1819 work( k, j+1 ) = conjg( work( k, j+1 ) )
1820 END DO
1821 CALL cgemv(
'No transpose', m-rk+1, k-1, -one,
1822
1823 & a(rk,offset+1), lda, work(k,2), ldw,
1824 & one, a(rk,rk), 1 )
1825 DO j = 1, k - 1
1826
1827 work( k, j + 1 ) = conjg( work( k, j + 1 ) )
1828 END DO
1829 END IF
1830
1831 IF( rk.LT.m ) THEN
1832 CALL clarfg( m-rk+1, a(rk,rk), a(rk+1,rk), 1, tau(rk) )
1833 ELSE
1834 CALL clarfg( 1, a(rk,rk), a(rk,rk), 1, tau(rk) )
1835 END IF
1836 akk = a(rk,rk)
1837 a(rk,rk) = one
1838
1839
1840 IF( rk.LT.n ) THEN
1841 CALL cgemv(
'Conjugate transpose', m-rk+1, n-rk, tau(rk),
1842 & a(rk,rk+1), lda, a(rk,rk), 1, zero,
1843
1844 & work( k+1, k+1 ), 1 )
1845 END IF
1846
1847 DO j = 1, k
1848
1849 work( j, k+1 ) = zero
1850 END DO
1851
1852
1853
1854 IF( k.GT.1 ) THEN
1855 CALL cgemv(
'Conjugate transpose', m-rk+1, k-1, -tau(rk),
1856 & a(rk,offset+1), lda, a(rk,rk), 1, zero,
1857 & work(1,1), 1 )
1858
1859 CALL cgemv( 'no transpose
', N-OFFSET, K-1, ONE,
1860 & WORK(1,2), LDW, WORK(1,1), 1, ONE, WORK(1,K+1), 1 )
1861
1862 END IF
1863
1864
1865.LT. IF( RKN ) THEN
1866 CALL cgemm( 'no transpose', 'conjugate transpose',
1867 & 1, N-RK,
1868
1869 & K, -ONE, A( RK, OFFSET+1 ), LDA, WORK( K+1,2 ), LDW,
1870 & ONE, A( RK, RK+1 ), LDA )
1871 END IF
1872
1873
1874.LT. IF( RKMINMN ) THEN
1875 DO J = RK + 1, N
1876
1877.NE. IF( RWORK( J )RZERO ) THEN
1878
1879
1880
1881
1882
1883 TEMP = ABS( A( RK, J ) ) / RWORK( J )
1884 TEMP = MAX( RZERO, ( RONE+TEMP )*( RONE-TEMP ) )
1885
1886 TEMP2 = TEMP*( RWORK( J ) / RWORK( N+J ) )**2
1887.LE. IF( TEMP2 TOL3Z ) THEN
1888
1889 RWORK( N+J ) = REAL( LSTICC )
1890 LSTICC = J
1891 ELSE
1892
1893 RWORK( J ) = RWORK( J )*SQRT( TEMP )
1894 END IF
1895 END IF
1896 END DO
1897 END IF
1898 A( RK, RK ) = AKK
1899.NE. IF (LSTICC0) EXIT
1900.LT. IF (TOL_OPT0) THEN
1901
1902
1903 TRUNC_ERR = snrm2( N-RK, RWORK( RK+1 ), 1 )
1904 ENDIF
1905 END DO
1906
1907
1908
1909.LT. IF( RKMIN(N,M) ) THEN
1910 CALL cgemm( 'no transpose', 'conjugate transpose', M-RK,
1911 & N-RK, K, -ONE, A(RK+1,OFFSET+1), LDA,
1912
1913 & WORK(K+1,2), LDW, ONE, A(RK+1,RK+1), LDA )
1914 END IF
1915
1916.GT. DO WHILE( LSTICC0 )
1917
1918 ITEMP = NINT( RWORK( N + LSTICC ) )
1919
1920 RWORK( LSTICC ) = scnrm2( M-RK, A( RK+1, LSTICC ), 1 )
1921
1922
1923
1924
1925
1926
1927 RWORK( N + LSTICC ) = RWORK( LSTICC )
1928 LSTICC = ITEMP
1929 END DO
1930.GE. IF(RKMINMN) EXIT
1931 OFFSET = RK
1932.LT. IF (TOL_OPT0) THEN
1933
1934
1935 TRUNC_ERR = snrm2( N-RK, RWORK( RK+1 ), 1 )
1936 ENDIF
1937 END DO
1938 RANK = RK
1939.NOT..GT. ISLR = (RKMAXRANK)
1940 RETURN
1942 & I2,' had an illegal value')
subroutine cmumps_truncated_rrqr(m, n, a, lda, jpvt, tau, work, ldw, rwork, toleps, tol_opt, rank, maxrank, info, islr)
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
subroutine xerbla(srname, info)
XERBLA
integer function isamax(n, sx, incx)
ISAMAX
subroutine cgeqrf(m, n, a, lda, tau, work, lwork, info)
CGEQRF
subroutine clarfg(n, alpha, x, incx, tau)
CLARFG generates an elementary reflector (Householder matrix).
subroutine cunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMQR
subroutine cswap(n, cx, incx, cy, incy)
CSWAP
subroutine cgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
CGEMV
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
real(wp) function snrm2(n, x, incx)
SNRM2
real(wp) function scnrm2(n, x, incx)
SCNRM2
real function slamch(cmach)
SLAMCH