Skip to content

Commit

Permalink
Clean up table of sub-clock conversion operators
Browse files Browse the repository at this point in the history
  • Loading branch information
henrikt-ma committed Sep 19, 2020
1 parent 91a33aa commit 1d51433
Showing 1 changed file with 109 additions and 108 deletions.
217 changes: 109 additions & 108 deletions chapters/synchronous.tex
Expand Up @@ -622,137 +622,139 @@ \subsection{Base-clock conversion operators}\label{base-clock-conversion-operato

\subsection{Sub-clock conversion operators}\label{sub-clock-conversion-operators}

The following operators convert between synchronous clocks:
\begin{longtable}[]{|p{4cm}|p{11cm}|}
\hline \endhead
\multicolumn{2}{|p{15cm}|}{
The operators in this table have the following properties:

The input argument u is a clocked expression or an expression of type
Clock. (The operators can operate on all types of clocks.) If
u is a clocked expression, the operator returns a clocked variable that
has the same type as the expression. If u is an expression of type
Clock, the operator returns a Clock -- except for noClock where it is an error.

The optional input arguments \lstinline!factor! (default=0, min=0), and \lstinline!resolution!
(default=1, min=1) are parameter expressions of type Integer.
The operators listed below convert between synchronous clocks.
\begin{center}
\begin{tabular}{l|l l}
\hline
\tablehead{Expression} & \tablehead{Description} & \tablehead{Details}\\
\hline
\hline
\lstinline!subSample($u$, factor)! & Clock that is slower by a factor & \Cref{modelica:subSample}\\
\lstinline!superSample($u$, factor)! & Clock that is faster by a factor & \Cref{modelica:superSample}\\
\lstinline!shiftSample($u$, shiftCounter, resolution)! & Clock with time-shifted ticks & \Cref{modelica:shiftSample}\\
\lstinline!backSample($u$, backCounter, resolution)! & Inverse of \lstinline!shiftSample! & \Cref{modelica:backSample}\\
\lstinline!noClock($u$)! & Clock that is always inferred & \Cref{modelica:noClock}\\
\hline
\end{tabular}
\end{center}

Calls of the operators can use named arguments for the multi-letter arguments (i.e.\ not for u) with the given names, or positional arguments.
These operators have the following properties:
\begin{itemize}
\item
The input argument $u$ is a clocked expression or an expression of type \lstinline!Clock!. (The operators can operate on all types of clocks.) If $u$ is a clocked expression, the operator returns a clocked variable that has the same type as the expression. If $u$ is an expression of type \lstinline!Clock!, the operator returns a \lstinline!Clock! -- except for \lstinline!noClock! where it is an error.
\item
The optional input arguments \lstinline!factor! (defauls to 0, with \lstinline!min = 0!), and \lstinline!resolution! (defaults to 1, with \lstinline!min = 1!) are parameter expressions of type \lstinline!Integer!.
\item
Calls of the operators can use named arguments for the multi-letter arguments (i.e.\ not for $u$) with the given names, or positional arguments.
\begin{nonnormative}
Named arguments can make the calls easier to understand.
\end{nonnormative}
The input arguments \lstinline!shiftCounter! and \lstinline!backCounter! are parameter
expressions of type Integer (min=0).}
\\ \hline
\lstinline!subSample(u, factor)!
&
The clock of \lstinline!y = subSample(u, factor)! is factor-times slower than the clock of \lstinline!u!. At every factor ticks of the clock of \lstinline!u!, the
operator returns the value of \lstinline!u!. The first activation of the clock of \lstinline!y!
coincides with the first activation of the clock of \lstinline!u!, and then every activation of the clock of \lstinline!y!
coincides with the every factor-th activativation of the clock of \lstinline!u!. If argument
factor is not provided or is equal to zero, it is inferred, see \cref{sub-clock-inferencing}.
\\ \hline
\lstinline!superSample(u, factor)!
&
The clock of \lstinline!y = superSample(u, factor)! is factor-times faster
than the clock of \lstinline!u!. At every tick of the clock of \lstinline!y!, the operator
returns the value of \lstinline!u! from the last tick of the clock of \lstinline!u!. The first
activation of the clock of \lstinline!y! coincides with the first activation of the
clock of \lstinline!u!, and then the interval between activations of the clock of \lstinline!u! is split equidistantly
into factor activations, such that the activation 1+k*factor of \lstinline!y! coincides with the \lstinline!1+k! activation of \lstinline!u!.
\item
The input arguments \lstinline!shiftCounter! and \lstinline!backCounter! are parameter expressions of type \lstinline!Integer! with \lstinline!min = 0!.
\end{itemize}

\begin{operatordefinition}[subSample]
\begin{synopsis}\begin{lstlisting}
subSample($u$, factor=$\mathit{factor}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The clock of \lstinline!y = subSample($u$, $\mathit{factor}$)! is $\mathit{factor}$ times slower than the clock of $u$. At every $\mathit{factor}$ ticks of the clock of $u$, the operator returns the value of $u$. The first activation of the clock of \lstinline!y! coincides with the first activation of the clock of $u$, and then every activation of the clock of \lstinline!y! coincides with the every $\mathit{factor}$-th activativation of the clock of $u$. If argument $\mathit{factor}$ is not provided or is equal to zero, it is inferred, see \cref{sub-clock-inferencing}.
\end{semantics}
\end{operatordefinition}

\begin{operatordefinition}[superSample]
\begin{synopsis}\begin{lstlisting}
superSample($u$, factor=$\mathit{factor}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The clock of \lstinline!y = superSample($u$, $\mathit{factor}$)! is $\mathit{factor}$ times faster than the clock of $u$. At every tick of the clock of \lstinline!y!, the operator returns the value of $u$ from the last tick of the clock of $u$. The first activation of the clock of \lstinline!y! coincides with the first activation of the clock of $u$, and then the interval between activations of the clock of $u$ is split equidistantly into $\mathit{factor}$ activations, such that the activation $1 + k \cdot \mathit{factor}$ of \lstinline!y! coincides with the $1 + k$ activation of $u$.
\begin{nonnormative}
Thus \lstinline!subSample(superSample(u, factor), factor)=u!
Thus \lstinline!subSample(superSample($u$, $\mathit{factor}$), $\mathit{factor}$)! = $u$.
\end{nonnormative}
If argument factor is not provided or is equal to zero, it
is inferred, see \cref{sub-clock-inferencing}. If an event clock is associated to a
base-clock partition, all its sub-clock partitions must have resulting
clocks that are sub-sampled with an Integer factor with respect to this
base clock.
\par
\begin{example*}
If argument factor is not provided or is equal to zero, it is inferred, see \cref{sub-clock-inferencing}. If an event clock is associated to a base-clock partition, all its sub-clock partitions must have resulting clocks that are sub-sampled with an \lstinline!Integer! factor with respect to this base clock.

\begin{example}
\begin{lstlisting}[language=modelica]
Clock u = Clock(x > 0);
Clock y1 = subSample(u,4);
Clock y2 = superSample(y1,2); // fine; y2 = subSample(u,2)
Clock y3 = superSample(u ,2); // error
Clock y4 = superSample(y1,5); // error
Clock y1 = subSample(u, 4);
Clock y2 = superSample(y1, 2); // fine; y2 = subSample(u, 2)
Clock y3 = superSample(u, 2); // error
Clock y4 = superSample(y1, 5); // error
\end{lstlisting}
\end{example*}
\\ \hline
\begin{tabular}{@{}p{4cm}@{}}
\lstinline!shiftSample(u!,\\
\lstinline!shiftCounter, resolution)!
\end{tabular}
& The operator \lstinline!c=shiftSample(u,k,resolution)! splits the interval between
ticks of \lstinline!u! into \lstinline!resolution! equidistant intervals \lstinline!i!.
The clock \lstinline!c! then ticks \lstinline!k! intervals \lstinline!i! after each tick of \lstinline!u!.
\end{example}
\end{semantics}
\end{operatordefinition}

\begin{operatordefinition}[shiftSample]
\begin{synopsis}\begin{lstlisting}
shiftSample($u$, shiftCounter=$k$, resolution=$\mathit{resolution}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The operator \lstinline!c = shiftSample($u$, $k$, $\mathit{resolution}$)! splits the interval between ticks of $u$ into $\mathit{resolution}$ equidistant intervals $i$. The clock \lstinline!c! then ticks $k$ intervals $i$ after each tick of $u$.

It leads to
\begin{lstlisting}[language=modelica]
shiftSample(u,k,resolution)=subSample(shiftSample(superSample(u,resolution),k),resolution)
shiftSample($u$, $k$, $\mathit{resolution}$) =
subSample(shiftSample(superSample($u$, $\mathit{resolution}$), $k$), $\mathit{resolution}$)
\end{lstlisting}
\par
\begin{nonnormative*}

\begin{nonnormative}
Note, due to the restriction of \lstinline!superSample! on event clocks, \lstinline!shiftSample! can only shift the number of ticks of the event clock, but cannot introduce new ticks. Example:
\begin{lstlisting}[language=modelica]
// Rational interval clock
Clock u = Clock(3, 10); // ticks: 0, 3/10, 6/10, ..
Clock y1 = shiftSample(u,1,3); // ticks: 1/10, 4/10,
Clock y1 = shiftSample(u, 1, 3); // ticks: 1/10, 4/10,
...
// Event clock
Clock u = Clock(sin(2*pi*time)>0, startInterval=0.0)
Clock u = Clock(sin(2 * pi * time) > 0, startInterval = 0.0)
// ticks: 0.0, 1.0, 2.0, 3.0, ...
Clock y1 = shiftSample(u,2); // ticks: 2.0, 3.0, ...
Clock y2 = shiftSample(u,2,3);// error (resolution must be 1)
Clock y1 = shiftSample(u, 2); // ticks: 2.0, 3.0, ...
Clock y2 = shiftSample(u, 2, 3); // error (resolution must be 1)
\end{lstlisting}
\end{nonnormative*}
\\ \hline
\begin{tabular}{@{}p{4cm}@{}}
\lstinline!backSample(u,!\\
\lstinline!backCounter, resolution)!
\end{tabular}
&
The input argument u is either a \emph{component expression} (see
\cref{argument-restrictions-component-expression}) or an expression of type Clock.
This is an inverse of shiftSample such that \lstinline!Clock y=backSample(u, cnt, res)! implicitly defines
a clock y such that \lstinline!shiftSample(y, cnt, res)! activates at the same times as u.
It is an
error, if the clock of y starts before the base clock of u.

At every
tick of the clock of y, the operator returns the value of u from the
last tick of the clock of u. If u is a clocked Component Expression, the
operator returns the start value of u, see \cref{initialization-of-clocked-partitions}, before the
first tick of the clock of u.
\par
\begin{example*}
\end{nonnormative}
\end{semantics}
\end{operatordefinition}

\begin{operatordefinition}[backSample]
\begin{synopsis}\begin{lstlisting}
backSample($u$, backCounter=$\mathit{cnt}$, resolution=$\mathit{res}$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The input argument $u$ is either a \emph{component expression} (see \cref{argument-restrictions-component-expression}) or an expression of type \lstinline!Clock!. This is an inverse of \lstinline!shiftSample! such that \lstinline!Clock y = backSample($u$, $\mathit{cnt}$, $\mathit{res}$)! implicitly defines a clock \lstinline!y! such that \lstinline!shiftSample(y, $\mathit{cnt}$, $\mathit{res}$)! activates at the same times as $u$. It is an error if the clock of \lstinline!y! starts before the base clock of $u$.

At every tick of the clock of \lstinline!y!, the operator returns the value of $u$ from the last tick of the clock of $u$. If $u$ is a clocked Component Expression, the operator returns the start value of $u$, see \cref{initialization-of-clocked-partitions}, before the first tick of the clock of $u$.

\begin{example}
\begin{lstlisting}[language=modelica]
// Rational interval clock 1

Clock u = Clock(3, 10); // ticks: 0, 3/10, 6/10, ..
Clock y1 = shiftSample(u,3); // ticks: 9/10, 12/10, ..
Clock y2 = backSample(y1,2); // ticks: 3/10, 6/10,
Clock y1 = shiftSample(u, 3); // ticks: 9/10, 12/10, ..
Clock y2 = backSample(y1, 2); // ticks: 3/10, 6/10,
...
Clock y3 = backSample(y1,4); // error (ticks before u)
Clock y4 = shiftSample(u,2,3); // ticks: 2/10, 5/10,
Clock y3 = backSample(y1, 4); // error (ticks before u)
Clock y4 = shiftSample(u, 2, 3); // ticks: 2/10, 5/10,
...
Clock y5 = backSample(y4,1,3); // ticks: 1/10, 4/10,
Clock y5 = backSample(y4, 1, 3); // ticks: 1/10, 4/10,
...
// Event clock
Clock u = Clock(sin(2*pi*time) > 0, startInterval=xx)
Clock u = Clock(sin(2 * pi * time) > 0, startInterval=xx)
// ticks: 0, 1.0, 2.0, 3.0, ....
Clock y1 = shiftSample(u,3); // ticks: 3.0, 4.0, ...
Clock y2 = backSample(y1,2); // ticks: 1.0, 2.0, ...
Clock y1 = shiftSample(u, 3); // ticks: 3.0, 4.0, ...
Clock y2 = backSample(y1, 2); // ticks: 1.0, 2.0, ...
\end{lstlisting}
\end{example*}
\\ \hline
\lstinline!noClock(u)!
&
The clock of \lstinline!y = noClock(u)! is always inferred. At every tick
of the clock of \lstinline!y!, the operator returns the value of \lstinline!u! from the last
tick of the clock of \lstinline!u!. If \lstinline!noClock(u)! is called before the
first tick of the clock of \lstinline!u!, the start value of \lstinline!u! is returned.\\ \hline
\end{longtable}
\end{example}
\end{semantics}
\end{operatordefinition}

\begin{operatordefinition}[noClock]
\begin{synopsis}\begin{lstlisting}
noClock($u$)
\end{lstlisting}\end{synopsis}
\begin{semantics}
The clock of \lstinline!y = noClock($u$)! is always inferred. At every tick of the clock of \lstinline!y!, the operator returns the value of $u$ from the last tick of the clock of $u$. If \lstinline!noClock($u$)! is called before the first tick of the clock of $u$, the start value of $u$ is returned.
\end{semantics}
\end{operatordefinition}

\begin{nonnormative}
Clarification of \lstinline!backSample!:
Expand All @@ -773,25 +775,24 @@ \subsection{Sub-clock conversion operators}\label{sub-clock-conversion-operators
\begin{nonnormative}
Clarification of \lstinline!noClock! operator:

Note, that noClock(u) is not equivalent to sample(hold(u)). Consider the following model:
Note, that \lstinline!noClock(u)! is not equivalent to \lstinline!sample(hold(u))!. Consider the following model:
\begin{lstlisting}[language=modelica]
model NoClockVsSampleHold
Clock clk1 = Clock(0.1);
Clock clk2 = subSample(clk1,2);
Real x(start=0), y(start=0), z(start=0);
Clock clk2 = subSample(clk1, 2);
Real x(start = 0), y(start = 0), z(start = 0);
equation
when clk1 then
x = previous (x) + 0.1;
x = previous(x) + 0.1;
end when;
when clk2 then
y = noClock (x); // most recent value of x
z = sample (hold(x)); // left limit of x (infinitesimally delayed)!
y = noClock(x); // most recent value of x
z = sample(hold(x)); // left limit of x (infinitesimally delayed)!
end when;
end NoClockVsSampleHold;
\end{lstlisting}

Due to the infinitesimal delay of sample; z will not show the current value of x as clk2 ticks, but will show its previous value (left limit). However, y will show
the current value, since it has no infinitesimal delay.
Due to the infinitesimal delay of sample; \lstinline!z! will not show the current value of \lstinline!x! as \lstinline!clk2! ticks, but will show its previous value (left limit). However, \lstinline!y! will show the current value, since it has no infinitesimal delay.
\end{nonnormative}

Note that it is not legal to compute the derivative of the \lstinline!sample!, \lstinline!subSample!, \lstinline!superSample!, \lstinline!backSample!,
Expand Down

0 comments on commit 1d51433

Please sign in to comment.