Tuple Operationsπ
Operations are usually described assuming atomic tuples. If the tuple contains more than one element, most operators work as follows:
-
If one of the tuples is of length 1, all elements of the other tuples are combined with that single value for the chosen operation.
-
If both tuples have a length greater than 1, both tuples must have the same length, otherwise a runtime error occurs. In this case, the selected operation is applied to all elements with the same index. The length of the resulting tuples is identical to the length of the input tuples.
-
If one of the tuples is of length 0 (
[]
), a runtime error occurs.
In Table 1, you can find some examples for arithmetic operations with tuples.
Pay special attention to the order in which the string concatenations are performed.
The basic arithmetic operations in HDevelopEVO are +
, -
, *
, /
.
Note that +
is a dimorphic operation:
If both operands are numeric, it adds numbers.
If at least one of the operands is a string
, it concatenates both operands as strings.
Input | Result |
---|---|
5 * 5`` |
25 |
[5] * [5] |
25 |
[1,2,3] * 2 |
[2,4,6] |
[1,2,3] * 2.1 + 10 |
[12.1,14.2,16.3] |
[1,2,3] * [1,2,3] |
[1,4,9] |
[1,2,3] * [1,2] |
runtime error |
'Text1' + 'Text2' |
'Text1Text2' |
17 + '3' |
'173' |
'Text ' + 3.1 * 2 |
'Text 6.2' |
3.1 * (2 + ' Text') |
runtime error |
3.1 + 2 + ' Text' |
'5.1 Text' |
3.1 + (2 + ' Text') |
'3.12 Text' |
Conventions
In all following tables, variables and constants have been substituted by letters, which indicate allowed data types. These letters provide information about possible limitations of the areas of definition. The letters and their meaning are listed in Table 2. Operations on these symbols can only be applied to parameters of the indicated type or to expressions that return a result of the indicated type.
Symbol | Types |
---|---|
i |
integer |
a |
arithmetic, that is: integer or real |
b |
boolean |
s |
string |
v |
all types (atomic) |
t |
all types (tuple) |
The symbol names i
, a
, b
, and s
can denote atomic tuples (tuples of length 1) as well as tuples with arbitrary length.
Assignmentπ
In HDevelopEVO, an assignment is treated like an operator.
To use an assignment, you can either type it directly into the program window or use the operator assign
(Input, Result)
.
In the program text, the assignment is represented by the usual syntax of the assignment operator:
Result := Input
The following example outlines the difference between an assignment in C syntax and its transformed version in HDevelopEVO:
The assignment in C syntax:
Can be directly typed in the program window as:
u := sin(x) + cos(y)
Another possibility would be to use the assignment operator:
assign (sin(x) + cos(y), u)
If the result of the expression does not need to be stored in a variable, the expression can directly be used as input value for any operator, or be typed into the program window. Therefore, an assignment is necessary only if the value has to be used several times or if the variable has to be initialized, for example for a loop.
Modifying tuple elementsπ
Inside the program window, enter the following to change the an element of a tuple:
Result[Index] := Value
Another possibility would be to use the assignment operator assign_at
:
assign_at (Index, Value, Result)
Example
Areas := [1,2,3]
Areas[1] := 9
sets Areas
to [1,9,3]
.
To construct a tuple with assign_at
, usually an empty tuple is used as initial value and the elements are inserted in a loop:
Tuple :=
for i := 0 to 5 by 1
Tuple[i] := sqrt(real(i))
endfor
As you can see from the examples, the indices of a tuple start at 0.
An insertion into a tuple can generally be performed in one of the following ways:
-
In case of appending the value at the βbackβ or at the βfrontβ, the tuple concatenation operation β,β (comma) can be used. Here, the operator
assign
is used with the following parameters:assign ([Tuple,NewVal],Tuple)
which is displayed as
Tuple := [Tuple,NewVal]
-
If the index position is somewhere in between, the operator
tuple_insert
has to be used.To insert the tuple
[11,12,13]
into the tuple[1,2,3]
at position 1, usetuple_insert ([1,2,3], 1, [11,12,13], Result)
or as in-line operation
Result := insert([1,2,3], 1, [11,12,13])
resulting in
[1,11,12,13,2,3]
.
In the following example, regions are dilated with a circle mask and afterwards, the areas are stored into the tuple Areas
.
In this case, the operator assign_at
is used.
Example
read_image (Mreut, 'mreut')
threshold (Mreut, Region, 190, 255)
Areas :=
for Radius := 1 to 50 by 1
dilation_circle (Region, RegionDilation, Radius)
area_center (RegionDilation, Area, Row, Column)
Areas[Radius-1] := Area
endfor
At first, the variable Areas
has to be initialized to avoid a runtime error.
In the example, Areas
is initialized with the empty tuple ([]
).
Instead of assign_at
, the operator assign
with tuple concatenation could be used, because the element is appended at the end of the tuple:
Areas := [Areas,Area]
More examples can be found in the program assign.hdev
.
Basic Tuple Operationsπ
A basic tuple operation can be selecting one or more values, combining tuples (concatenation), or getting the number of elements. See Table 3 for operations on tuples containing control data.
Operation | Meaning | HALCON operator |
---|---|---|
t := [t1,t2] |
concatenate tuples | tuple_concat |
i := \|t\| |
get number of elements of tuple t |
tuple_length |
v := t1[t2] |
select element t2 of tuple t1 |
tuple_select |
t := t1[t2,t3] |
select elements t2 and t3 of tuple t1 |
tuple_select |
t := t[i1:i2] |
select from element i1 to element i2 of tuple t |
tuple_select_range |
t := subset(t1,t2) |
select elements specified in t2 from t1 |
tuple_select |
t := firstn(t,i) |
select first elements from t up to index i |
tuple_first_n |
t := lastn(t,i) |
select elements from t from index i to the end |
tuple_last_n |
t := select_mask(t1,t2) |
select all elements from t1 where the corresponding mask value in t2 is greater than 0 |
tuple_select_mask |
t := remove(t,i) |
remove elements specified in i from t |
tuple_remove |
t := insert(t1,i,t2) |
insert elements from t2 at position i in t1 |
tuple_insert |
i := find(t1,t2) |
get indices of all occurrences of t2 within t1 (or -1 if no match) |
tuple_find |
i := replace(t1,t2,t3) |
replace elements | tuple_replace |
i := find_first(t1,t2) |
get indices of the first occurrences of t2 within t1 (or -1 if no match) |
tuple_find_first |
i := find_last(t1,t2) |
get indices of the last occurrences of t2 within t1 (or -1 if no match) |
tuple_find_last |
t := uniq(t) |
discard all but one of successive identical elements from t |
tuple_uniq |
t := [i1:i2:i3] |
generate a sequence of values from i1 to i3 with an increment value of i2 |
tuple_gen_sequence |
t := [i1:i2] |
generate a sequence of values from i1 to i2 with an increment value of one |
tuple_gen_sequence |
t := gen_tuple_const(i,t) |
generate a tuple with i values set to t |
tuple_gen_const |
t := rep(t,i) |
repeat t i times |
tuple_repeat |
t := rep_elem(t,i) |
repeat t i times elementwise |
tuple_repeat_elem |
The concatenation accepts one or more variables or constants as input.
They are all listed between the brackets, separated by commas.
The result again is a tuple.
Note the following: [[t]] = [t] = t
.
Number of Elements and Indexesπ
|t|
returns the number of elements of a tuple.
The indices of elements range from zero to the number of elements minus one (|t|-1
).
Therefore, the selection index has to be within this range.1
Tuple := [V1,V2,V3,V4]
for i := 0 to |Tuple|-1 by 1
fwrite_string (FileHandle,Tuple[i]+'\n')
endfor
Example
In the following, the variable Var
contains [2,4,8,16,16,32]
:
Input | Result |
---|---|
[1,Var,[64,128]] |
[1,2,4,8,16,16,32,64,128] |
| Var| |
6 |
Var[4] |
16 |
Var[4,5] |
[16,32] |
Var[2:4] |
[8,16,16] |
subset(Var,[0,2,4]) |
[2,8,16] |
select_mask(Var,[1,0,0,1,1,1]) |
[2,16,16,32] |
remove(Var,[2,3]) |
[2,4,16,32] |
find(Var,[8,16]) |
2 |
uniq(Var) |
[2,4,8,16,32] |
Other examples can be found in the program tuple.hdev
.
The HALCON operators that correspond to the basic tuple operations are listed in Table 3.
Tuple Operations for Iconic Dataπ
The direct operations mentioned in the previous section cannot be used for iconic tuples.
Iconic objects cannot be selected from a tuple using []
and their number cannot be directly determined using ||
.
For iconic data, equivalent HALCON operators exist.
In Table 4, you can see tuple operations that work on control data (applied via assign
or assign_at
) and their counterparts that work on iconic data (which are independent operators).
The symbol t
represents a control tuple, and the symbols p
and q
represent iconic tuples.
control | iconic |
---|---|
[] |
gen_empty_obj () |
[t1,t2] |
concat_obj (p1, p2, q) |
| t | |
count_obj (p, num) |
t[i] |
select_obj (p, q, i+1) |
t[i1:i2] |
copy_obj (p, q, i1+1, i2-i1+1) |
Tuple Creationπ
The simplest way to create a tuple, as mentioned in Control Types and Constants, is the use of constants together with the operator assign
(or, in case of iconic data, one of its equivalents shown in Table 4):
assign (,empty_tuple)
assign (4711,one_integer)
assign ([4711,0.815],two_numbers)
This code is displayed as
empty_tuple :=
one_integer := 4711
two_numbers := [4711,0.815]
This is useful for constant tuples with a fixed (small) length. More general tuples can be created by successive application of the concatenation or the operator together with variables, expressions, or constants. If you want to generate a tuple of length 100, where each element has the value 4711, it can be done like this:
tuple :=
for i := 1 to 100 by 1
tuple := [tuple,4711]
endfor
Because this is not very convenient, a special function called gen_tuple_const
is available to construct a tuple of a given length, where each element has the same value.
Using this function, the program from above is reduced to:
tuple := gen_tuple_const(100,4711)
A fast way to create a sequence of values with a common increment is to use tuple_gen_sequence
.
For example, to create a tuple containing the values 1..1000, use
tuple_gen_sequence(1,1000,1,Sequence)
An alternative syntax to the above is to write:
Sequence := [1:1:1000]
If the increment value is one (as in the above example), it is also possible to write:
Sequence := [1:1000]
If we want to construct a tuple with the same length as a given tuple, there are two ways to get an easy solution.
The first one is based on gen_tuple_const
:
tuple_new := gen_tuple_const(|tuple_old|,4711)
The second one is trickier and uses arithmetic functions:
tuple_new := (tuple_old * 0) + 4711
Here, we first get a tuple of the same length with every element set to zero. Then, we add the constant to each element.
If the tuples have different values, we have to use the loop version to assign the values to each position:
tuple :=
for i := 1 to 100 by 1
tuple := [tuple,i*i]
endfor
In this example, we construct a tuple with the square values of \(i\) from \(1^2\) to \(100^2\).
-
In contrast, the index of objects, for example,
select_obj
, ranges from 1 to the number of elements.Β β©