void transpose_array(const BaseArray<T>& x, BaseArray<T>& a) { size_t ndims = x.getNumDims(); if(ndims < 2 || ndims != a.getNumDims()) throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, "Wrong dimensions in transpose_array"); vector<size_t> ex = x.getDims(); std::swap(ex[0], ex[1]); a.setDims(ex); vector<Slice> sx(ndims); vector<Slice> sa(ndims); for (int i = 1; i <= x.getDim(1); i++) { sa[1] = sx[0] = Slice(i); ArraySlice<T>(a, sa).assign(ArraySliceConst<T>(x, sx)); } }
void multiply_array(const BaseArray<T> &leftArray, const BaseArray<T> &rightArray, BaseArray<T> &resultArray) { size_t leftNumDims = leftArray.getNumDims(); size_t rightNumDims = rightArray.getNumDims(); size_t matchDim = rightArray.getDim(1); resultArray.setDims(leftArray.getDims()); if (leftArray.getDim(leftNumDims) != matchDim) throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, "Wrong sizes in multiply_array"); if (leftNumDims == 1 && rightNumDims == 2) { size_t rightDim = rightArray.getDim(2); for (size_t j = 1; j <= rightDim; j++) { T val = T(); for (size_t k = 1; k <= matchDim; k++) val += leftArray(k) * rightArray(k, j); resultArray(j) = val; } } else if (leftNumDims == 2 && rightNumDims == 1) { size_t leftDim = leftArray.getDim(1); for (size_t i = 1; i <= leftDim; i++) { T val = T(); for (size_t k = 1; k <= matchDim; k++) val += leftArray(i, k) * rightArray(k); resultArray(i) = val; } } else if (leftNumDims == 2 && rightNumDims == 2) { size_t leftDim = leftArray.getDim(1); size_t rightDim = rightArray.getDim(2); for (size_t i = 1; i <= leftDim; i++) { for (size_t j = 1; j <= rightDim; j++) { T val = T(); for (size_t k = 1; k <= matchDim; k++) val += leftArray(i, k) * rightArray(k, j); resultArray(i, j) = val; } } } else throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, "Unsupported dimensions in multiply_array"); }
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++; } } } }