void cast_array(const BaseArray<S>& a, BaseArray<T>& b) { b.setDims(a.getDims()); int numElems = a.getNumElems(); const S* src_data = a.getData(); T* dst_data = b.getData(); for (int i = 0; i < numElems; i++) *dst_data++ = (T)(*src_data++); }
T dot_array(const BaseArray<T>& a, const BaseArray<T>& b) { if(a.getNumDims() != 1 || b.getNumDims() != 1) throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION,"error in dot array function. Wrong dimension"); const T* data1 = a.getData(); const T* data2 = b.getData(); T r = std::inner_product(data1, data1 + a.getNumElems(), data2, 0.0); return r; }
void divide_array(const BaseArray<T>& inputArray, const T &b, BaseArray<T>& outputArray) { size_t nelems = inputArray.getNumElems(); if (outputArray.getNumElems() != nelems) { outputArray.setDims(inputArray.getDims()); } const T* data = inputArray.getData(); T* aim = outputArray.getData(); std::transform(data, data + nelems, aim, std::bind2nd(std::divides<T>(), b)); }
void subtract_array_scalar(const BaseArray<T>& inputArray, T b, BaseArray<T>& outputArray) { size_t dim = inputArray.getNumElems(); if(dim > 0) { outputArray.setDims(inputArray.getDims()); const T* data = inputArray.getData(); T* aim = outputArray.getData(); std::transform (data, data + inputArray.getNumElems(), aim, std::bind2nd(std::minus<T>(), b)); } }
void pow_array_scalar(const BaseArray<double> &inputArray, T exponent, BaseArray<double> &outputArray) { size_t nelems = inputArray.getNumElems(); if (outputArray.getNumElems() != nelems) outputArray.setDims(inputArray.getDims()); const double *data = inputArray.getData(); double *dest = outputArray.getData(); double *end = dest + nelems; while (dest != end) *dest++ = pow(*data++, exponent); }
void multiply_array(const BaseArray<T>& inputArray, const T &b, BaseArray<T>& outputArray) { size_t dim = inputArray.getNumElems(); if(dim > 0) { outputArray.setDims(inputArray.getDims()); const T* data = inputArray.getData(); T* aim = outputArray.getData(); std::transform (data, data + inputArray.getNumElems(), aim, std::bind2nd(std::multiplies<T>(), b)); } };
std::pair<T,T> min_max(const BaseArray<T>& x) { const T* data = x.getData(); std::pair<const T*, const T*> ret = minmax_element(data, data + x.getNumElems()); return std::make_pair(*(ret.first), *(ret.second)); }
void add_array(const BaseArray<T>& leftArray, const BaseArray<T>& rightArray, BaseArray<T>& resultArray) { size_t dimLeft = leftArray.getNumElems(); size_t dimRight = rightArray.getNumElems(); if(dimLeft != dimRight) throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, "Right and left array must have the same size for element wise addition"); resultArray.setDims(leftArray.getDims()); const T* data1 = leftArray.getData(); const T* data2 = rightArray.getData(); T* aim = resultArray.getData(); std::transform(data1, data1 + leftArray.getNumElems(), data2, aim, std::plus<T>()); }
void multiply_array_elem_wise(const BaseArray<T> &leftArray, const BaseArray<T> &rightArray, BaseArray<T> &resultArray) { size_t dimLeft = leftArray.getNumElems(); size_t dimRight = rightArray.getNumElems(); if(dimLeft != dimRight) throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, "Right and left array must have the same size for element wise multiplication"); resultArray.setDims(leftArray.getDims()); const T* leftData = leftArray.getData(); const T* rightData = rightArray.getData(); T* aim = resultArray.getData(); std::transform (leftData, leftData + leftArray.getNumElems(), rightData, aim, std::multiplies<T>()); }
void promote_array(size_t n, const BaseArray<T>& s, BaseArray<T>& d) { vector<size_t> ex = s.getDims(); for (int i=0; i<n; i++) ex.push_back(1); d.setDims(ex); d.assign(s.getData()); }
T sum_array (const BaseArray<T>& x) { const T* data = x.getData(); T val = std::accumulate(data, data + x.getNumElems(), T()); return val; }
void fill_array(BaseArray<T>& inputArray, T b) { T* data = inputArray.getData(); std::fill(data, data + inputArray.getNumElems(), b); }
void cat_array(int k, const vector<const BaseArray<T>*>& x, BaseArray<T>& a) { unsigned int new_k_dim_size = 0; unsigned int n = x.size(); /* check dim sizes of all inputs */ if(n<1) throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION,"No input arrays"); if(x[0]->getDims().size() < k) throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION,"Wrong dimension for input array"); new_k_dim_size = x[0]->getDims()[k-1]; for(int i = 1; i < n; i++) { //arrays must have same number of dimensions if(x[0]->getDims().size() != x[i]->getDims().size()) throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION,"Wrong dimension for input array"); //Size matching: Arrays must have identical array sizes with the exception of the size of dimension k for(int j = 0; j < (k - 1); j++) { if (x[0]->getDims()[j] != x[i]->getDims()[j]) throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION,"Wrong size for input array"); } //calculate new size of dimension k new_k_dim_size += x[i]->getDims()[k-1]; //Size matching: Arrays must have identical array sizes with the exception of the size of dimension k for(int j = k; j < x[0]->getDims().size(); j++) { if (x[0]->getDims()[j] != x[i]->getDims()[j]) throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION,"Wrong size for input array"); } } /* calculate size of sub and super structure in 1-dim data representation */ unsigned int n_sub = 1; unsigned int n_super = 1; for (int i = 0; i < (k - 1); i++) { n_super *= x[0]->getDims()[i]; } for (int i = k; i < x[0]->getDims().size(); i++) { n_sub *= x[0]->getDims()[i]; } /* allocate output array */ vector<size_t> ex = x[0]->getDims(); ex[k-1] = new_k_dim_size; if(ex.size()<k) throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION,"Error resizing concatenate array"); a.setDims( ex ); /* concatenation along k-th dimension */ T* a_data = a.getData(); int j = 0; for (int i = 0; i < n_super; i++) { for (int c = 0; c < n; c++) { int n_sub_k = n_sub * x[c]->getDims()[k-1]; const T* x_data = x[c]->getData(); for (int r = 0; r < n_sub_k; r++) { a_data[j] = x_data[r + (i * n_sub_k)]; j++; } } } }