@@ -142,8 +142,8 @@ program test_linalg
142
142
! is_triangular
143
143
!
144
144
call test_is_triangular_rsp
145
- ! call test_is_triangular_rdp
146
- ! call test_is_triangular_rqp
145
+ call test_is_triangular_rdp
146
+ call test_is_triangular_rqp
147
147
148
148
! call test_is_triangular_csp
149
149
! call test_is_triangular_cdp
@@ -1498,6 +1498,187 @@ subroutine test_is_triangular_rsp
1498
1498
msg= " true_when_working failed." ,warn= warn)
1499
1499
end subroutine test_is_triangular_rsp
1500
1500
1501
+ subroutine test_is_triangular_rdp
1502
+ real (dp) :: A_true_s_u(2 ,2 ), A_false_s_u(2 ,2 ) ! square matrices (upper triangular)
1503
+ real (dp) :: A_true_sf_u(2 ,3 ), A_false_sf_u(2 ,3 ) ! short and fat matrices
1504
+ real (dp) :: A_true_ts_u(3 ,2 ), A_false_ts_u(3 ,2 ) ! tall and skinny matrices
1505
+ real (dp) :: A_true_s_l(2 ,2 ), A_false_s_l(2 ,2 ) ! square matrices (lower triangular)
1506
+ real (dp) :: A_true_sf_l(2 ,3 ), A_false_sf_l(2 ,3 ) ! short and fat matrices
1507
+ real (dp) :: A_true_ts_l(3 ,2 ), A_false_ts_l(3 ,2 ) ! tall and skinny matrices
1508
+ logical :: should_be_true_s_u, should_be_false_s_u, true_when_working_s_u ! upper logicals
1509
+ logical :: should_be_true_sf_u, should_be_false_sf_u, true_when_working_sf_u
1510
+ logical :: should_be_true_ts_u, should_be_false_ts_u, true_when_working_ts_u
1511
+ logical :: should_be_true_s_l, should_be_false_s_l, true_when_working_s_l ! lower logicals
1512
+ logical :: should_be_true_sf_l, should_be_false_sf_l, true_when_working_sf_l
1513
+ logical :: should_be_true_ts_l, should_be_false_ts_l, true_when_working_ts_l
1514
+ logical :: true_when_working_u, true_when_working_l, true_when_working
1515
+ write (* ,* ) " test_is_triangular_rdp"
1516
+ ! upper triangular
1517
+ A_true_s_u = reshape ([1 .,0 .,3 .,4 .],[2 ,2 ]) ! generate triangular and non-triangular matrices of 3 types
1518
+ A_false_s_u = reshape ([1 .,2 .,0 .,4 .],[2 ,2 ])
1519
+ A_true_sf_u = reshape ([1 .,0 .,3 .,4 .,0 .,6 .],[2 ,3 ])
1520
+ A_false_sf_u = reshape ([1 .,2 .,3 .,4 .,0 .,6 .],[2 ,3 ])
1521
+ A_true_ts_u = reshape ([1 .,0 .,0 .,4 .,5 .,0 .],[3 ,2 ])
1522
+ A_false_ts_u = reshape ([1 .,0 .,0 .,4 .,5 .,6 .],[3 ,2 ])
1523
+ should_be_true_s_u = is_triangular(A_true_s_u,' u' ) ! test generated matrices
1524
+ should_be_false_s_u = is_triangular(A_false_s_u,' u' )
1525
+ should_be_true_sf_u = is_triangular(A_true_sf_u,' u' )
1526
+ should_be_false_sf_u = is_triangular(A_false_sf_u,' u' )
1527
+ should_be_true_ts_u = is_triangular(A_true_ts_u,' U' )
1528
+ should_be_false_ts_u = is_triangular(A_false_ts_u,' U' )
1529
+ true_when_working_s_u = (should_be_true_s_u .and. (.not. should_be_false_s_u)) ! combine results
1530
+ true_when_working_sf_u = (should_be_true_sf_u .and. (.not. should_be_false_sf_u))
1531
+ true_when_working_ts_u = (should_be_true_ts_u .and. (.not. should_be_false_ts_u))
1532
+ true_when_working_u = (true_when_working_s_u .and. true_when_working_sf_u .and. true_when_working_ts_u)
1533
+ ! lower triangular
1534
+ A_true_s_l = reshape ([1 .,2 .,0 .,4 .],[2 ,2 ]) ! generate triangular and non-triangular matrices of 3 types
1535
+ A_false_s_l = reshape ([1 .,0 .,3 .,4 .],[2 ,2 ])
1536
+ A_true_sf_l = reshape ([1 .,2 .,0 .,4 .,0 .,0 .],[2 ,3 ])
1537
+ A_false_sf_l = reshape ([1 .,2 .,3 .,4 .,0 .,0 .],[2 ,3 ])
1538
+ A_true_ts_l = reshape ([1 .,2 .,3 .,0 .,5 .,6 .],[3 ,2 ])
1539
+ A_false_ts_l = reshape ([1 .,2 .,3 .,4 .,5 .,6 .],[3 ,2 ])
1540
+ should_be_true_s_l = is_triangular(A_true_s_l,' l' ) ! test generated matrices
1541
+ should_be_false_s_l = is_triangular(A_false_s_l,' l' )
1542
+ should_be_true_sf_l = is_triangular(A_true_sf_l,' l' )
1543
+ should_be_false_sf_l = is_triangular(A_false_sf_l,' l' )
1544
+ should_be_true_ts_l = is_triangular(A_true_ts_l,' L' )
1545
+ should_be_false_ts_l = is_triangular(A_false_ts_l,' L' )
1546
+ true_when_working_s_l = (should_be_true_s_l .and. (.not. should_be_false_s_l)) ! combine results
1547
+ true_when_working_sf_l = (should_be_true_sf_l .and. (.not. should_be_false_sf_l))
1548
+ true_when_working_ts_l = (should_be_true_ts_l .and. (.not. should_be_false_ts_l))
1549
+ true_when_working_l = (true_when_working_s_l .and. true_when_working_sf_l .and. true_when_working_ts_l)
1550
+ ! combine upper and lower results
1551
+ true_when_working = (true_when_working_u .and. true_when_working_l)
1552
+ call check(true_when_working, &
1553
+ msg= " true_when_working failed." ,warn= warn)
1554
+ end subroutine test_is_triangular_rdp
1555
+
1556
+ subroutine test_is_triangular_rqp
1557
+ real (qp) :: A_true_s_u(2 ,2 ), A_false_s_u(2 ,2 ) ! square matrices (upper triangular)
1558
+ real (qp) :: A_true_sf_u(2 ,3 ), A_false_sf_u(2 ,3 ) ! short and fat matrices
1559
+ real (qp) :: A_true_ts_u(3 ,2 ), A_false_ts_u(3 ,2 ) ! tall and skinny matrices
1560
+ real (qp) :: A_true_s_l(2 ,2 ), A_false_s_l(2 ,2 ) ! square matrices (lower triangular)
1561
+ real (qp) :: A_true_sf_l(2 ,3 ), A_false_sf_l(2 ,3 ) ! short and fat matrices
1562
+ real (qp) :: A_true_ts_l(3 ,2 ), A_false_ts_l(3 ,2 ) ! tall and skinny matrices
1563
+ logical :: should_be_true_s_u, should_be_false_s_u, true_when_working_s_u ! upper logicals
1564
+ logical :: should_be_true_sf_u, should_be_false_sf_u, true_when_working_sf_u
1565
+ logical :: should_be_true_ts_u, should_be_false_ts_u, true_when_working_ts_u
1566
+ logical :: should_be_true_s_l, should_be_false_s_l, true_when_working_s_l ! lower logicals
1567
+ logical :: should_be_true_sf_l, should_be_false_sf_l, true_when_working_sf_l
1568
+ logical :: should_be_true_ts_l, should_be_false_ts_l, true_when_working_ts_l
1569
+ logical :: true_when_working_u, true_when_working_l, true_when_working
1570
+ write (* ,* ) " test_is_triangular_rqp"
1571
+ ! upper triangular
1572
+ A_true_s_u = reshape ([1 .,0 .,3 .,4 .],[2 ,2 ]) ! generate triangular and non-triangular matrices of 3 types
1573
+ A_false_s_u = reshape ([1 .,2 .,0 .,4 .],[2 ,2 ])
1574
+ A_true_sf_u = reshape ([1 .,0 .,3 .,4 .,0 .,6 .],[2 ,3 ])
1575
+ A_false_sf_u = reshape ([1 .,2 .,3 .,4 .,0 .,6 .],[2 ,3 ])
1576
+ A_true_ts_u = reshape ([1 .,0 .,0 .,4 .,5 .,0 .],[3 ,2 ])
1577
+ A_false_ts_u = reshape ([1 .,0 .,0 .,4 .,5 .,6 .],[3 ,2 ])
1578
+ should_be_true_s_u = is_triangular(A_true_s_u,' u' ) ! test generated matrices
1579
+ should_be_false_s_u = is_triangular(A_false_s_u,' u' )
1580
+ should_be_true_sf_u = is_triangular(A_true_sf_u,' u' )
1581
+ should_be_false_sf_u = is_triangular(A_false_sf_u,' u' )
1582
+ should_be_true_ts_u = is_triangular(A_true_ts_u,' U' )
1583
+ should_be_false_ts_u = is_triangular(A_false_ts_u,' U' )
1584
+ true_when_working_s_u = (should_be_true_s_u .and. (.not. should_be_false_s_u)) ! combine results
1585
+ true_when_working_sf_u = (should_be_true_sf_u .and. (.not. should_be_false_sf_u))
1586
+ true_when_working_ts_u = (should_be_true_ts_u .and. (.not. should_be_false_ts_u))
1587
+ true_when_working_u = (true_when_working_s_u .and. true_when_working_sf_u .and. true_when_working_ts_u)
1588
+ ! lower triangular
1589
+ A_true_s_l = reshape ([1 .,2 .,0 .,4 .],[2 ,2 ]) ! generate triangular and non-triangular matrices of 3 types
1590
+ A_false_s_l = reshape ([1 .,0 .,3 .,4 .],[2 ,2 ])
1591
+ A_true_sf_l = reshape ([1 .,2 .,0 .,4 .,0 .,0 .],[2 ,3 ])
1592
+ A_false_sf_l = reshape ([1 .,2 .,3 .,4 .,0 .,0 .],[2 ,3 ])
1593
+ A_true_ts_l = reshape ([1 .,2 .,3 .,0 .,5 .,6 .],[3 ,2 ])
1594
+ A_false_ts_l = reshape ([1 .,2 .,3 .,4 .,5 .,6 .],[3 ,2 ])
1595
+ should_be_true_s_l = is_triangular(A_true_s_l,' l' ) ! test generated matrices
1596
+ should_be_false_s_l = is_triangular(A_false_s_l,' l' )
1597
+ should_be_true_sf_l = is_triangular(A_true_sf_l,' l' )
1598
+ should_be_false_sf_l = is_triangular(A_false_sf_l,' l' )
1599
+ should_be_true_ts_l = is_triangular(A_true_ts_l,' L' )
1600
+ should_be_false_ts_l = is_triangular(A_false_ts_l,' L' )
1601
+ true_when_working_s_l = (should_be_true_s_l .and. (.not. should_be_false_s_l)) ! combine results
1602
+ true_when_working_sf_l = (should_be_true_sf_l .and. (.not. should_be_false_sf_l))
1603
+ true_when_working_ts_l = (should_be_true_ts_l .and. (.not. should_be_false_ts_l))
1604
+ true_when_working_l = (true_when_working_s_l .and. true_when_working_sf_l .and. true_when_working_ts_l)
1605
+ ! combine upper and lower results
1606
+ true_when_working = (true_when_working_u .and. true_when_working_l)
1607
+ call check(true_when_working, &
1608
+ msg= " true_when_working failed." ,warn= warn)
1609
+ end subroutine test_is_triangular_rqp
1610
+
1611
+ subroutine test_is_triangular_csp
1612
+ complex (sp) :: A_true_s_u(2 ,2 ), A_false_s_u(2 ,2 ) ! square matrices (upper triangular)
1613
+ complex (sp) :: A_true_sf_u(2 ,3 ), A_false_sf_u(2 ,3 ) ! short and fat matrices
1614
+ complex (sp) :: A_true_ts_u(3 ,2 ), A_false_ts_u(3 ,2 ) ! tall and skinny matrices
1615
+ complex (sp) :: A_true_s_l(2 ,2 ), A_false_s_l(2 ,2 ) ! square matrices (lower triangular)
1616
+ complex (sp) :: A_true_sf_l(2 ,3 ), A_false_sf_l(2 ,3 ) ! short and fat matrices
1617
+ complex (sp) :: A_true_ts_l(3 ,2 ), A_false_ts_l(3 ,2 ) ! tall and skinny matrices
1618
+ logical :: should_be_true_s_u, should_be_false_s_u, true_when_working_s_u ! upper logicals
1619
+ logical :: should_be_true_sf_u, should_be_false_sf_u, true_when_working_sf_u
1620
+ logical :: should_be_true_ts_u, should_be_false_ts_u, true_when_working_ts_u
1621
+ logical :: should_be_true_s_l, should_be_false_s_l, true_when_working_s_l ! lower logicals
1622
+ logical :: should_be_true_sf_l, should_be_false_sf_l, true_when_working_sf_l
1623
+ logical :: should_be_true_ts_l, should_be_false_ts_l, true_when_working_ts_l
1624
+ logical :: true_when_working_u, true_when_working_l, true_when_working
1625
+ write (* ,* ) " test_is_triangular_csp"
1626
+ ! upper triangular
1627
+ A_true_s_u = reshape ([cmplx (1 .,1 .),cmplx (0 .,0 .), &
1628
+ cmplx (3 .,1 .),cmplx (4 .,0 .)],[2 ,2 ]) ! generate triangular and non-triangular matrices of 3 types
1629
+ A_false_s_u = reshape ([cmplx (1 .,1 .),cmplx (2 .,0 .), &
1630
+ cmplx (0 .,0 .),cmplx (4 .,0 .)],[2 ,2 ])
1631
+ A_true_sf_u = reshape ([cmplx (1 .,1 .),cmplx (0 .,0 .), &
1632
+ cmplx (3 .,1 .),cmplx (4 .,0 .), &
1633
+ cmplx (0 .,0 .),cmplx (6 .,0 .)],[2 ,3 ])
1634
+ A_false_sf_u = reshape ([cmplx (1 .,1 .),cmplx (2 .,0 .), &
1635
+ cmplx (3 .,1 .),cmplx (4 .,0 .), &
1636
+ cmplx (0 .,0 .),cmplx (6 .,0 .)],[2 ,3 ])
1637
+ A_true_ts_u = reshape ([cmplx (1 .,1 .),cmplx (0 .,0 .),cmplx (0 .,0 .), &
1638
+ cmplx (4 .,0 .),cmplx (5 .,1 .),cmplx (0 .,0 .)],[3 ,2 ])
1639
+ A_false_ts_u = reshape ([cmplx (1 .,1 .),cmplx (0 .,0 .),cmplx (0 .,0 .), &
1640
+ cmplx (4 .,0 .),cmplx (5 .,1 .),cmplx (6 .,0 .)],[3 ,2 ])
1641
+ should_be_true_s_u = is_triangular(A_true_s_u,' u' ) ! test generated matrices
1642
+ should_be_false_s_u = is_triangular(A_false_s_u,' u' )
1643
+ should_be_true_sf_u = is_triangular(A_true_sf_u,' u' )
1644
+ should_be_false_sf_u = is_triangular(A_false_sf_u,' u' )
1645
+ should_be_true_ts_u = is_triangular(A_true_ts_u,' U' )
1646
+ should_be_false_ts_u = is_triangular(A_false_ts_u,' U' )
1647
+ true_when_working_s_u = (should_be_true_s_u .and. (.not. should_be_false_s_u)) ! combine results
1648
+ true_when_working_sf_u = (should_be_true_sf_u .and. (.not. should_be_false_sf_u))
1649
+ true_when_working_ts_u = (should_be_true_ts_u .and. (.not. should_be_false_ts_u))
1650
+ true_when_working_u = (true_when_working_s_u .and. true_when_working_sf_u .and. true_when_working_ts_u)
1651
+ ! lower triangular
1652
+ A_true_s_l = reshape ([cmplx (1 .,1 .),cmplx (2 .,0 .), &
1653
+ cmplx (0 .,0 .),cmplx (4 .,0 .)],[2 ,2 ]) ! generate triangular and non-triangular matrices of 3 types
1654
+ A_false_s_l = reshape ([cmplx (1 .,1 .),cmplx (0 .,0 .), &
1655
+ cmplx (3 .,1 .),cmplx (4 .,0 .)],[2 ,2 ])
1656
+ A_true_sf_l = reshape ([cmplx (1 .,1 .),cmplx (2 .,0 .), &
1657
+ cmplx (0 .,0 .),cmplx (4 .,0 .), &
1658
+ cmplx (0 .,0 .),cmplx (0 .,0 .)],[2 ,3 ])
1659
+ A_false_sf_l = reshape ([cmplx (1 .,1 .),cmplx (2 .,0 .), &
1660
+ cmplx (3 .,1 .),cmplx (4 .,0 .), &
1661
+ cmplx (0 .,0 .),cmplx (0 .,0 .)],[2 ,3 ])
1662
+ A_true_ts_l = reshape ([cmplx (1 .,1 .),cmplx (2 .,0 .),cmplx (3 .,1 .), &
1663
+ cmplx (0 .,0 .),cmplx (5 .,1 .),cmplx (6 .,0 .)],[3 ,2 ])
1664
+ A_false_ts_l = reshape ([cmplx (1 .,1 .),cmplx (2 .,0 .),cmplx (3 .,1 .), &
1665
+ cmplx (4 .,0 .),cmplx (5 .,1 .),cmplx (6 .,0 .)],[3 ,2 ])
1666
+ should_be_true_s_l = is_triangular(A_true_s_l,' l' ) ! test generated matrices
1667
+ should_be_false_s_l = is_triangular(A_false_s_l,' l' )
1668
+ should_be_true_sf_l = is_triangular(A_true_sf_l,' l' )
1669
+ should_be_false_sf_l = is_triangular(A_false_sf_l,' l' )
1670
+ should_be_true_ts_l = is_triangular(A_true_ts_l,' L' )
1671
+ should_be_false_ts_l = is_triangular(A_false_ts_l,' L' )
1672
+ true_when_working_s_l = (should_be_true_s_l .and. (.not. should_be_false_s_l)) ! combine results
1673
+ true_when_working_sf_l = (should_be_true_sf_l .and. (.not. should_be_false_sf_l))
1674
+ true_when_working_ts_l = (should_be_true_ts_l .and. (.not. should_be_false_ts_l))
1675
+ true_when_working_l = (true_when_working_s_l .and. true_when_working_sf_l .and. true_when_working_ts_l)
1676
+ ! combine upper and lower results
1677
+ true_when_working = (true_when_working_u .and. true_when_working_l)
1678
+ call check(true_when_working, &
1679
+ msg= " true_when_working failed." ,warn= warn)
1680
+ end subroutine test_is_triangular_csp
1681
+
1501
1682
1502
1683
pure recursive function catalan_number(n) result(value)
1503
1684
integer , intent (in ) :: n
0 commit comments