Found an issue with the book? Report it on Github.

함수 주석(Function Annotations)

함수 주석(Function Annotations)

이미 일반적인 주석에 대해 논의했지만, 함수와 함께 특히 많이 사용하는 여러 표준 주석을 다루어 보겠습니다. 이러한 주석의 의미는 모델리카 사양에 공식적으로 모두 정의되어 있습니다. 하지만, 이 섹션에서는 함수에 대한 주석의 세 가지 일반적인 범주에 대해 이야기를 하고 주석이 필요한 이유와 사용 방법에 대해 설명하고자 합니다.

수치적 주석(Mathematical Annotations)

첫번째로 다루는 것은, 함수에 대한 추가적인 수학적 정보를 주석이 제공한다는 것 입니다.함수는 algorithm 섹션을 사용하여 작성되기 때문에 일반적으로 함수의 동작에 대한 방정식을 유도하는 것이 불가능하며,따라서 많은 기호 조작(symbolic manipulations)이 불가능합니다.그러나 이 섹션의 주석을 사용하면 이러한 정보로 함수 정의를 확장할 수 있습니다.

도함수(derivative)

다항식 해석(Polynomial Evaluation) 예제에서 본 것처럼 모델리카 컴파일러에 주어진 함수의 도함수를 계산하는 방법을 알려주고 싶은 상황이 있습니다. 이는 함수에 derivative 주석을 추가하여 수행됩니다.

간단한 1차 도함수(Simple First Derivative)

derivative 주석의 기본 용도는 주석이 달린 함수의 1차 도함수를 계산하는 다른 모델리카 함수의 이름을 지정하는 것입니다. 예를 들어 아래와 같습니다.

function f
  input Real x;
  input Real y;
  output Real z;
  annotation ...
algorithm
  z := // some expression involving x and y
end f;

function df
  input Real x;
  input Real y;
  input Real dx;
  input Real dy;
  output Real dz;
algorithm
  dz := // some expression involving x, y, dx and dy
end df;

이 경우 미분 함수 df 에 대한 첫 번째 인수는 원래 함수 f 와 동일하며, 인수 다음에는 원래 함수에 대한 입력 인수의 미분한 버전이 옵니다. 마지막으로 미분 함수의 출력은 원래 함수 출력의 미분 버전입니다. 복잡하게 들리지만 동일한 기능을 코드로 실제 구성 할 때는 정말 간단하다는 사실을 알게 될 것입니다.

모델리카 함수가 주어지면 모델리카 컴파일러는 이러한 함수를 사용하여 예제 와 같은 다양한 도함수를 계산할 수 있습니다.

\frac{\mathrm{d}f}{\mathrm{d}v}(x,y) = df(x, y, \frac{\partial x}{\partial v}, \frac{\partial y}{\partial v})

일부 전달 요소(Arguments)의 민감도(Insensitivity to Some Arguments)

이제 \frac{\partial y}{\partial v} 가 0인 경우를 생각해 보겠습니다.미분 함수는 0 값(또는 인수가 배열인 경우 0으로된 배열)을 전달합니다. 그런 다음 이 0 값은 미분 함수 내부의 여러 계산에 사용하는데, 전부는 아니더라도 대부분은 곱셈이므로 계산 결과는 0이 됩니다.그러면 이러한 0이 최종 결과에 추가되지만 영향을 미치지는 않고, 결과에 영향을 주지 않기 때문에 건너뛸 수 있는 계산이 많이 존재합니다.

모델리카는 이러한 계산을 피할 수 있는 방법을 제공합니다.모델리카 컴파일러가 미분 중 하나가 0이라는 것을 선험적으로 알고 있는 경우 해당 사례에 대한 미분을 계산하는 함수가 정의되어 있는지 (derivative 주석 집합 중에서) 확인할 수 있는데,이러한 경우는 derivative 주석에 zeroDerivative 인수를 사용하여 지정합니다.예제 함수 f 의 경우 다음 주석을 추가할 수 있습니다.

function f
  input Real x;
  input Real y;
  output Real z;
  annotation ...
algorithm
  z := // some expression involving x and y
end f;

여기서 df_onlyx 는 다음과 같이 정의합니다.

function df_onlyx
  input Real x;
  input Real y;
  input Real dx;
  output Real dz;
algorithm
  dz := // some expression involving x, y, dx
