Opened 9 years ago

Closed 9 years ago

Last modified 7 years ago

#3765 closed defect (fixed)

Bad macro for semiLinear

Reported by: crupp@… Owned by: somebody
Priority: blocker Milestone: 1.11.0
Component: Run-time Version: v1.10.0-dev-nightly
Keywords: Cc: rfranke, niklwors

Description

In openmodelica.h the macro for semiLinear is defined as:
#define semiLinear(x,positiveSlope,negativeSlope) (x>=0?positiveSlope*x:negativeSlope*x)

If x is an expression such as x=-1+a/b then the macro evaluates it incorrectly.

It should be:
#define semiLinear(x,positiveSlope,negativeSlope) (x>=0?positiveSlope*(x):negativeSlope*(x))

The added parentheses fix the issue. I've attached a test case that illustrates the issue. In this test the expression is transformed into semiLinear(-1+d/L,k,0).

It turns out that this is a long-standing issue since it was implemented (2010). Maybe it will magically fix some test cases.

Attachments (1)

semiLinear_bug.mo (214 bytes) - added by crupp@… 9 years ago.

Download all attachments as: .zip

Change History (13)

Changed 9 years ago by crupp@…

comment:1 Changed 9 years ago by vitalij

Thank you for the analysis!

comment:2 Changed 9 years ago by vitalij

your fixes was added with PR528

comment:3 Changed 9 years ago by vitalij

  • Resolution set to fixed
  • Status changed from new to closed

comment:4 Changed 9 years ago by crupp@…

  • Resolution fixed deleted
  • Status changed from closed to reopened

Looks like I was sloppy. The cpp version also needs it in:
OMCompiler/SimulationRuntime/cpp/Include/Core/Math/Functions.h

comment:5 Changed 9 years ago by adrpo

  • Cc rfranke niklwors added

Added rfranke and niklwors to CC for the CPP runtime.

comment:6 Changed 9 years ago by crupp@…

Also, vitalij was smart and caught the error in my fix, it should be:
#define semiLinear(x,positiveSlope,negativeSlope) (x>=0?(positiveSlope)*(x):(negativeSlope)*(x))

Is there any reason that the conditional x>=0 should be (x)>=0? The only reason I can think of is if there was some sort of bitwise operator. I don't know how that would get there, but it may be better to be safe than sorry.

comment:7 follow-up: Changed 9 years ago by sjoelund.se

I think I would have preferred to make it a static inline function, or just inline it in the code generator for the simple reason that x is present in multiple places and could in some instances cause unexpected behaviour.

comment:8 Changed 9 years ago by rfranke

@crupp: can you be a bit more specific what you mean with "Looks like I was sloppy. The cpp version also needs it in: OMCompiler/SimulationRuntime/cpp/Include/Core/Math/Functions.h"?

The inline function should be ok:

inline static double semiLinear(double x,double positiveSlope,double negativeSlope)
{
 if(x>=0)
    return positiveSlope*x;
 else
    return negativeSlope*x;
}

comment:9 Changed 9 years ago by crupp@…

Having not used them much in the past, I was assuming that inlined functions are treated similarly to macros in that it mixes the operations. After reading into it, it looks like I'm wrong and that it still behaves like a function. So, I retract my statement. Sorry for the trouble.

comment:10 in reply to: ↑ 7 Changed 9 years ago by vitalij

Replying to sjoelund.se:

I think I would have preferred to make it a static inline function, or just inline it in the code generator for the simple reason that x is present in multiple places and could in some instances cause unexpected behaviour.

I like the idea with inline function. PR 533

principally it work for DIVSION_SIM PR 534, too??

comment:11 Changed 9 years ago by vitalij

  • Resolution set to fixed
  • Status changed from reopened to closed

comment:12 Changed 7 years ago by sjoelund.se

  • Milestone changed from Future to 1.11.0
Note: See TracTickets for help on using tickets.