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, , LDW, M, N, RANK,
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680 INTEGER :: TOL_OPT
1681 DOUBLE PRECISION :: TOLEPS
1682 INTEGER :: JPVT(*)
1683 DOUBLE PRECISION :: RWORK(*)
1684 DOUBLE PRECISION :: (LDA,*), TAU(*)
1685 DOUBLE PRECISION :: WORK(LDW,*)
1686 LOGICAL :: ISLR
1687 DOUBLE PRECISION :: TOLEPS_EFF, TRUNC_ERR
1688 INTEGER, PARAMETER :: =1, inbmin=2
1689 INTEGER :: J, JB, MINMN, NB
1690 INTEGER :: OFFSET, ITEMP
1691 INTEGER :: LSTICC, , K, RK
1692 DOUBLE PRECISION :: TEMP, TEMP2, TOL3Z
1693 DOUBLE PRECISION ::
1694 LOGICAL INADMISSIBLE
1695 DOUBLE PRECISION, PARAMETER :: =0.0d+0, rone=1.0d+0
1696 DOUBLE PRECISION :: ZERO
1697 DOUBLE PRECISION ::
1698 parameter( one = 1.0d+0 )
1699 parameter( zero = 0.0d+0 )
1700 DOUBLE PRECISION :: dlamch
1701 INTEGER :: ilaenv, idamax
1706 DOUBLE PRECISION, EXTERNAL :: dnrm2
1707 info = 0
1708 islr = .false.
1709 IF( m.LT.0 ) THEN
1710 info = -1
1711 ELSE IF( n.LT.0 ) THEN
1712 info = -2
1713 ELSE IF( lda.LT.
max( 1, m ) )
THEN
1714 info = -4
1715 END IF
1716 IF( info.EQ.0 ) THEN
1717 IF( ldw.LT.n ) THEN
1718 info = -8
1719 END IF
1720 END IF
1721 IF( info.NE.0 ) THEN
1722 WRITE(*,999) -info
1723 RETURN
1724 END IF
1726 IF( minmn.EQ.0 ) THEN
1727 rank = 0
1728 RETURN
1729 END IF
1730 nb =
ilaenv( inb,
'CGEQRF',
' ', m, n, -1, -1 )
1731 SELECT CASE(abs(tol_opt))
1732 CASE(1)
1733 toleps_eff = toleps
1734 CASE(2)
1735
1736 CASE DEFAULT
1737 write(*,*) 'Internal error in DMUMPS_TRUNCATED_RRQR: TOL_OPT =',
1738 & tol_opt
1740 END SELECT
1741 toleps_eff = toleps
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753 DO j = 1, n
1754
1755 rwork( j ) =
dnrm2( m, a( 1, j ), 1 )
1756
1757 rwork( n + j ) = rwork( j )
1758 jpvt(j) = j
1759 END DO
1760 IF (tol_opt.LT.0) THEN
1761
1762
1763 trunc_err =
dnrm2( n, rwork( 1 ), 1 )
1764 ENDIF
1765 offset = 0
1766 tol3z = sqrt(
dlamch(
'Epsilon'))
1767 DO
1768 jb =
min(nb,minmn-offset)
1769 lsticc = 0
1770 k = 0
1771 DO
1772 IF(k.EQ.jb) EXIT
1773 k = k+1
1774 rk = offset+k
1775
1776 pvt = ( rk-1 ) +
idamax( n-rk+1, rwork( rk ), 1 )
1777 IF (rk.EQ.1) THEN
1778
1779 IF (abs(tol_opt).EQ.2) toleps_eff = rwork(pvt)*toleps
1780 ENDIF
1781 IF (tol_opt.GT.0) THEN
1782
1783 trunc_err = rwork(pvt)
1784
1785
1786 ENDIF
1787 IF(trunc_err.LT.toleps_eff) THEN
1788 rank = rk-1
1789 islr = .true.
1790 RETURN
1791 ENDIF
1792 inadmissible = (rk.GT.maxrank)
1793 IF (inadmissible) THEN
1794 rank = rk
1795 info = rk
1796 islr = .false.
1797 RETURN
1798 END IF
1799 IF( pvt.NE.rk ) THEN
1800 CALL dswap( m, a( 1, pvt ), 1, a( 1, rk ), 1 )
1801
1802
1803 CALL dswap( k-1, work( pvt-offset, 2 ), ldw,
1804 & work( k, 2 ), ldw )
1805 itemp = jpvt(pvt)
1806 jpvt(pvt) = jpvt(rk)
1807 jpvt(rk) = itemp
1808
1809
1810 rwork(pvt) = rwork(rk)
1811 rwork(n+pvt) = rwork(n+rk)
1812 END IF
1813
1814
1815 IF( k.GT.1 ) THEN
1816 CALL dgemv(
'No transpose', m-rk+1, k-1, -one,
1817
1818 & a(rk,offset+1), lda, work(k,2), ldw,
1819 & one, a(rk,rk), 1 )
1820 END IF
1821
1822 IF( rk.LT.m ) THEN
1823 CALL dlarfg( m-rk+1, a(rk,rk), a(rk+1,rk), 1, tau(rk) )
1824 ELSE
1825 CALL dlarfg( 1, a(rk,rk), a(rk,rk), 1, tau(rk) )
1826 END IF
1827 akk = a(rk,rk)
1828 a(rk,rk) = one
1829
1830
1831 IF( rk.LT.n ) THEN
1832 CALL dgemv(
'Transpose', m-rk+1, n-rk, tau(rk),
1833 & a(rk,rk+1), lda, a(rk,rk), 1, zero,
1834
1835 & work( k+1, k+1 ), 1 )
1836 END IF
1837
1838 DO j = 1, k
1839
1840 work( j, k+1 ) = zero
1841 END DO
1842
1843
1844
1845 IF( k.GT.1 ) THEN
1846 CALL dgemv(
'Transpose', m-rk+1, k-1, -tau(rk),
1847 & a(rk,offset+1), lda, a(rk,rk), 1, zero,
1848 & work(1,1), 1 )
1849
1850 CALL dgemv(
'No transpose', n-offset, k-1, one,
1851 & work(1,2), ldw, work(1,1), 1, one, work(1,k+1), 1 )
1852
1853 END IF
1854
1855
1856 IF( rk.LT.n ) THEN
1857
1858 CALL dgemv(
'No Transpose', n-rk, k, -one, work( k+1,2 ),
1859 & ldw,
1860 & a( rk, offset+1 ), lda, one, a( rk, rk+1 ), lda )
1861 END IF
1862
1863
1864 IF( rk.LT.minmn ) THEN
1865 DO j = rk + 1, n
1866
1867 IF( rwork( j ).NE.rzero ) THEN
1868
1869
1870
1871
1872
1873 temp = abs( a( rk, j ) ) / rwork( j )
1874 temp =
max( rzero, ( rone+temp )*( rone-temp ) )
1875
1876 temp2 = temp*( rwork( j ) / rwork( n+j ) )**2
1877 IF( temp2 .LE. tol3z ) THEN
1878
1879 rwork( n+j ) = dble( lsticc )
1880 lsticc = j
1881 ELSE
1882
1883 rwork( j ) = rwork( j )*sqrt( temp )
1884 END IF
1885 END IF
1886 END DO
1887 END IF
1888 a( rk, rk ) = akk
1889 IF (lsticc.NE.0) EXIT
1890 IF (tol_opt.LT.0) THEN
1891
1892
1893 trunc_err =
dnrm2( n-rk, rwork( rk+1 ), 1 )
1894 ENDIF
1895 END DO
1896
1897
1898
1899 IF( rk.LT.
min(n,m) )
THEN
1900 CALL dgemm(
'No transpose',
'Transpose', m-rk,
1901 & n-rk, k, -one, a(rk+1,offset+1), lda,
1902
1903 & work(k+1,2), ldw, one, a(rk+1,rk+1), lda )
1904 END IF
1905
1906 DO WHILE( lsticc.GT.0 )
1907
1908 itemp = nint( rwork( n + lsticc ) )
1909
1910 rwork( lsticc ) =
dnrm2( m-rk, a( rk+1, lsticc ), 1 )
1911
1912
1913
1914
1915
1916
1917 rwork( n + lsticc ) = rwork( lsticc )
1918 lsticc = itemp
1919 END DO
1920 IF(rk.GE.minmn) EXIT
1921 offset = rk
1922 IF (tol_opt.LT.0) THEN
1923
1924
1925 trunc_err =
dnrm2( n-rk, rwork( rk+1 ), 1 )
1926 ENDIF
1927 END DO
1928 rank = rk
1929 islr = .NOT.(rk.GT.maxrank)
1930 RETURN
1931 999 FORMAT ('On entry to DMUMPS_TRUNCATED_RRQR, parameter number',
1932 & i2,' had an illegal value')
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
subroutine xerbla(srname, info)
XERBLA
integer function idamax(n, dx, incx)
IDAMAX
subroutine dgeqrf(m, n, a, lda, tau, work, lwork, info)
DGEQRF
subroutine dlarfg(n, alpha, x, incx, tau)
DLARFG generates an elementary reflector (Householder matrix).
subroutine dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMQR
subroutine dswap(n, dx, incx, dy, incy)
DSWAP
subroutine dgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
DGEMV
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
real(wp) function dnrm2(n, x, incx)
DNRM2
double precision function dlamch(cmach)
DLAMCH