end df_onlyx;

dy 는 이 함수에 포함되어 있지 않습니다. 이 함수는 dy 가 0인 특별한 경우에 사용하며, dy 가 인수에 나타나지 않기 때문에 dx 와 관련된 계산만 포함 합니다.

2차 도함수(Second Derivatives)

여기에서 다룰 가치가 있는 몇 가지 변형된 형태가 더 있습니다. 첫 번째는 함수의 2차 도함수를 지정하는 방법이고, order 인수를 추가하면 됩니다.함수는 여러 derivative 주석을 가질 수 있습니다. 예를 들면 아래와 같습니다.

function f
  input Real x;
  input Real y;
  output Real z;
  annotation ...
algorithm
  z := // some expression involving x and y
end f;

function df
  ...
end df;

function ddf
  input Real x;
  input Real y;
  input Real dx;
  input Real dy;
  input Real ddx;
  input Real ddy;
  output Real ddz;
algorithm
  ddz := // some expression involving x, y, dx, dy,
        // ddx and ddz
end ddf;

여기에서 어떻게 해야할 지 당황하지 않았기를 바랍니다. 2차 도함수를 계산하기 위해서는 원래 함수에 derivative 주석을 추가해야 합니다. 즉, 아래와 같습니다.

annotation ...

이 추가 주석에는 함수가 계산하는 도함수를 나타내는 추가 인수 order 가 있습니다.

Non-Real 전달인자(Non-Real Arguments)

논의해야 할 복합적인 문제가 하나 더 있습니다.함수에 실수를 나타내지 않는 인수가 있는 경우 입니다.예를 들면 아래와 같습니다.

function g
  input Real x;
  input Integer y;
  output Real z;
algorithm
  z := // some expression involving x and y
end g;

여기에서 y 인수와 관련하여 이 함수의 미분을 취하는 것은 의미가 없습니다. 왜냐하면 그것이 정수이기 때문입니다.도함수를 공식화할 때 모든 비실수 인수는 무시할 수 있습니다. 따라서 이 함수의 도함수를 계산하려면 다음과 같이 하면 됩니다.

function g
  input Real x;
  input Integer y;
  output Real z;
  annotation ...
algorithm
  z := // some expression involving x and y
end g;

function dg
  input Real x;
  input Integer y;
  input Real dx;
  output Real dz;
algorithm
  dz := // some expression involving x, y and dx
end dg;

즉, 미분 인수는 실제 인수에만 적용됩니다.

inverse

비선형성(Non-Linearities) 에 대한 토론 중에 inverse 주석을 사용하여 모델리카 컴파일러에 함수의 역을 계산하는 방법을 알려주는 방법을 다루었습니다.역함수의 목표는 현재 함수의 입력 인수 중 하나에 대해 명시적으로 해결하는 것입니다.이와 같이 inverse 주석에는 현재 함수의 입력 및 출력 변수를 포함하는 명시적 방정식이 포함되지만 입력 인수 중 하나를 명시적으로 계산하기 위해 다른 함수와 함께 사용합니다.

예를 들어 다음과 같이 정의된 모델리카 함수의 경우

 function h
   input Real a;
   input Real b;
   output Real c;
   annotation ...
algorithm
   c := // some calculation involving a and b
end h;

정의되는 h_inv_b 함수에 ac 를 인수로 전달하여 b 를 계산할 수 있음을 알 수 있습니다.

 function h_inv_b
   input Real a;
   input Real c;
   output Real b;
algorithm
   b := // some calculation involving a and c
end h_inv_b;

코드 생성(Code Generation)

주석에 대해 다음에 다룰 주제는 함수 정의가 시뮬레이션을 위해 코드로 변환되는 방식과 관련됩니다.이러한 주석을 통해 모델 개발자는 코드 생성 프로세스를 수행하는 방법에 대한 힌트를 모델리카 컴파일러에게 제공할 수 있습니다.

Inline

Inline 주석은 함수의 명령문이 "inline" 되어야 한다는 모델리카 컴파일러에게 주는 힌트이며, 주석 값은 인라인을 수행해야 하는지 여부를 제안하는 데 사용합니다. 기본값(Inline 주석이 없는 경우)은 false 입니다.다음은 Inline 주석을 사용하는 함수입니다:

function SimpleCalculation
  input Real x;
  input Real y;
  output Real z;
  annotation ...
