Skip to content

Commit

Permalink
More work on array arithmetic.
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@733 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
ankar committed Feb 13, 2002
1 parent 79809df commit 3d5d12d
Show file tree
Hide file tree
Showing 4 changed files with 249 additions and 31 deletions.
2 changes: 1 addition & 1 deletion mosh/src/Makefile
Expand Up @@ -83,4 +83,4 @@ reallyclean: clean

mosh.o : mosh.cpp ../../modelica_parser/src/modelica_lexer.hpp ../../modelica_parser/src/modelica_parser.hpp

include Makefile.depend
#include Makefile.depend
113 changes: 111 additions & 2 deletions mosh/src/runtime/numerical_array.hpp
Expand Up @@ -36,6 +36,16 @@ class numerical_array : public modelica_array<Tp>

numerical_array<Tp> operator- () const;

numerical_array<Tp>& operator*= (const numerical_array<Tp>& arr);

//numerical_array<Tp> operator* (const numerical_array<Tp>& arr) const;
numerical_array<Tp> operator* (const numerical_array<Tp>& arr) const;
numerical_array<Tp>& operator*= (const Tp& s);
numerical_array<Tp> operator* (const Tp& s);

friend Tp mul_vector_vector<Tp>(const numerical_array<Tp>& v1,const numerical_array<Tp>& v2);
friend numerical_array<Tp> mul_vector_matrix<Tp>(const numerical_array<Tp>& v1, const numerical_array<Tp>& v2);

numerical_array() {};
numerical_array(std::vector<int> dims) : modelica_array<Tp>(dims) {};
numerical_array(std::vector<int> dims,std::vector<Tp> scalars) : modelica_array<Tp>(dims,scalars) {};
Expand Down Expand Up @@ -141,8 +151,107 @@ numerical_array<Tp> numerical_array<Tp>::operator- () const
return tmp;
}

// typedef numerical_array<double> real_array;
// typedef numerical_array<int> integer_array;
template<typename Tp>
numerical_array<Tp> numerical_array<Tp>::operator* (const numerical_array<Tp>& arr) const
{
assert(ndims() == 2);
assert(arr.ndims() ==2);
assert(m_dim_size[1] == arr.m_dim_size[0]);

int i_size = m_dim_size[0];
int j_size = m_dim_size[1];
int k_size = arr.m_dim_size[1];

std::vector<int> result_dims;
result_dims.push_back(i_size);
result_dims.push_back(k_size);

numerical_array<Tp> result(result_dims);
for (int i = 0; i < i_size; ++i)
{
for (int j = 0; j < j_size; ++j)
{
Tp tmp = static_cast<Tp>(0);
for (int k = 0; k < k_size; ++k)
{
tmp += m_data[i*k_size+k]*arr.m_data[k*j_size+j];
}
result.m_data[i*j_size+j] = tmp;
}
}
return result;
}

template<typename Tp>
Tp mul_vector_vector(const numerical_array<Tp>& v1,const numerical_array<Tp>& v2)
{
assert(v1.ndims() == 1);
assert(v2.ndims() == 1);
assert(v1.m_dim_size[0] == v2.m_dim_size[0]);

return std::inner_product(v1.m_data.begin(),v1.m_data.end(),v2.m_data.begin(),static_cast<Tp>(0));
}

template<typename Tp>
numerical_array<Tp> mul_vector_matrix(const numerical_array<Tp>& v1, const numerical_array<Tp>& v2)
{
assert(v1.ndims() == 1);
assert(v2.ndims() == 2);
assert(v1.m_dim_size[0] == v2.m_dim_size[0]);

std::vector<Tp>::const_iterator it = v2.m_data.begin();

numerical_array<Tp> result(std::vector<int>(1,v2.m_dim_size[1]));
for (; it != v2.m_data.end();++it)
{
Tp element = std::inner_product(v1.m_data.begin(),v1.m_data.end(),it,static_cast<Tp>(0));
result.m_data.push_back(element);
}

assert(result.m_data.size() == v2.m_dim_size[1]);
return result;
}

// template<typename Tp>
// numerical_array<Tp>& numerical_array<Tp>::operator*= (const numerical_array<Tp>& arr)
// {

