Skip to content

Commit

Permalink
Implement built-in function diagonal in Cpp runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
rfranke authored and sjoelund committed Jun 28, 2021
1 parent 93240f5 commit dc65eb9
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 7 deletions.
6 changes: 6 additions & 0 deletions OMCompiler/Compiler/Template/CodegenCppCommon.tpl
Expand Up @@ -2062,6 +2062,12 @@ template daeExpCall(Exp call, Context context, Text &preExp /*BUFP*/, Text &varD
let &preExp += 'identity_alloc(<%var1%>, <%tvar%>);<%\n%>'
'<%tvar%>'

case CALL(path=IDENT(name="diagonal"), expLst={v}, attr=CALL_ATTR(ty=ty as T_ARRAY(ty=elty))) then
let var1 = daeExp(v, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let tvar = tempDecl('DynArrayDim2<<%expTypeShort(elty)%>>', &varDecls)
let &preExp += 'diagonal_alloc(<%var1%>, <%tvar%>);<%\n%>'
'<%tvar%>'

case CALL(path=IDENT(name="rem"), expLst={e1, e2}) then
let var1 = daeExp(e1, context, &preExp, &varDecls,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let var2 = daeExp(e2, context, &preExp, &varDecls,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
Expand Down
23 changes: 23 additions & 0 deletions OMCompiler/SimulationRuntime/cpp/Core/Math/ArrayOperations.cpp
Expand Up @@ -219,6 +219,24 @@ void identity_alloc(size_t n, DynArrayDim2<int>& I)
I(i, i) = 1;
}

template <typename T>
void diagonal_alloc(const BaseArray<T>& v, BaseArray<T>& D)
{
if (v.getNumDims() != 1)
throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, "Error in diagonal, input must be vector");
if (D.getNumDims() != 2)
throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, "Error in diagonal, output must be matrix");
vector<size_t> dims = v.getDims();
size_t n = dims[0];
dims.push_back(n);
D.setDims(dims);
const T* v_data = v.getData();
T* D_data = D.getData();
std::fill(D_data, D_data + n * n, 0);
for (size_t i = 0; i < n; i++)
D_data[i * n + i] = v_data[i];
}

//template < typename T , size_t NumDims, size_t NumDims2 >
template <typename T>
void promote_array(size_t n, const BaseArray<T>& s, BaseArray<T>& d)
Expand Down Expand Up @@ -602,6 +620,11 @@ transpose_array(const BaseArray<int>& x, BaseArray<int>& a);
template void BOOST_EXTENSION_EXPORT_DECL
transpose_array(const BaseArray<bool>& x, BaseArray<bool>& a);

template void BOOST_EXTENSION_EXPORT_DECL
diagonal_alloc(const BaseArray<double>& v, BaseArray<double>& D);
template void BOOST_EXTENSION_EXPORT_DECL
diagonal_alloc(const BaseArray<int>& v, BaseArray<int>& D);

template void BOOST_EXTENSION_EXPORT_DECL
promote_array(size_t n, const BaseArray<double>& s, BaseArray<double>& d);
template void BOOST_EXTENSION_EXPORT_DECL
Expand Down
Expand Up @@ -51,6 +51,9 @@ void fill_array_from_shape(const spec_type& sp,BaseArray<T>& s,BaseArray<T>& d);

void BOOST_EXTENSION_EXPORT_DECL identity_alloc(size_t n, DynArrayDim2<int>& I);

template <typename T>
void diagonal_alloc(const BaseArray<T>& v, BaseArray<T>& D);

template <typename T>
void promote_array(size_t n, const BaseArray<T>& s, BaseArray<T>& d);

Expand Down
32 changes: 25 additions & 7 deletions testsuite/openmodelica/cppruntime/arrayOperationsTest.mos
Expand Up @@ -10,27 +10,35 @@ loadString("
package ArrayOperations
model Test
input Real u = 0;
Real y = f({u + 1, u + 2, u + 3});
Real[2] z = g(u);
Real y = f1({u + 1, u + 2, u + 3});
Real[2] z = f2(u);
Real[2,2] D = f3(z);
annotation(experiment(StopTime = 0));
end Test;
// see Modelica.Mechanics.MultiBody.Examples.Rotational3DEffects.MovingActuatedDrive
function f
function f1
input Real[:] v;
output Real y;
protected
Real[:,:] m;
algorithm
m := matrix(v) * transpose(matrix(v));
y := m[3,1];
end f;
end f1;
// see Modelica.Media.Examples.ReferenceAir.MoistAir
function g
function f2
input Real u;
output Real[:] y; // unknown dimension
algorithm
y := {u, u + 1};
end g;
y := {u + 1, u + 2};
end f2;
// built-in diagonal
function f3
input Real[:] v;
output Real[size(v, 1), size(v, 1)] D;
algorithm
D := diagonal(v);
end f3;
end ArrayOperations;
");
getErrorString();
Expand All @@ -39,7 +47,12 @@ simulate(ArrayOperations.Test);
getErrorString();

val(y, 0);
val(z[1], 0);
val(z[2], 0);
val(D[1,1], 0);
val(D[1,2], 0);
val(D[2,1], 0);
val(D[2,2], 0);

// Result:
// true
Expand All @@ -53,4 +66,9 @@ val(z[2], 0);
// ""
// 3.0
// 1.0
// 2.0
// 1.0
// 0.0
// 0.0
// 2.0
// endResult

0 comments on commit dc65eb9

Please sign in to comment.