This lightly commented program performs a unit test on the Mathematic_Vector Class.
program Unit_Test use Caesar_Data_Structures_Module use Caesar_Mathematic_Vector_Class use Caesar_Numbers_Module, only: one, two, three, six implicit none type(Communication_type) :: Comm type(Base_Structure_type) :: Row_Structure type(Status_type) :: status type(character,name_length) :: Locus_Name, MV_Name type(integer,1) :: Row_Length_Vector, Rows type(integer) :: shift type(real,1) :: Values type(real) :: A_Norm2, B_Norm2, DotP, NRows_real, PNorm type(integer) :: I, NRows type(Mathematic_Vector_type) :: A_MV, B_MV ! Initializations. call Initialize (Comm) call Output (Comm) call Initialize (status) call Initialize (Locus_Name) Locus_Name = 'Rows' call Initialize (MV_Name) MV_Name = 'Variables' call Initialize (Row_Length_Vector, NPEs) Row_Length_Vector = (/ (i**2, i = 1, NPEs) /) ! Local temp vectors. call Initialize (Rows, Row_Length_Vector(this_PE)) call Initialize (Values, Row_Length_Vector(this_PE)) ! Initialize base structure and mathematic vectors. call Initialize (Row_Structure, Row_Length_Vector, Locus_Name, status) call Initialize (A_MV, Row_Structure, MV_Name, status) call Duplicate (B_MV, A_MV, status) NRows = Length_Total(Row_Structure) ! Testing statements. ! Note that there can be no procedure calls inside a loop which ! is executed a different number of times on each PE, because ! global communication is done for verifications within a procedure. shift = - First_PE(Row_Structure) + 1 do i = First_PE(Row_Structure), Last_PE(Row_Structure) ! Values(i) = global i Values(i + shift) = changetype(real, i) ! Rows(i) = global i, but reversed in order on each PE Rows(i + shift) = Last_PE(Row_Structure) + First_PE(Row_Structure) - i end do ! Set A_MV via operator overloading. A_MV = Values ! Set B_MV via explicit call (vector of values) with half of Values, ! then use the Add_Values procedure to add the other half. ! Note that B_MV values are in reverse order on each PE. Values = Values/2.d0 call Set_Values (B_MV, Values, Rows) call Add_Values (B_MV, Values, Rows) ! Output the MVs. PNorm = P_Norm(A_MV, 4) call Output (A_MV, MAX(1, NRows/10), MIN(NRows, NRows/10+50)) call Output (B_MV, MAX(1, NRows/10), MIN(NRows, NRows/10+50)) ! Check some things that are known because Values(i) = i : if (Average(A_MV) /= (Maximum(A_MV)+one)/two) then if (this_is_IO_PE) then write (6,*) 'Error -- Average or Maximum is incorrect.' end if end if if (Maximum(A_MV) /= Infinity_Norm(A_MV)) then if (this_is_IO_PE) then write (6,*) 'Error -- Maximum or Infinity_Norm is incorrect.' end if end if if (Minimum(A_MV) /= one) then if (this_is_IO_PE) then write (6,*) 'Error -- Minimum is incorrect.' end if end if if (Sum(A_MV) /= One_Norm(A_MV)) then if (this_is_IO_PE) then write (6,*) 'Error -- Sum or One_Norm is incorrect.' end if end if ! Tweak one value of A_MV and re-output. call Set_Values (A_MV, 10.d0, Last_PE(Row_Structure)) call Output (A_MV, MAX(1, NRows/10), MIN(NRows, NRows/10+50)) ! Set A_MV = B_MV (values are reversed on each PE). Values = B_MV A_MV = Values ! Orthogonality test (note A_MV = B_MV from above). if (A_MV .Orthogonal. B_MV) then if (this_is_IO_PE) then write (6,*) 'Error -- Vectors are orthogonal.' end if end if ! Dot product test. ! This makes use of the fact that ! ! -- ! \ 2 1 3 2 ! / k = - (2 n + 3 n + n) ! -- 6 ! k=1,n A_MV = Values ! Make sure A_MV = B_MV. Note that value order is B_MV = Values ! reversed on each PE, but that won't affect the ! dot product. A_Norm2 = Two_Norm(A_MV) ! These are calculated here so that the B_Norm2 = Two_Norm(B_MV) ! Cauchy-Schwartz inequality check will be ! done in the dot product. DotP = A_MV .DotProduct. B_MV NRows_real = changetype(real,NRows) if (this_is_IO_PE) then write (6,100) 'Dot product of A_MV and B_MV = ', DotP 100 format (/,a,f15.1) if (.not. VeryClose(DotP, & (two * NRows_real**3 + three * NRows_real**2 + NRows_real)/six)) then write (6,*) 'Error -- Dot product is incorrect.' end if end if ! Also need ! 1: call Add (MV1, MV2, MV3) or call Add_to_MV (MV1, MV2) ! 2: MV1 = MV2 ! 3: call Scale (MV, scalar) ! 4: MV1 == MV2 ! Check state of the mathematic vectors. VERIFY(Valid_State(A_MV),0) VERIFY(Valid_State(B_MV),0) ! Finalize mathematic vectors and communications. call Finalize (A_MV) call Finalize (B_MV) call Finalize (Comm) end