// if ( (m_dims_size.size() == 1 ) && (arr.m_dim_size.size() == 1))
// {
// if (m_dims_size[0] == val.m_dim_size[0])
// {
// std::inner_product(m_data.begin(),m_data.end(),arr.m_data.begin(),0);
// }
// else
// {
// throw modelica_runtime_error("Incompatible vector dimensions\n");
// }
// }
// for (size_t i = 0; i < m_data.size(); ++i)
// {
// m_data[i] *= s;
// }
// return *this;
// }

template<typename Tp>
numerical_array<Tp>& numerical_array<Tp>::operator*= (const Tp& s)
{
for (size_t i = 0; i < m_data.size(); ++i)
{
m_data[i] *= s;
}
return *this;
}

template<typename Tp>
numerical_array<Tp> numerical_array<Tp>::operator * (const Tp& s)
{
numerical_array tmp(*this);

tmp *= s;
return tmp;
}

class real_array : public numerical_array<double>
{
Expand Down
120 changes: 114 additions & 6 deletions mosh/src/value.cpp
Expand Up @@ -747,11 +747,59 @@ value value::operator-(const value& v) const

const value& value::operator*= (const value& val)
{
// if (!is_numeric() || !val.is_numeric())
// {
// throw modelica_runtime_error("Multiplying non-numerical value\n");
// }
if (!is_numeric() || !val.is_numeric())
{
throw modelica_runtime_error("Multiplying non-numerical value\n");
}

if (is_real() && val.is_real())
{
m_real *= val.m_real;
}
else if (is_real() && val.is_integer())
{
m_real *= val.m_integer;
}
else if (is_integer() && val.is_real())
{
m_real = m_integer;
m_real *= val.m_real;
m_basic_type = create_real();
}
else if (is_integer() && val.is_integer())
{
m_integer *= val.m_integer;
}
else if (is_real_array() && val.is_real())
{
m_real_array *= val.m_real;
}
else if (is_real_array() && val.is_integer())
{
m_real_array *= double(val.m_integer);
}
else if (is_real() && val.is_real_array())
{
m_real_array = val.m_real_array;
m_real_array *= m_real;
m_basic_type = create_real_array(val.m_real_array.size());
}
else if (is_integer() && val.is_real_array())
{
m_real_array = val.m_real_array;
m_real_array *= double(m_integer);
m_basic_type = create_real_array(val.m_real_array.size());
}
else if (is_integer() && val.is_integer_array())
{
m_integer_array = val.m_integer_array;
m_integer_array *= m_integer;
m_basic_type = create_integer_array(val.m_integer_array.size());
}
else
{
throw modelica_runtime_error("This multiplication is not defined\n");
}
// if (val.is_real() || is_real())
// {
// m_real = to_double()*val.to_double();
Expand All @@ -769,8 +817,68 @@ const value& value::operator*= (const value& val)
value value::operator*(const value& v) const
{
value tmp(*this);
tmp *= v;
return tmp;

if (is_real_array() && v.is_real_array())
{
std::vector<int> s1 = m_real_array.size();
std::vector<int> s2 = v.m_real_array.size();

if ((m_real_array.ndims() == 1) && (v.m_real_array.ndims() == 1))
{
// vector x vector
if (s1[0] != s2[0])
{
throw modelica_runtime_error("Vector should be of the same length");
}
else
{
tmp.m_real = mul_vector_vector(m_real_array,v.m_real_array);
tmp.m_basic_type = create_real();
}
}
// else if (m_real_array.ndims() == 1)
// {
// // vector x matrix
// if(s1[0] != s2[0])
// {
// throw modelica_runtime_error("Invalid dimension in vector matrix product\n");
// }
// else
// {
// m_real_array = mul_vector_matrix(m_real_array,val.m_real_array);
// }

// }
// else if (val.m_real_array.ndims() == 1)
// {
// // matrix x vector
// if (s1[1] != s2[0])
// {
// throw modelica_runtime_error("Invalid dimension in matrix vector product\n");
// }
// else
// {

// }
// }
// else if (s1[1] != s2[0])
// {
// throw modelica_runtime_error("Invalid dimension sizes\n");
// }

// real_array result;
// result = m_real_array * val.m_real_array;

// m_real_array = result;
// }
}
else
{

tmp *= v;

}
return tmp;
}

const value& value::operator/= (const value& val)
Expand Down

0 comments on commit 3d5d12d

Please sign in to comment.