algorithm
  z := 2*x-y;
end SimpleCalculation;

여기에서 Inline 주석은 모델리카 컴파일러가 SimpleCalculation 함수를 인라인해야 함을 시사합니다.함수 호출을 출력 결과를 계산하는 함수의 명령문으로 대체하여 함수가 인라인되며, 매우 간단한 계산을 수행하는 함수에 유용합니다. 함수를 호출하는 "비용"(CPU 시간)은 함수가 수행하는 작업의 비용과 같은 수준인데, 이런경우 함수를 인라인하면 목적을 유지하면서 함수 호출 비용을 제거할 수 있습니다.

Inline 기능은 모델리카 컴파일러에 대한 힌트일 뿐이며, 컴파일러는 함수를 인라인할 의무가 없습니다. 또한 함수를 인라인하는 컴파일러의 기능은 함수의 복잡성에 따라 달라집니다.일반적으로 함수를 인라인하는 것이 반드시 가능하거나 바람직하지는 않습니다.

LateInline

Inline 주석과 마찬가지로 LateInline 함수는 모델리카 컴파일러에게 함수를 인라인하는 것이 더 효율적일 것이라고 알려줍니다.``LateInline`` 주석에는 함수를 인라인할지 여부를 지정하는 Boolean 값도 할당합니다.``Inline`` 주석과 LateInline 주석의 차이점은 LateInline 은 기호 조작이 수행된 후에 인라인을 수행 해야 함을 나타낸다는 점 입니다.하지만, 인라인과 다른 기호 조작 간의 잠재적인 상호 작용에 대한 자세한 논의는 이 책의 범위를 벗어나므로 다루지 않겠습니다.

LateInline 주석이 둘 다 함수에 적용되는 경우 Inline 주석보다 우선한다는 점에 유의해야 합니다. 즉, 아래와 같습니다.

Inline

LateInline

Interpretation

false

false

Inline=false

true

false

Inline=true

false

true

LateInline=true

true

true

LateInline=true

외부 함수(External Functions)

주석에 대해 마지막으로 알아야 할 것은 external 로 정의된 함수 입니다.이러한 함수는 외부에 포함된 파일이나 라이브러리에 의존 하는 경우 도 있는데, 이러한 주석은 종속성과 해당 위치를 모델리카 컴파일러에 알려줍니다.

Include

Include 주석은 모델리카 컴파일러에서 생성된 코드에 include 문이 필요할 때마다 사용되며,일반적으로 이것은 외부 라이브러리를 참조할 때 필요합니다. Include 주석의 값은 생성된 코드에 삽입되어야 하는 것에 대한 문자열 입니다.

annotation ...

Note

Include 주석의 값은 문자열입니다. 만약 여기 문자열이 포함된 경우에는 이스케이프해야 합니다.

IncludeDirectory

앞서 살펴본 바와 같이 Include 주석을 사용하면 생성된 코드에 삽입할 수 있고, IncludeDirectory 주석은 Include 주석으로 지정된 콘텐츠를 찾기 위해 검색해야 하는 디렉토리를 지정합니다.

이 주석의 값은 문자열이며, 디렉토리를 나타내거나 URL을 표현할 수 있습니다. 예를 들어 IncludeDirectory 주석의 기본값은 다음과 같습니다.

IncludeDirectory=modelica://LibraryName/Resources/Include

이러한 modelica:// URLs 의 의미를 곧 설명하겠습니다.

Library

Library 주석은 함수가 의존할 수 있는 컴파일된 라이브러리를 지정하는 데 사용되며, library의 값은 라이브러리의 이름을 나타내는 간단한 문자열이거나 이러한 문자열의 배열일 수 있습니다.

annotation ...

혹은

annotation ...

모델리카 컴파일러는 생성된 코드를 "연결"하는 동안 이 정보를 사용합니다.

LibraryDirectory

Include 와 같은 문제가 Library 에도 존재합니다. Library 주석은 추가해야 할 항목을 알려주지만 찾을 위치는 알려주지 않습니다. 이런 식으로 LibraryDirectory 주석은 IncludeDirectory 주석과 같은 역할을 합니다. IncludeDirectory 주석과 마찬가지로 URL일 수도 있습니다. 기본값은 다음과 같습니다.

LibraryDirectory=modelica://LibraryName/Resources/Library