표준 라이브러리: 수치 연산

표준 라이브러리: 수치 연산 (Standard library: Numerics)

표준 라이브러리는 부동 소수점 타입과 복소수 타입, 행렬에 대한 일반적인 수치 연산을 지원해요. 아래 절들에서 이 수치 연산들에 대한 간략한 소개를 제시할게요.

출처: 표준 라이브러리: 수치 연산 문서

본문

기본 함수 (Elementary Functions)

Ada.Numerics.Elementary_Functions 패키지는 부동 소수점 타입에 대한 일반적인 연산(제곱근, 로그, 삼각 함수(예: sin, cos))을 제공해요. 예를 들어:

with Ada.Text_IO;  use Ada.Text_IO;
with Ada.Numerics; use Ada.Numerics;

with Ada.Numerics.Elementary_Functions;
use  Ada.Numerics.Elementary_Functions;

procedure Show_Elem_Math is
   X : Float;
begin
   X := 2.0;
   Put_Line ("Square root of "
             & Float'Image (X)
             & " is "
             & Float'Image (Sqrt (X)));

   X := e;
   Put_Line ("Natural log of "
             & Float'Image (X)
             & " is "
             & Float'Image (Log (X)));

   X := 10.0 ** 6.0;
   Put_Line ("Log_10      of "
             & Float'Image (X)
             & " is "
             & Float'Image (Log (X, 10.0)));

   X := 2.0 ** 8.0;
   Put_Line ("Log_2       of "
             & Float'Image (X)
             & " is "
             & Float'Image (Log (X, 2.0)));

   X := Pi;
   Put_Line ("Cos         of "
             & Float'Image (X)
             & " is "
             & Float'Image (Cos (X)));

   X := -1.0;
   Put_Line ("Arccos      of "
             & Float'Image (X)
             & " is "
             & Float'Image (Arccos (X)));
end Show_Elem_Math;

여기서 Ada.Numerics 패키지의 표준 ePi 상수를 사용해요.

Ada.Numerics.Elementary_Functions 패키지는 Float 타입에 대한 연산을 제공해요. Long_FloatLong_Long_Float 타입에 대해서도 유사한 패키지가 있어요. 예를 들어 Ada.Numerics.Long_Elementary_Functions 패키지는 Long_Float 타입에 대해 동일한 연산 집합을 제공해요. 또한 Ada.Numerics.Generic_Elementary_Functions 패키지는 사용자 정의 부동 소수점 타입을 위해 인스턴스화할 수 있는 제네릭 버전이에요. 실제로 Elementary_Functions 패키지는 다음과 같이 정의할 수 있어요:

package Elementary_Functions is new
  Ada.Numerics.Generic_Elementary_Functions (Float);

난수 생성 (Random Number Generation)

Ada.Numerics.Float_Random 패키지는 0.0과 1.0 사이 범위에 대한 간단한 난수 생성기를 제공해요. 사용하려면 Random에 전달하는 생성기 G를 선언해요. 예를 들어:

with Ada.Text_IO;  use Ada.Text_IO;

with Ada.Numerics.Float_Random;
use  Ada.Numerics.Float_Random;

procedure Show_Float_Random_Num is
   G : Generator;
   X : Uniformly_Distributed;
begin
   Reset (G);

   Put_Line ("Some random numbers between "
             & Float'Image
                 (Uniformly_Distributed'First)
             & " and "
             & Float'Image
                 (Uniformly_Distributed'Last)
             & ":");
   for I in 1 .. 15 loop
      X := Random (G);
      Put_Line (Float'Image (X));
   end loop;
end Show_Float_Random_Num;

표준 라이브러리는 또한 Ada.Numerics.Discrete_Random 패키지에 속한 이산 숫자용 난수 생성기도 포함해요. 제네릭 패키지이므로 원하는 이산 타입으로 인스턴스화해야 해요. 이렇게 하면 생성기의 범위를 지정할 수 있어요. 다음 예시에서는 1에서 10 사이의 무작위 정수를 표시하는 애플리케이션을 만듭니다:

with Ada.Text_IO;  use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;

procedure Show_Discrete_Random_Num is

   subtype Random_Range is Integer range 1 .. 10;

   package R is new
     Ada.Numerics.Discrete_Random (Random_Range);
   use R;

   G : Generator;
   X : Random_Range;
begin
   Reset (G);

   Put_Line ("Some random numbers between "
             & Integer'Image (Random_Range'First)
             & " and "
             & Integer'Image (Random_Range'Last)
             & ":");

   for I in 1 .. 15 loop
      X := Random (G);
      Put_Line (Integer'Image (X));
   end loop;
end Show_Discrete_Random_Num;

여기서 패키지 R은 1에서 10 사이의 제한된 범위를 가진 Random_Range 타입으로 인스턴스화돼요. 이를 통해 난수에 사용되는 범위를 제어할 수 있어요. Random_Range 타입의 스펙을 변경해 0에서 20 사이의 무작위 정수를 표시하도록 애플리케이션을 쉽게 수정할 수 있어요. 부동 소수점이나 고정 소수점 타입도 사용할 수 있어요.

복소수 타입 (Complex Types)

Ada.Numerics.Complex_Types 패키지는 복소수 타입에 대한 지원을 제공하고, Ada.Numerics.Complex_Elementary_Functions 패키지는 Ada.Numerics.Elementary_Functions 패키지와 유사하게 복소수 타입에 대한 일반적인 연산을 지원해요. 마지막으로 Ada.Text_IO.Complex_IO 패키지를 사용해 복소수에 대한 I/O 연산을 수행할 수 있어요. 다음 예시에서 Complex 타입의 변수를 선언하고 애그리게이트(aggregate)로 초기화해요:

with Ada.Text_IO;  use Ada.Text_IO;
with Ada.Numerics; use Ada.Numerics;

with Ada.Numerics.Complex_Types;
use  Ada.Numerics.Complex_Types;

with Ada.Numerics.Complex_Elementary_Functions;
use  Ada.Numerics.Complex_Elementary_Functions;

with Ada.Text_IO.Complex_IO;

procedure Show_Elem_Math is

   package C_IO is new
     Ada.Text_IO.Complex_IO (Complex_Types);
   use C_IO;

   X, Y  : Complex;
   R, Th : Float;
begin
   X := (2.0, -1.0);
   Y := (3.0,  4.0);

   Put (X);
   Put (" * ");
   Put (Y);
   Put (" is ");
   Put (X * Y);
   New_Line;
   New_Line;

   R  := 3.0;
   Th := Pi / 2.0;
   X  := Compose_From_Polar (R, Th);
   --  대안:
   --  X := R * Exp ((0.0, Th));
   --  X := R * e ** Complex'(0.0, Th);

   Put ("Polar form:    "
        & Float'Image (R)  & " * e**(i * "
        & Float'Image (Th) & ")");
   New_Line;

   Put ("Modulus     of ");
   Put (X);
   Put (" is ");
   Put (Float'Image (abs X));
   New_Line;

   Put ("Argument    of ");
   Put (X);
   Put (" is ");
   Put (Float'Image (Argument (X)));
   New_Line;
   New_Line;

   Put ("Sqrt        of ");
   Put (X);
   Put (" is ");
   Put (Sqrt (X));
   New_Line;
end Show_Elem_Math;

이 예시에서 볼 수 있듯 *+ 같은 모든 일반적인 연산자는 복소수 타입에 사용할 수 있어요. 복소수에 대한 Argument, Exp 같은 전형적인 연산도 있어요. 애그리게이트를 사용해 데카르트 형식으로 복소수를 초기화하는 것 외에도 Compose_From_Polar 함수를 호출해 극 형식으로 초기화할 수 있어요.

Ada.Numerics.Complex_TypesAda.Numerics.Complex_Elementary_Functions 패키지는 Float 타입에 대한 연산을 제공해요. Long_FloatLong_Long_Float 타입에 대해서도 유사한 패키지가 있어요. 또한 Ada.Numerics.Generic_Complex_TypesAda.Numerics.Generic_Complex_Elementary_Functions 패키지는 사용자 정의 또는 미리 정의된 부동 소수점 타입을 위해 인스턴스화할 수 있는 제네릭 버전이에요. 예를 들어:

with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Elementary_Functions;
with Ada.Text_IO.Complex_IO;

procedure Show_Elem_Math is

   package Complex_Types is new
     Ada.Numerics.Generic_Complex_Types (Float);
   use Complex_Types;

   package Elementary_Functions is new
     Ada.Numerics.Generic_Complex_Elementary_Functions
       (Complex_Types);
   use Elementary_Functions;

   package C_IO is new Ada.Text_IO.Complex_IO
     (Complex_Types);
   use C_IO;

   X, Y  : Complex;
   R, Th : Float;

벡터와 행렬 조작 (Vector and Matrix Manipulation)

Ada.Numerics.Real_Arrays 패키지는 벡터와 행렬에 대한 지원을 제공해요. 역행렬, 행렬식, 고유값 같은 일반적인 행렬 연산과 행렬 덧셈·곱셈 같은 더 단순한 연산자를 포함해요. 벡터와 행렬은 각각 Real_VectorReal_Matrix 타입으로 선언할 수 있어요.

다음 예시는 Ada.Numerics.Real_Arrays 패키지의 일부 연산을 사용해요:

with Ada.Text_IO;  use Ada.Text_IO;

with Ada.Numerics.Real_Arrays;
use  Ada.Numerics.Real_Arrays;

procedure Show_Matrix is

   procedure Put_Vector (V : Real_Vector) is
   begin
      Put ("    (");
      for I in V'Range loop
         Put (Float'Image (V (I)) & " ");
      end loop;
      Put_Line (")");
   end Put_Vector;

   procedure Put_Matrix (M : Real_Matrix) is
   begin
      for I in M'Range (1) loop
         Put ("    (");
         for J in M'Range (2) loop
            Put (Float'Image (M (I, J)) & " ");
         end loop;
         Put_Line (")");
      end loop;
   end Put_Matrix;

   V1       : Real_Vector := (1.0, 3.0);
   V2       : Real_Vector := (75.0, 11.0);

   M1       : Real_Matrix :=
                ((1.0, 5.0, 1.0),
                 (2.0, 2.0, 1.0));
   M2       : Real_Matrix :=
                ((31.0, 11.0, 10.0),
                 (34.0, 16.0, 11.0),
                 (32.0, 12.0, 10.0),
                 (31.0, 13.0, 10.0));
   M3       : Real_Matrix := ((1.0, 2.0),
                              (2.0, 3.0));
begin
   Put_Line ("V1");
   Put_Vector (V1);
   Put_Line ("V2");
   Put_Vector (V2);
   Put_Line ("V1 * V2 =");
   Put_Line ("    "
             & Float'Image (V1 * V2));
   Put_Line ("V1 * V2 =");
   Put_Matrix (V1 * V2);
   New_Line;

   Put_Line ("M1");
   Put_Matrix (M1);
   Put_Line ("M2");
   Put_Matrix (M2);
   Put_Line ("M2 * Transpose(M1) =");
   Put_Matrix (M2 * Transpose (M1));
   New_Line;

   Put_Line ("M3");
   Put_Matrix (M3);
   Put_Line ("Inverse (M3) =");
   Put_Matrix (Inverse (M3));
   Put_Line ("abs Inverse (M3) =");
   Put_Matrix (abs Inverse (M3));
   Put_Line ("Determinant (M3) =");
   Put_Line ("    "
             & Float'Image (Determinant (M3)));
   Put_Line ("Solve (M3, V1) =");
   Put_Vector (Solve (M3, V1));
   Put_Line ("Eigenvalues (M3) =");
   Put_Vector (Eigenvalues (M3));
   New_Line;
end Show_Matrix;

행렬 차원은 지정하지 않으면 초기화에 사용된 애그리게이트에서 자동으로 결정돼요. 하지만 명시적 범위를 사용할 수도 있어요. 예를 들어:

M1       : Real_Matrix (1 .. 2, 1 .. 3) :=
             ((1.0, 5.0, 1.0),
              (2.0, 2.0, 1.0));

Ada.Numerics.Real_Arrays 패키지는 Float 타입에 대한 연산을 구현해요. Long_FloatLong_Long_Float 타입에 대해서도 유사한 패키지가 있어요. 또한 Ada.Numerics.Generic_Real_Arrays 패키지는 사용자 정의 부동 소수점 타입으로 인스턴스화할 수 있는 제네릭 버전이에요. 예를 들어 Real_Arrays 패키지는 다음과 같이 정의할 수 있어요:

package Real_Arrays is new
  Ada.Numerics.Generic_Real_Arrays (Float);

더 알아보기 (Learn more)