#4055 closed defect (wontfix)
Wrong code generation template for complex numbers in algorithms
Reported by: | massimo ceraolo | Owned by: | Mahder Alemseged Gebremedhin |
---|---|---|---|
Priority: | critical | Milestone: | 1.14.0 |
Component: | Code Generation | Version: | |
Keywords: | Cc: |
Description (last modified by )
The following simple model compiles but does not run:
model ComplexTest parameter Integer n = 3; Complex Z[n]; constant Complex j = Complex(0.0, 1.0); algorithm for i in 1:n loop Z[i] := 1.0 + j; end for; end ComplexTest;
Here's the error message:
ComplexIssue.Test.c: In function 'ComplexIssue_Test_eqFunction_2':
ComplexIssue.Test.c:143:7: warning: implicit declaration of function '$PZ$lB' [-Wimplicit-function-declaration]
$PZ$lB(modelica_integer)$Pi$rB$Pre = tmp1._re;
ComplexIssue.Test.c:143:14: error: expected expression before 'modelica_integer'
$PZ$lB(modelica_integer)$Pi$rB$Pre = tmp1._re;
ComplexIssue.Test.c:143:31: error: expected ';' before '$Pi$rB$Pre'
$PZ$lB(modelica_integer)$Pi$rB$Pre = tmp1._re;
ComplexIssue.Test.c:144:14: error: expected expression before 'modelica_integer'
$PZ$lB(modelica_integer)$Pi$rB$Pim = tmp1._im;
ComplexIssue.Test.c:144:31: error: expected ';' before '$Pi$rB$Pim'
$PZ$lB(modelica_integer)$Pi$rB$Pim = tmp1._im;
Tested with OpenModelica v1.11.0-dev-16-g6312752
Change History (18)
comment:1 by , 8 years ago
Description: | modified (diff) |
---|
comment:3 by , 8 years ago
ehm...
may I ask if someone plans to have a look at this ticket in the following weeks?
Just to know whether there is some chance of having it addressed in the near future.
Thanks!
follow-ups: 6 9 comment:5 by , 8 years ago
The model ComplexFillEqs
works, because the equation is evaluated within the backend.
comment:6 by , 8 years ago
comment:7 by , 8 years ago
@ceraolo: this is a problem in the code generation template handling assignment of indexed array of complex or record on left hand side in an assignment.
comment:8 by , 8 years ago
Just a small addition.
I did not open this ticket just to demonstrate an issue but because it arose from a real-life case.
In that case I needed to simulate an high-speed train line, which was fed in AC (as normally happens), using matrices describing the electromagnetic interaction of the 14 conductors involved. Before the actual beginning of simulation I need to compute these matrices from track geometry.
Maybe this is just an example of a general situation: whenever we want to simulate power systems using impedance models, in an automatic way, we might to have the need of some pre-processing in which we create and manipulate complex matrices.
follow-up: 10 comment:9 by , 8 years ago
Replying to lochel:
The model
ComplexFillEqs
works, because the equation is evaluated within the backend.
Will the new front end be able to address this ticket? Thanks.
comment:10 by , 8 years ago
Replying to ceraolo:
Will the new front end be able to address this ticket? Thanks.
No, I don't think so. This need to be fixed within code generation. We should give this one a higher priority.
comment:11 by , 8 years ago
Milestone: | 1.11.0 → 1.12.0 |
---|
Milestone moved to 1.12.0 due to 1.11.0 already being released.
comment:12 by , 8 years ago
Owner: | changed from | to
---|---|
Status: | new → accepted |
comment:13 by , 7 years ago
Another version that does not work:
model ComplexTest parameter Integer n = 3; Complex Z[n]; algorithm for i in 1:n loop Z[i] := Complex(1.0,1.0); end for; end ComplexTest;
comment:14 by , 7 years ago
Summary: | A problem with complex numbers → Wrong code generation template for complex numbers in algorithms |
---|
comment:15 by , 7 years ago
Milestone: | 1.12.0 → 1.13.0 |
---|
comment:17 by , 6 years ago
Resolution: | → wontfix |
---|---|
Status: | accepted → closed |
@ceraolo, some comments on this old ticket.
In section 11.1.2 of the Modelica Specification, you can read:
An algorithm section is treated as an atomic vector-equation, which is sorted together with all other equations. For the sorting process (BLT), every algorithm section with N different left-hand side variables, is treated as an atomic N-dimensional vector-equation containing all variables appearing in the algorithm section. an algorithm section is used directly in a model, it is interpreted to compute a set of left-hand-side variables. This guarantees that all N equations end up in an algebraic loop and the statements of the algorithm section remain together.
The rationale of this rule is that, in general, your algorithm may introduce arbitrary dependencies between the variables, which cannot be analyzed by the backend in general - I guess this can be proven to be an undecidable problem, for a generic algorithm.
This means that your nice sequence of independent explicit assignments unnecessarily ends up in nonlinear algebraic equation containing records, that the backend currently cannot handle.
We may support implicit nonlinear record equations in the backend in the future, but in fact this is not really the way you want to solve your problem.
There is a simple way to avoid this issue: put the algorithm in a function, and then put the function call in an equation section. In this case, the causality is well-defined, because your function does not depend on any variable, and the causality analysis of the equation is trivial: each element of Z depends on one output of the function.
model ImplicitRecordTest parameter Integer n = 3; Complex Z[n]; function compute_Z input Integer n; output Complex Z[n]; algorithm for i in 1:n loop Z[i] := Complex(1.0,1.0); end for; end compute_Z; equation Z = compute_Z(n=3); end ImplicitRecordTest;
This already works both with the old and new front-end.
As a general rule, I would only use algorithms in models for when clauses. In all other cases, encapsulating the algorithm in a function is usually a good practice. IMHO, it also makes the model better understood, I find algorithms in models fishy, unless they involve discrete variables.
comment:18 by , 6 years ago
As a general rule, I would only use algorithms in models for when clauses. In all other cases, encapsulating the algorithm in a function is usually a good practice. IMHO, it also makes the model better understood, I find algorithms in models fishy, unless they involve discrete variables.
I rarely use algorithms outside functions. I built this piece of code after having tried several other methods to construct an array of Complex numbers, and having found several barriers in OM. Check for instance ticket #4611, which has an approach similar to the snippet in Comment:17, but does not work.
I did read in the specification that
every algorithm section with N different left-hand side variables, is treated as an atomic N-dimensional vector-equation containing all variables appearing in the algorithm section
and this for me justified to try this ticket's approach. I also checked with Dymola and my snippet is fine there.
At least you did find a working way to construct an array of Complex's, that overcomes the difficulties here and in #4611!
At least there is a problem related to the use of complex numbers in algorithms.
the following code works:
the following does not:
Unfortunately I need to manipulate complex matrices inside functions, and therefore I need algorithm sections.
Other people might have the same need.