{"id":195908,"date":"2025-01-13T08:52:43","date_gmt":"2025-01-13T08:52:43","guid":{"rendered":"https:\/\/innovationspace.ansys.com\/knowledge\/?post_type=topic&#038;p=195908"},"modified":"2025-11-26T14:54:00","modified_gmt":"2025-11-26T14:54:00","slug":"image-processing-in-scade-one-with-the-pack-operator","status":"publish","type":"topic","link":"https:\/\/innovationspace.ansys.com\/knowledge\/forums\/topic\/image-processing-in-scade-one-with-the-pack-operator\/","title":{"rendered":"Image processing in Scade One with the pack operator"},"content":{"rendered":"<h3  id=\"INTRODUCTION\">Introduction<\/h3>\n<p>In a previous blog series, we introduced <a href=\"https:\/\/innovationspace.ansys.com\/knowledge\/forums\/topic\/scade-one-bridging-the-gap-between-model-based-design-and-traditional-programming\/\">Swan<\/a>, the domain-specific language designed for modeling in Scade One. We also explored how the <a href=\"https:\/\/innovationspace.ansys.com\/knowledge\/forums\/topic\/matrix-operators-using-scade-ones-forward-block\/\">forward<\/a> block facilitates the implementation of array and matrix operators with a new loop-like construct for iterative algorithms.<\/p>\n<p>In this new blog, we will showcase the pack operator, a powerful new construct available in Swan, that helps address common uses cases in signal processing such as correlation, convolution, cross-correlation, and more.<\/p>\n<h3  id=\"THE-PROBLEM-SPACE\">The problem space<\/h3>\n<p>In today&#8217;s article, we will demonstrate how to to solve a signal processing problem with Scade One: detecting shapes in a noisy 2D image. To achieve this, we will implement a (somewhat naive) Scade One cross-correlation algorithm that demonstrates core principles.<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-banner.jpg\" style=\"max-height: 700px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>The solutions presented in this article can apply to any signal processing problem that looks at a signal&#8217;s current value and its neighbors. This includes many common applications: filtering, edge detection, blurring, sharpening, correlation, convolution, etc.<\/p>\n<h3  id=\"A-NOTE-ON-SAFE-ARRAY-ACCESS-IN-SWAN\">A note on safe array access in Swan<\/h3>\n<p>One way to implement our algorithm would be to process our signal using a fixed-size, sliding window of elements.<\/p>\n<p>By construction, the Swan language enables <a href=\"https:\/\/ansyskm.ansys.com\/forums\/topic\/memory-safe-languages-and-what-it-means-for-scade\/\">safe usage of arrays<\/a>: arrays have a static size, no out-of-bounds accesses, and are fully defined. Any time we need to dynamically access an array index, we benefit from Scade One&#8217;s native array access protection. It returns a default value if the index is not within the array&#8217;s bounds:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-safe-array-access-1.jpg\" style=\"max-height: 250px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>In some cases, the model designer may have already added a similar protection to the index computation itself. Such an approach may introduce uncoverable points in the model, that may later need to be justified during validation.<\/p>\n<p>One thing to note is that the above construct introduces an <code>if<\/code> statement in the generated C code. Signal processing algorithms often involve processing large arrays and reading several contiguous values. Relying on the above construct for such a large number of reads would be detrimental to performance; we are therefore going to rely on another construct that fits our purpose better.<\/p>\n<h3  id=\"INTRODUCING-THE-PACK-BLOCK\">Introducing the pack block<\/h3>\n<p>In the Swan language, successor of Scade, the new <strong>pack block<\/strong> allows us to process a <strong>Swan array or matrix by chunks, which may or may not overlap<\/strong>.<\/p>\n<p>The <strong>pack<\/strong> operator guarantees safe <em>and efficient<\/em> usage of arrays without the need to specify redundant default values.<\/p>\n<p><strong>Swan language reference<\/strong><\/p>\n<table>\n<tr>\n<td>\n<p><code>pack&lt;&zwj;&lt;&zwj;k,m&zwj;&gt;&zwj;&gt;(A)<\/code> returns the array composed of <code>m<\/code> chunks of size <code>k<\/code>; chunks can overlap.<\/p>\n<p>If <code>A<\/code> is of size <code>n<\/code>, <code>B = pack&lt;&zwj;&lt;&zwj;k,m&zwj;&gt;&zwj;&gt;(A)<\/code> is such that <code>B[i][j] = A[s*i*j]<\/code> where <code>s = (n-k)\/(m-1)<\/code><\/p>\n<ul>\n<li><code>input<\/code>: an array of type <code>T^n<\/code><\/li>\n<li>input parameters:<em> <\/em><code>k<\/code>,<em> <\/em><code>m<\/code><em> <\/em>two sizes verifying the conditions: <code>m&zwj;&gt;1<\/code> and <code>k&lt;&zwj;n<\/code> and <code>(m-1)<\/code> divides <code>(n-k)<\/code><\/li>\n<li>output: an array of type <code>T^k^m<\/code><\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<\/table>\n<p>Examples:<\/p>\n<p>Let&#8217;s have a look at four use cases, starting from this stream of values:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-stream-1.svg\" style=\"max-height: 100px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>We want to apply an iterative algorithm on:<\/p>\n<ul>\n<li>4 chunks with size 5 without overlap between each chunk.<\/li>\n<\/ul>\n<table>\n<tr>\n<td>\n<p><code>n = 20<\/code>, size of the stream <\/p>\n<p><code>k = 5<\/code>, size of each chunk<\/p>\n<p><code>s = 5<\/code>, to avoid overlap<\/p>\n<p>Let&#8217;s verify constraints: <code>s = (n - k) \/ (m - 1)<\/code><\/p>\n<p>or : <code>m = (n - k) \/ s + 1<\/code><\/p>\n<ul>\n<li><code>pack&lt;&zwj;&lt;&zwj;5 , (20 - 5) \/ 4 + 1&zwj;&gt;&zwj;&gt;<\/code><\/li>\n<li><code>pack&lt;&zwj;&lt;&zwj;5,4&zwj;&gt;&zwj;&gt;<\/code><\/li>\n<\/ul>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-pack-5-4-example-1.svg\" style=\"max-height: 100px !important\" \/><br \/>\n                <em><\/em>\n<\/p>\n<p><code>pack&lt;&zwj;&lt;&zwj;5,4&zwj;&gt;&zwj;&gt;(A)<\/code> reshapes <code>A<\/code> from <code>integer^20<\/code> to <code>integer^5^4<\/code><\/p>\n<\/td>\n<\/tr>\n<\/table>\n<ul>\n<li>Overlapping chunks with size 5, shifted by 1.<\/li>\n<\/ul>\n<table>\n<tr>\n<td>\n<p><code>n = 20<\/code>, size of the stream <\/p>\n<p><code>k = 5<\/code>, size of each chunk<\/p>\n<p><code>s = 1<\/code><\/p>\n<p>Let&#8217;s verify constraints: <code>s = (n - k) \/ (m - 1)<\/code><\/p>\n<p>or : <code>m = (n - k) \/ s + 1<\/code><\/p>\n<ul>\n<li><code>pack&lt;&zwj;&lt;&zwj;5 , (20 - 5) \/ 1 + 1&zwj;&gt;&zwj;&gt;<\/code><\/li>\n<li><code>pack&lt;&zwj;&lt;&zwj;5,16&zwj;&gt;&zwj;&gt;<\/code><\/li>\n<\/ul>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-pack-5-16-example-1.svg\" style=\"max-height: 300px !important\" \/><br \/>\n                <em><\/em>\n<\/p>\n<p><code>pack&lt;&zwj;&lt;&zwj;5,16&zwj;&gt;&zwj;&gt;(A)<\/code> reshapes <code>A<\/code> from <code>integer^20<\/code> to <code>integer^5^16<\/code><\/p>\n<\/td>\n<\/tr>\n<\/table>\n<ul>\n<li>Overlapping chunks with size 5, shifted by 2.<\/li>\n<\/ul>\n<table>\n<tr>\n<td>\n<p><code>n = 20<\/code>, the size of the stream <\/p>\n<p><code>k = 5<\/code>, the size of chunk<\/p>\n<p><code>s = 2<\/code><\/p>\n<p>Let&#8217;s verify constraint: <code>s = (n - k) \/ (m - 1)<\/code><\/p>\n<p>or : <code>m = (n - k) \/ s + 1<\/code><\/p>\n<p><strong>The result has no integer solution<\/strong>: <code>(m-1)<\/code> does not divide <code>(n-k)<\/code>.<\/p>\n<p>We need to add or crop values to or from the input stream to shift by 2 with pack<\/p>\n<ul>\n<li><code>pack&lt;&zwj;&lt;&zwj;5,9&zwj;&gt;&zwj;&gt;(A @ [A[19]])<\/code><em> <\/em>reshapes A from <code>integer^21<\/code> to <code>integer^5^9<\/code><\/li>\n<\/ul>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-pack-5-9-example-1.svg\" style=\"max-height: 200px !important\" \/><br \/>\n                <em><\/em>\n<\/p>\n<\/td>\n<\/tr>\n<\/table>\n<h3  id=\"USING-PACK-IN-ONE-DIMENSION\">Using pack in one dimension<\/h3>\n<p>A common signal processing need is to apply an operation, such as &#x2297;, &#x2295;, *, or any user <em>algorithm<\/em> between a sliding <em>mask<\/em> and a <em>stream<\/em> values:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-1D-pack-1.svg\" style=\"max-height: 150px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>Step 1, we reshape stream <code>A<\/code> by using <code>pack<\/code>, as explained above, to propose a way to iterate safely with a <code>forward<\/code><em> <\/em>loop. <\/p>\n<p>With <code>N = 20<\/code> and <code>K = 5<\/code><\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-1D-pack-step1a-1.jpg\" style=\"max-height: 400px !important\" \/><br \/>\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-1D-pack-step1b.jpg\" style=\"max-height: 400px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>Step 2, we apply our algorithm on each element of the chunk. Let&#8217;s cumulate the square of the difference between chunk and mask elements:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-1D-pack-step2a.jpg\" style=\"max-height: 400px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>And finally, we fill in our algorithm to compute the difference of squares:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-1D-pack-step2b.jpg\" style=\"max-height: 400px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>The resulting array of this operation is an array of size <code>N-k+1<\/code>.<\/p>\n<p>For consistency, let&#8217;s complete the output array by appending (<code>@<\/code> operator) the end value to retrieve the same input size.<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-1D-pack-step2c-1.jpg\" style=\"max-height: 500px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>The resulting stream is the following. It measures, at each position, the gap between the mask and the input stream. The minimum value corresponds to the best match (least difference). A result of 0 corresponds to the perfect match (no difference).<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-1D-pack-unrolled-1.svg\" style=\"max-height: 500px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>Running a test in our Scade One model, we confirm that the above example finds a perfect match at index 7:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-1D-pack-test-1.jpg\" style=\"max-height: 300px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<h3  id=\"USING-PACK-IN-TWO-DIMENSIONS\">Using pack in two dimensions<\/h3>\n<p>Let&#8217;s go back to our initial problem: detecting shapes in a 2D image. For this, we will use <code>pack<\/code> in two dimensions.<\/p>\n<p>Here, the stream becomes a picture, implemented as a two-dimension matrix of type <code>integer^COL^ROW<\/code><em>.<\/em><\/p>\n<p>The mask is a small square shape, implemented as a two-dimension matrix of type <code>integer^K^K<\/code>.<\/p>\n<p>We must now determine the position of the mask shape in the picture:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-2D-pack-overview-1.png\" style=\"max-height: 400px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>Our aim is to visit all parts of the image with the same size as the mask and apply our algorithm on each one.<\/p>\n<p>The picture has type <code>integer^Col^Row<\/code> and the mask has type <code>integer^K^K<\/code>.<\/p>\n<p>We start by creating a pack of <code>K<\/code> rows, shifted by one row:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-2D-pack-rows-1.svg\" style=\"max-height: 300px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p><code>pack &lt;&zwj;&lt;&zwj;K, Row-K+1&zwj;&gt;&zwj;&gt;(picture)<\/code> \u2192 <code>integer^Col^K^(Row-K+1)<\/code><\/p>\n<p>Then, we iterate on each pack:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow:auto;width:auto;background:none;border:none;padding:.2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\"><span><\/span><span style=\"font-weight: bold\">forward<\/span> &amp;lt;&amp;zwj;&amp;lt;&amp;zwj;Row<span style=\"font-weight: bold\">-<\/span>k<span style=\"font-weight: bold\">+<\/span><span style=\"color: #009999\">1<\/span>&amp;zwj;&amp;gt;&amp;zwj;&amp;gt; <span style=\"font-weight: bold\">with<\/span> [lines] <span style=\"font-weight: bold\">=<\/span> <span style=\"font-weight: bold\">pack<\/span>&amp;lt;&amp;zwj;&amp;lt;&amp;zwj;K,Row<span style=\"font-weight: bold\">-<\/span>K<span style=\"font-weight: bold\">+<\/span><span style=\"color: #009999\">1<\/span>&amp;zwj;&amp;gt;&amp;zwj;&amp;gt;(picture);\r\n<\/pre>\n<\/div>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-2D-pack-rows-forward.svg\" style=\"max-height: 200px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>Now, we want to create a pack of <code>K<\/code> columns from <em>lines \u2192<\/em> <code>integer^Col^K<\/code>:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-2D-pack-cols.svg\" style=\"max-height: 300px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>To iterate on the second dimension Col, we must transpose the dimension: <code>transpose(rows)<\/code><em> \u2192<\/em> <code>integer^K^Col<\/code><\/p>\n<p>When applying pack on <code>transpose(rows)<\/code>:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow:auto;width:auto;background:none;border:none;padding:.2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\"><span><\/span><span style=\"font-weight: bold\">pack<\/span> &amp;lt;&amp;zwj;&amp;lt;&amp;zwj;K, Col<span style=\"font-weight: bold\">-<\/span>K<span style=\"font-weight: bold\">+<\/span><span style=\"color: #009999\">1<\/span>&amp;zwj;&amp;gt;&amp;zwj;&amp;gt;(<span style=\"font-weight: bold\">transpose<\/span>(rows)) \u2192 <span style=\"color: #445588;font-weight: bold\">integer<\/span><span style=\"font-weight: bold\">^<\/span>K<span style=\"font-weight: bold\">^<\/span>K<span style=\"font-weight: bold\">^<\/span>(Col<span style=\"font-weight: bold\">-<\/span>k<span style=\"font-weight: bold\">+<\/span><span style=\"color: #009999\">1<\/span>)\r\n<\/pre>\n<\/div>\n<p>Our final form is:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow:auto;width:auto;background:none;border:none;padding:.2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\"><span><\/span><span style=\"font-weight: bold\">forward<\/span> &amp;lt;&amp;zwj;&amp;lt;&amp;zwj;Col<span style=\"font-weight: bold\">-<\/span>k<span style=\"font-weight: bold\">+<\/span><span style=\"color: #009999\">1<\/span>&amp;zwj;&amp;gt;&amp;zwj;&amp;gt; <span style=\"font-weight: bold\">with<\/span> [subrows] <span style=\"font-weight: bold\">=<\/span> <span style=\"font-weight: bold\">pack<\/span>&amp;lt;&amp;zwj;&amp;lt;&amp;zwj;K,Col<span style=\"font-weight: bold\">-<\/span>K<span style=\"font-weight: bold\">+<\/span><span style=\"color: #009999\">1<\/span>&amp;zwj;&amp;gt;&amp;zwj;&amp;gt;(<span style=\"font-weight: bold\">transpose<\/span>(rows));\r\n<\/pre>\n<\/div>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-2D-pack-cols-forward.svg\" style=\"max-height: 200px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>We are now able to iterate on mask-sized subpictures, computing the difference between our mask and each subpicture.<\/p>\n<p>Notice that here we use a square mask, and the dimensions seem good between the mask and the subpicture. All are matrices of type <em>\u2192<\/em> <code>integer ^K^K<\/code>.<\/p>\n<p>However, due to the previous <code>transpose<\/code> operation, mask dimensions are reversed; we must transpose our subpicture to realign it with the mask:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-2D-pack-reverse-dimensions.svg\" style=\"max-height: 100px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow:auto;width:auto;background:none;border:none;padding:.2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\"><span><\/span><span style=\"font-weight: bold\">forward<\/span>\r\n&amp;lt;&amp;zwj;&amp;lt;&amp;zwj;K&amp;zwj;&amp;gt;&amp;zwj;&amp;gt;\r\n&amp;lt;&amp;zwj;&amp;lt;&amp;zwj;K&amp;zwj;&amp;gt;&amp;zwj;&amp;gt; <span style=\"font-weight: bold\">with<\/span> [[s]]<span style=\"font-weight: bold\">=<\/span>shape; [[elt]]<span style=\"font-weight: bold\">=transpose<\/span>(subrows);\r\n<\/pre>\n<\/div>\n<p>Here is our final operator:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-2D-pack-conv2D-1.jpg\" style=\"max-height: 400px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>The resulting matrix measures, at each position, the difference between the mask and the input picture. The minimum value corresponds to the best match.<\/p>\n<p>A naive approach to find this best match consists in extracting the position of the minimum value, cumulatively measured for each line and column.<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-2D-pack-find-best-match-1.png\" style=\"max-height: 400px !important\" \/><br \/>\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-2D-pack-graphical-panel-1.png\" style=\"max-height: 500px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>Now that our implementation is complete, here is a video of our Scade One model in action, with a graphical panel showing what&#8217;s happening:<\/p>\n<p><p style=\"text-align: center\"><iframe loading=\"lazy\" class=\"vidyard_iframe\" src=\"https:\/\/play.vidyard.com\/32JcqYjbJx8zfv6Ykrv3iM\" width=\"740\" height=\"460\" frameborder=\"0\" allowfullscreen referrerpolicy=\"no-referrer-when-downgrade\"><\/iframe><\/p>\n<\/p>\n<h3  id=\"CONCLUSION\">Conclusion<\/h3>\n<p>In this article, we demonstrated the use of the <code>forward<\/code> and <code>pack<\/code> Swan operators to solve a signal processing problem.<\/p>\n<p>We saw that these operators enable clear, readable signal processing algorithms. By construction, the Swan language enforces safe array access, which allowed us to focus on our logic without worrying about skipping values or out-of-bounds errors.<\/p>\n<h3  id=\"EXPLORE-FURTHER\">Explore Further<\/h3>\n<p>Download the example in this blog <a href=\"https:\/\/ansys13.ansys.com\/KnowledgeArticles\/SCADE\/image_processing.zip\">here<\/a>. If you are a SCADE user, you may access Scade One Essential with your existing licenses on the <a href=\"https:\/\/download.ansys.com\/\">Ansys Download Portal<\/a> and experiment with this example!<\/p>\n<p>Learn more about the forward and pack blocks by visiting the <a href=\"https:\/\/ansyshelp.ansys.com\/public\/account\/secured?returnurl=\/Views\/Secured\/ScadeOne\/v242\/en\/ScadeOne\/techdoc\/concepts_explanations\/language\/language_explanation.html\">Language Explanations<\/a> section of the Scade One User Documentation.<\/p>\n<p>Finally, you may schedule a live demo of Scade One using this <a href=\"https:\/\/www.ansys.com\/products\/embedded-software\/request-assessment-scade-one\">link<\/a>.<\/p>\n<h3  id=\"ABOUT-THE-AUTHOR\">About the author<\/h3>\n<table style=\"border: none !important\">\n<tr>\n<td style=\"border: none !important\">\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/01\/scade-027-author-1.png\" style=\"max-height: 150px !important\" \/>\n        <\/td>\n<td style=\"border: none !important\">\n<p>Mathieu Viala (<a href=\"https:\/\/www.linkedin.com\/in\/mathieu-viala-373798115\/\">LinkedIn<\/a>) is a lead Application Engineer at Ansys. He has been supporting SCADE customers in early development phases, managing PoCs, training and post-sales support for more than 16 years.<\/p>\n<\/td>\n<\/tr>\n<\/table>\n","protected":false},"template":"","class_list":["post-195908","topic","type-topic","status-publish","hentry","topic-tag-2d","topic-tag-forward","topic-tag-image-processing","topic-tag-pack","topic-tag-scade-one","topic-tag-signal-processing"],"aioseo_notices":[],"acf":[],"custom_fields":[{"0":{"_edit_lock":["1764169014:1769"],"_edit_last":["1769"],"_aioseo_title":[null],"_aioseo_description":[null],"_aioseo_keywords":["a:0:{}"],"_aioseo_og_title":[null],"_aioseo_og_description":[null],"_aioseo_og_article_section":[""],"_aioseo_og_article_tags":["a:0:{}"],"_aioseo_twitter_title":[null],"_aioseo_twitter_description":[null],"filter_by_optics_product":["Lumerical"],"_filter_by_optics_product":["field_64fb192ba3121"],"application_name":[""],"_application_name":["field_64a80903c8e15"],"family":[""],"_family":["field_64a809229a857"],"siebel_km_number":[""],"_siebel_km_number":["field_63ecbffce60db"],"salesforce_km_number":[""],"_salesforce_km_number":["field_63ecc018e60dc"],"km_published_date":[""],"_km_published_date":["field_64c77704499dd"],"product_version":[""],"_product_version":["field_64c776cb4fd2e"],"_bbp_forum_id":["27825"],"_bbp_topic_id":["197675"],"_bbp_author_ip":["176.143.247.201"],"_bbp_last_reply_id":["0"],"_bbp_last_active_id":["195909"],"_bbp_last_active_time":["2025-01-13 08:52:43"],"_bbp_reply_count":["0"],"_bbp_reply_count_hidden":["0"],"_bbp_voice_count":["0"],"_btv_view_count":["821"],"_bbp_likes_count":["6"]},"test":"solution"}],"_links":{"self":[{"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/topics\/195908","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/topics"}],"about":[{"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/types\/topic"}],"version-history":[{"count":25,"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/topics\/195908\/revisions"}],"predecessor-version":[{"id":197675,"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/topics\/195908\/revisions\/197675"}],"wp:attachment":[{"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/media?parent=195908"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}