Opened 7 years ago

Last modified 7 years ago

#4890 new defect

strange power — at Version 2

Reported by: Vitalij Ruge Owned by: somebody
Priority: high Milestone: Future
Component: Backend Version:
Keywords: Cc: Francesco Casella, Willi Braun

Description (last modified by Vitalij Ruge)

the following simple model create for simple power operation

model pow_test
 Real x = time^(1/3);
end pow_test;  

about 60 lines C-Code:

/*
 equation index: 2
 type: SIMPLE_ASSIGN
 x = time ^ 0.3333333333333333
 */
void pow_test_eqFunction_2(DATA *data, threadData_t *threadData)
{
  TRACE_PUSH
  const int equationIndexes[2] = {1,2};
  modelica_real tmp0;
  modelica_real tmp1;
  modelica_real tmp2;
  modelica_real tmp3;
  modelica_real tmp4;
  modelica_real tmp5;
  modelica_real tmp6;
  tmp0 = data->localData[0]->timeValue;
  tmp1 = 0.3333333333333333;
  if(tmp0 < 0.0 && tmp1 != 0.0)
  {
    tmp3 = modf(tmp1, &tmp4);
    
    if(tmp3 > 0.5)
    {
      tmp3 -= 1.0;
      tmp4 += 1.0;
    }
    else if(tmp3 < -0.5)
    {
      tmp3 += 1.0;
      tmp4 -= 1.0;
    }
    
    if(fabs(tmp3) < 1e-10)
      tmp2 = pow(tmp0, tmp4);
    else
    {
      tmp6 = modf(1.0/tmp1, &tmp5);
      if(tmp6 > 0.5)
      {
        tmp6 -= 1.0;
        tmp5 += 1.0;
      }
      else if(tmp6 < -0.5)
      {
        tmp6 += 1.0;
        tmp5 -= 1.0;
      }
      if(fabs(tmp6) < 1e-10 && ((unsigned long)tmp5 & 1))
      {
        tmp2 = -pow(-tmp0, tmp3)*pow(tmp0, tmp4);
      }
      else
      {
        throwStreamPrint(threadData, "%s:%d: Invalid root: (%g)^(%g)", __FILE__, __LINE__, tmp0, tmp1);
      }
    }
  }
  else
  {
    tmp2 = pow(tmp0, tmp1);
  }
  if(isnan(tmp2) || isinf(tmp2))
  {
    throwStreamPrint(threadData, "%s:%d: Invalid root: (%g)^(%g)", __FILE__, __LINE__, tmp0, tmp1);
  }
  data->localData[0]->realVars[0] /* x variable */ = tmp2;
  TRACE_POP
}

Line: https://github.com/OpenModelica/OMCompiler/blob/master/Compiler/Template/CodegenCFunctions.tpl#L4938

related commits:
https://github.com/OpenModelica/OMCompiler/commit/63d57dd2ca84c3e72641edba77fde0494bc56b73

https://github.com/OpenModelica/OMCompiler/commit/cb732fc280ac2d8940713d8a104c18952a0634da

Change History (2)

comment:1 by Francesco Casella, 7 years ago

I guess that is kind of necessary if p is a parameter that is amenable to be changed at runtime. I guess the whole thing should be much leaner if you had either

constant Real p = 1;

or

final Real p = 1;

or

parameter Real p = 1 annotation(Evaluate=true);

so that p can be constant evaluated and time^p replaced with time.

Have you tried those out?

comment:2 by Vitalij Ruge, 7 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.