2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010 - DIGITEO - Antoine ELIAS
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
16 #include "arrayof.hxx"
19 #include "singlepoly.hxx"
20 #include "singlestruct.hxx"
21 #include "type_traits.hxx"
23 #include "types_tools.hxx"
27 #include "dynlib_ast.h"
34 static int get_max_size(int* _piDims, int _iDims)
42 for (int i = 0 ; i < _iDims ; i++)
50 GenericType* ArrayOf<T>::createEmpty()
52 return createEmptyDouble();
56 bool ArrayOf<T>::getMemory(long long* _piSize, long long* _piSizePlusType)
58 *_piSize = getSize() * sizeof(T) * (isComplex() ? 2 : 1);
59 *_piSizePlusType = *_piSize + sizeof(*this);
64 void ArrayOf<T>::humanReadableByteCount(size_t n, char (&str)[9])
69 std::snprintf(str, 9, "%lu B", n);
73 int exp = (int) std::log(n) / std::log(unit);
74 char preUnit[] = "kMGTPE";
75 char pre = preUnit[exp - 1];
77 std::snprintf(str, 9, "%.1f %cB", n / std::pow(unit, exp), pre);
81 void ArrayOf<T>::getIndexes(int _iIndex, int* _piIndexes)
83 getIndexesWithDims(_iIndex, _piIndexes, m_piDims, m_iDims);
87 ArrayOf<T>* ArrayOf<T>::insert(typed_list* _pArgs, InternalType* _pSource)
89 ArrayOf<T>* pIT = checkRef(this, &ArrayOf::insert, _pArgs, _pSource);
96 if (getScalarIndex(this, _pArgs, &index))
98 ArrayOf* pIns = _pSource->getAs<ArrayOf>();
99 int sizeIn = pIns->getSize();
100 //only scalar can be used to ".=" operation
106 T* pRealData = pIns->get();
107 T* pImgData = pIns->getImg();
109 if (isComplex() == false && pIns->isComplex() == false)
111 if (isNativeType() && index < m_iSize)
113 m_pRealData[index] = *pRealData;
118 if (set(index, *pRealData) != NULL)
125 //if complex continue
129 int iDims = (int)_pArgs->size();
130 int* piMaxDim = new int[iDims];
131 int* piCountDim = new int[iDims];
132 //evaluate each argument and replace by appropriate value and compute the count of combinations
133 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
140 cleanIndexesArguments(_pArgs, &pArg);
144 ArrayOf* pSource = _pSource->getAs<ArrayOf>();
146 //only scalar can be used to ".=" operation
147 if (iSeqCount != pSource->getSize() && pSource->isScalar() == false)
152 cleanIndexesArguments(_pArgs, &pArg);
156 //remove last dimension at size 1
157 //remove last dimension if are == 1
158 for (int i = (iDims - 1); i >= m_iDims; i--)
160 if (piMaxDim[i] == 1)
163 pArg.back()->killMe();
173 //insertion of a scalar is always possible regardless of index dimensions
174 if (pSource->isScalar() == false)
176 int *piSourceDims = pSource->getDimsArray();
177 int sDims = pSource->getDims();
180 for (int i = 0; i < iDims; i++)
182 if (piCountDim[i] == 1)
186 while (j < sDims && piSourceDims[j] == 1)
190 if (piSourceDims[j] != piCountDim[i])
195 cleanIndexesArguments(_pArgs, &pArg);
202 std::vector<int> indexes;
203 std::vector<int> dims;
204 if (getImplicitIndex(this, _pArgs, indexes, dims))
206 if (indexes.size() == 0)
211 cleanIndexesArguments(_pArgs, &pArg);
215 ArrayOf* pIns = _pSource->getAs<ArrayOf>();
216 int sizeIn = pIns->getSize();
217 int count = static_cast<int>(indexes.size());
218 //only scalar can be used to ".=" operation
219 if (sizeIn != 1 && count != sizeIn)
224 cleanIndexesArguments(_pArgs, &pArg);
228 T* pRealData = pIns->get();
229 T* pImgData = pIns->getImg();
232 if (isComplex() == false && pIns->isComplex() == false)
238 for (int i : indexes)
246 m_pRealData[i] = *pRealData;
251 for (int i : indexes)
253 if (set(i, *pRealData) == NULL)
265 for (int i : indexes)
273 m_pRealData[i] = *pRealData;
279 for (int i : indexes)
281 if (set(i, *pRealData) == NULL)
296 cleanIndexesArguments(_pArgs, &pArg);
300 //if status is false, continue to entire process
304 bool bNeedToResize = false;
305 int iDimsOrigine = m_iDims;
308 int* piNewDims = NULL;
311 bool bIsColon = false;
313 if (iDims >= m_iDims)
315 //all case are good, we can do almost everything
316 //check if resize is needed
319 bNeedToResize = true;
321 else //_iDims == m_iDims
323 for (int i = 0; i < m_iDims; i++)
325 if (m_piDims[i] < piMaxDim[i])
327 bNeedToResize = true;
333 //determine new dimension of the matrix
334 if (bNeedToResize == true)
337 piNewDims = new int[iNewDims];
338 for (int i = 0; i < m_iDims; i++)
340 piNewDims[i] = std::max(piMaxDim[i], m_piDims[i]);
343 int iSource = (pSource->getDims() - 1);
344 bool bPassed = false;
345 int *piSourceDims = pSource->getDimsArray();
347 for (int i = m_iDims; i < iNewDims; ++i)
349 piNewDims[i] = piMaxDim[i];
353 else // _iDims < m_iDims
355 if (isVector() || isScalar() || getSize() == 0) //getSize() == 0, only for [] and {}
357 if (getSize() < piMaxDim[0])
359 bNeedToResize = true;
361 piNewDims = new int[2] {1, 1};
363 if (isScalar() || getSize() == 0)
365 int *piSourceDims = pSource->getDimsArray();
366 // if source is scalar then resize indexed array as a column vector
367 // otherwise resize with shape of source
368 piNewDims[(int)(piSourceDims[0] == 1 && pSource->getSize() > 1)] = piMaxDim[0];
370 else // resize with same shape as indexed array
372 piNewDims[(int)(getRows() == 1)] = piMaxDim[0];
378 //each index before last index must be in range of his dimension
379 //and last given dimension can not be > prod(last dimensions)
380 for (int i = 0; i < iDims - 1; i++)
382 //indexes are always doubles
383 double* pIdx = getDoubleArrayFromDouble(pArg[i]);
384 //InternalType* pVar = pArg[i];
385 //double* pIdx = static_cast<double*>(pVar->getAs<Double>()->get());
386 int iSize = pArg[i]->getAs<ArrayOf>()->getSize();
387 for (int j = 0; j < iSize; j++)
389 if (pIdx[j] > m_piDims[i])
394 cleanIndexesArguments(_pArgs, &pArg);
401 int iMaxLastDim = getVarMaxDim(iDims - 1, iDims);
402 double* pIdx = getDoubleArrayFromDouble(pArg[pArg.size() - 1]);
403 //InternalType* pVar = pArg[pArg.size() - 1];
404 //double* pIdx = static_cast<double*>(pVar->getAs<Double>()->get());
405 int iSize = pArg[pArg.size() - 1]->getAs<GenericType>()->getSize();
406 for (int i = 0; i < iSize; i++)
408 if (pIdx[i] > iMaxLastDim)
413 cleanIndexesArguments(_pArgs, &pArg);
420 //update complexity *before* first resizing
421 if (pSource->isComplex() && m_pImgData == NULL)
426 //before resize, check input dimension
429 ArrayOf<T>* pTemp = resize(piNewDims, iNewDims);
435 cleanIndexesArguments(_pArgs, &pArg);
441 piNewDims = m_piDims;
445 int argSize = static_cast<int>(pArg.size());
446 int* piIndex = new int[argSize];
447 int* piCoord = new int[argSize];
448 int* piViewDims = new int[iDims];
449 memset(piIndex, 0x00, sizeof(int) * argSize);
451 //convert current dimension to view dimension
452 for (int i = 0; i < iDims; i++)
454 piViewDims[i] = getVarMaxDim(i, iDims);
457 T* pRealData = pSource->get();
458 T* pImgData = pSource->getImg();
459 bool bComplex = pSource->isComplex();
461 for (int i = 0; i < iSeqCount; i++)
463 computeTuples(piCountDim, argSize, argSize - 1, piIndex);
466 for (int j = 0; j < argSize; j++)
468 piCoord[j] = getIntValueFromDouble(pArg[j], piIndex[j]) - 1;
469 //InternalType* pVar = pArg[j];
470 //piCoord[j] = static_cast<int>(pVar->getAs<Double>()->get(piIndex[j]) - 1);
471 //std::cout << piCoord[j] << " ";
474 //std::cout << "]" << std::endl;
476 int iPos = getIndexWithDims(piCoord, piViewDims, iDims);
491 cleanIndexesArguments(_pArgs, &pArg);
493 wchar_t szError[bsiz];
494 os_swprintf(szError, bsiz, _W("Invalid index.\n").c_str());
495 throw ast::InternalError(szError);
498 if (pSource->isScalar())
500 //element-wise insertion
501 set(iPos, pRealData[0]);
502 if (pImgData != NULL && bComplex)
504 setImg(iPos, pImgData[0]);
512 for (int j = 0; j < iDimsOrigine; j++)
514 iPas = iPas * m_piDims[j];
517 for (int iPost = iPos; iPost < this->getSize(); iPost += iPas)
519 set(iPost, pRealData[i]);
520 if (pImgData != NULL && bComplex)
522 setImg(iPost, pImgData[i]);
529 set(iPos, pRealData[i]);
530 if (pImgData != NULL && bComplex)
532 setImg(iPos, pImgData[i]);
537 // reset imaginary part
538 if (m_pImgData != NULL && bComplex == false)
559 cleanIndexesArguments(_pArgs, &pArg);
564 template <typename T>
565 GenericType* ArrayOf<T>::insertNew(typed_list* _pArgs)
567 bool bComplex = getImg() != NULL;
568 std::vector<int> dims;
569 if (getArgsDims(_pArgs, dims))
571 InternalType *pOut = NULL;
573 if (dims.size() == 1 && getDims() == 2)
577 dims.insert(dims.begin(), 1);
585 while (dims.size() < 2)
590 pOut = createEmpty((int)dims.size(), dims.data(), bComplex);
591 ArrayOf* pArrayOut = pOut->getAs<ArrayOf>();
592 pArrayOut->fillDefaultValues();
593 ArrayOf* pOut2 = pArrayOut->insert(_pArgs, this);
603 InternalType *pOut = NULL;
605 int iDims = (int)_pArgs->size();
606 int* piMaxDim = new int[iDims];
607 int* piCountDim = new int[iDims];
609 //evaluate each argument and replace by appropriate value and compute the count of combinations
610 int iSeqCount = checkIndexesArguments(NULL, _pArgs, &pArg, piMaxDim, piCountDim);
617 cleanIndexesArguments(_pArgs, &pArg);
618 return createEmptyDouble();
623 //manage : and $ in creation by insertion
624 int iSourceDims = getDims();
628 for (int i = 0; i < iDims; ++i)
636 if (iNbColon == iDims)
641 cleanIndexesArguments(_pArgs, &pArg);
645 int *piSourceDims = new int[iSourceDims];
646 memcpy(piSourceDims, getDimsArray(), iSourceDims * sizeof(int));
648 if (iNbColon == 1 && isVector())
651 piSourceDims[0] = getSize();
654 //vector or matrix case
655 for (int i = 0; i < iDims; ++i)
657 //if these do not match another following explicit index, replace ":" by known source dimensions
660 if (iSource < iSourceDims)
662 //by default, replace colon by current source dimension
663 piMaxDim[i] = piSourceDims[iSource];
664 //if there are more index dimensions left than source dimensions left
665 if (iDims - i > iSourceDims - iSource)
667 for (int j = i + 1; j < iDims - iSourceDims + iSource + 1; ++j)
669 //when first explicit index is reached
672 //if future index #j and current source dimensions match
673 if (piCountDim[j] == piSourceDims[iSource])
686 //fill dimensions after iSourceDims with 1
689 pArg[i] = createDoubleVector(piMaxDim[i]);
692 else if (iSource < iSourceDims &&
693 piCountDim[i] == piSourceDims[iSource] &&
694 (piCountDim[i] > 1 || iNbColon < iSourceDims))
699 delete[] piSourceDims;
702 //remove last dimension at size 1
703 //remove last dimension if are == 1
704 for (int i = (iDims - 1); i >= 2; i--)
706 if (piMaxDim[i] == 1)
709 pArg.back()->killMe();
718 if (checkArgValidity(pArg) == false)
723 cleanIndexesArguments(_pArgs, &pArg);
724 //contain bad index, like <= 0, ...
732 int piRealDim[2] = {piMaxDim[0], 1};
733 pOut = createEmpty(2, piRealDim, bComplex);
738 int piRealDim[2] = {1, piMaxDim[0]};
739 pOut = createEmpty(2, piRealDim, bComplex);
744 pOut = createEmpty(iDims, piMaxDim, bComplex);
748 //fill with null item
749 ArrayOf* pArrayOut = pOut->getAs<ArrayOf>();
750 pArrayOut->fillDefaultValues();
751 //T* pRealData = pArrayOut->get();
754 // int size = pArrayOut->getSize();
755 // T* pImgData = pArrayOut->getImg();
757 // if (isNativeType())
759 // T val = getNullValue();
760 // for (int i = 0; i < size; i++)
762 // pRealData[i] = val;
763 // pImgData[i] = val;
768 // for (int i = 0; i < size; i++)
770 // pArrayOut->deleteData(pRealData[i]);
771 // pRealData[i] = getNullValue();
772 // pArrayOut->deleteData(pImgData[i]);
773 // pImgData[i] = getNullValue();
779 // int size = pArrayOut->getSize();
780 // if (isNativeType())
782 // T val = getNullValue();
783 // for (int i = 0; i < size; i++)
785 // pRealData[i] = val;
790 // for (int i = 0; i < size; i++)
792 // pArrayOut->deleteData(pRealData[i]);
793 // pRealData[i] = getNullValue();
798 //insert values in new matrix
799 ArrayOf* pOut2 = pArrayOut->insert(&pArg, this);
808 cleanIndexesArguments(_pArgs, &pArg);
813 template <typename T>
814 ArrayOf<T>* ArrayOf<T>::append(int _iRows, int _iCols, InternalType* _poSource)
816 ArrayOf<T>* pIT = checkRef(this, &ArrayOf::append, _iRows, _iCols, _poSource);
822 _poSource->IncreaseRef();
823 ArrayOf * pGT = _poSource->getAs<ArrayOf>();
824 int iRows = pGT->getRows();
825 int iCols = pGT->getCols();
827 //insert without resize
828 if (iRows + _iRows > m_iRows || iCols + _iCols > m_iCols)
833 //Update complexity if necessary
834 if (pGT->isComplex())
838 else if (isComplex())
840 pGT = pGT->setComplex(true);
843 if (pGT->isComplex())
845 for (int i = 0; i < iRows; i++)
847 for (int j = 0; j < iCols; j++)
849 set(_iRows + i, _iCols + j, pGT->get(i, j));
850 setImg(_iRows + i, _iCols + j, pGT->getImg(i, j));
856 for (int i = 0; i < iRows; i++)
858 for (int j = 0; j < iCols; j++)
860 set(_iRows + i, _iCols + j, pGT->get(i, j));
866 _poSource->DecreaseRef();
871 template <typename T>
872 GenericType* ArrayOf<T>::remove(typed_list* _pArgs)
874 ArrayOf<T>* pOut = NULL;
875 int iDims = (int)_pArgs->size();
878 int* piMaxDim = new int[iDims];
879 int* piCountDim = new int[iDims];
881 //evaluate each argument and replace by appropriate value and compute the count of combinations
882 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
888 cleanIndexesArguments(_pArgs, &pArg);
889 //no Seq, no change but no error.
893 int iToDelIndex = -1;
894 std::vector<int> toDelIndexVect;
896 // dimensions not subject to deletion must be indexed with colon or equivalent
897 for (int i = 0; i < iDims; i++)
899 int iDimToCheck = getVarMaxDim(i, iDims);
900 int iIndexSize = pArg[i]->getAs<GenericType>()->getSize();
901 if ((*_pArgs)[i]->isColon() == false)
903 //if equivalent to colon, should be 1:iDimToCheck after sorting and removing duplicates
904 double* pIndexes = getDoubleArrayFromDouble(pArg[i]);
905 std::vector<int> pIndexesVect(pIndexes, pIndexes + iIndexSize);
906 std::sort(pIndexesVect.begin(), pIndexesVect.end());
907 pIndexesVect.erase(unique(pIndexesVect.begin(), pIndexesVect.end()), pIndexesVect.end());
908 //remove index > iDimToCheck to allow a[10, 10](1, 1:100) = [] and a[10, 10]([1 5 20], :) = []
909 auto lastUnique = std::find_if(pIndexesVect.begin(), pIndexesVect.end(),
910 [&iDimToCheck](int idx)
912 return idx > iDimToCheck;
914 pIndexesVect.erase(lastUnique, pIndexesVect.end());
916 if (pIndexesVect.size() != iDimToCheck)
918 // index is not equivalent to colon -> index to delete
922 toDelIndexVect = pIndexesVect;
926 //cannot delete indexes on more than one dimension
928 cleanIndexesArguments(_pArgs, &pArg);
937 // overall removal x(:,...,:) = []
938 cleanIndexesArguments(_pArgs, &pArg);
939 return createEmpty();
942 if (toDelIndexVect.size() == 0)
944 // no removal because of too large indexes
945 cleanIndexesArguments(_pArgs, &pArg);
949 int iNewDimSize = getVarMaxDim(iToDelIndex, iDims) - toDelIndexVect.size();
951 int* piNewDims = new int[iDims];
952 for (int i = 0; i < iDims; i++)
954 piNewDims[i] = getVarMaxDim(i, iDims);
956 piNewDims[iToDelIndex] = iNewDimSize;
958 //remove last dimension if are == 1
959 int iOrigDims = iDims;
960 for (int i = (iDims - 1); i >= 2; i--)
962 if (piNewDims[i] == 1)
974 //two cases, depends of original matrix/vector
975 if ((*_pArgs)[0]->isColon() == false && m_iDims == 2 && m_piDims[0] == 1 && m_piDims[1] != 1)
977 //special case for row vector
978 int piRealDim[2] = {1, iNewDimSize};
979 //in this case we have to care of 2nd dimension
981 pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
985 int piRealDim[2] = {iNewDimSize, 1};
986 pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
991 pOut = createEmpty(iDims, piNewDims, m_pImgData != NULL);
994 // find a way to copy existing data to new variable ...
995 int* piViewDims = new int[iOrigDims];
996 int* piOffset = new int[iOrigDims + 1];
1000 for (int i = 0; i < iOrigDims; i++)
1002 piViewDims[i] = getVarMaxDim(i, iOrigDims);
1003 piOffset[i + 1] = piViewDims[i] * piOffset[i];
1006 // indexes to remove -> [ 0, toDelIndexVect, piViewDims[iToDelIndex]+1 ] to facilitate loop
1007 toDelIndexVect.insert(toDelIndexVect.begin(), 0);
1008 toDelIndexVect.push_back(piViewDims[iToDelIndex] + 1);
1012 int iOffset1 = piOffset[iToDelIndex];
1013 int iOffset2 = piOffset[iToDelIndex + 1];
1014 int iNbChunks = getSize() / iOffset2;
1016 // fast algorithm (allowing in place removal if necessary)
1017 for (int k = 0, iDest = 0; k < iNbChunks; k++)
1019 iStart = k * iOffset2;
1020 // loop on indexes to remove
1021 for (int j = 0; j < toDelIndexVect.size() - 1; j++)
1023 iSize = (toDelIndexVect[j + 1] - toDelIndexVect[j] - 1) * iOffset1;
1026 memcpy(pOut->m_pRealData + iDest, m_pRealData + iStart, iSize * sizeof(T));
1027 if (m_pImgData != NULL)
1029 memcpy(pOut->m_pImgData + iDest, m_pImgData + iStart, iSize * sizeof(T));
1035 for (int i = iStart; i < iStart + iSize; i++, iDest++)
1037 pOut->set(iDest, get(i));
1038 if (m_pImgData != NULL)
1040 pOut->setImg(iDest, getImg(i));
1044 iStart += iSize + iOffset1;
1048 delete[] piViewDims;
1053 cleanIndexesArguments(_pArgs, &pArg);
1058 template <typename T>
1059 GenericType* ArrayOf<T>::extract(typed_list* _pArgs)
1061 ArrayOf<T>* pOut = NULL;
1062 int iDims = (int)_pArgs->size();
1066 if (getScalarIndex(this, _pArgs, &index))
1075 return createEmpty();
1078 if (index >= getSize())
1083 int dims[2] = {1, 1};
1084 pOut = createEmpty(2, dims, false);
1085 pOut->set(0, get(index));
1086 bool c = isNativeType() ? getImg(index) != 0 : isComplexElement(index);
1087 if (isComplex() && c)
1089 pOut->setComplex(true);
1090 pOut->setImg(0, getImg(index));
1094 pOut->setComplex(false);
1102 std::vector<double> il;
1103 if (getScalarImplicitIndex(this, _pArgs, il))
1105 double start = il[0];
1106 double step = il[1];
1109 bool isForceColVector = il.size() == 4;
1111 //std::cout << start << ":" << step << ":" << end << std::endl;
1112 int size = static_cast<int>((end - start) / step + 1);
1114 if (size <= 0 || m_iSize == 0)
1116 return createEmpty();
1120 if (step > 0 && ((size - 1) * step + start > m_iSize || start < 1) ||
1121 (step < 0 && (start > m_iSize || end < 1)))
1126 bool isColVector = isForceColVector || (isVector() && m_iCols == 1);
1127 int dims[2] = {isColVector ? size : 1, isColVector ? 1 : size};
1128 pOut = createEmpty(2, dims, isComplex());
1133 bool bIsComplex = false;
1134 for (int i = 0; i < size; ++i)
1136 int index = static_cast<int>(idx) - 1;
1137 T iValue = getImg(index);
1138 pOut->set(i, get(index));
1139 pOut->setImg(i, iValue);
1142 bIsComplex |= (iValue != 0);
1146 bIsComplex |= (isComplexElement(index) != 0);
1151 pOut->setComplex(bIsComplex);
1155 for (int i = 0; i < size; ++i)
1157 pOut->set(i, get(static_cast<int>(idx) - 1));
1164 std::vector<int> indexes;
1165 std::vector<int> dims;
1166 if (getImplicitIndex(this, _pArgs, indexes, dims))
1168 if (indexes.size() == 0)
1170 return createEmpty();
1173 if (dims.size() == 1)
1175 int d[2] = {1, dims[0]};
1176 pOut = createEmpty(2, d, isComplex());
1180 pOut = createEmpty(static_cast<int>(dims.size()), dims.data(), isComplex());
1183 int size = getSize();
1186 bool bIsComplex = false;
1188 for (int & i : indexes)
1190 if (i < 0 || i >= size)
1196 T iValue = getImg(i);
1197 pOut->set(idx, get(i));
1198 pOut->setImg(idx, iValue);
1201 bIsComplex |= (iValue != 0);
1205 bIsComplex |= (isComplexElement(i) != 0);
1210 pOut->setComplex(bIsComplex);
1215 for (int & i : indexes)
1217 pOut->set(idx, get(i));
1226 int* piMaxDim = new int[iDims];
1227 int* piCountDim = new int[iDims];
1229 //evaluate each argument and replace by appropriate value and compute the count of combinations
1230 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
1234 delete[] piCountDim;
1236 cleanIndexesArguments(_pArgs, &pArg);
1237 return createEmpty();
1243 delete[] piCountDim;
1245 cleanIndexesArguments(_pArgs, &pArg);
1249 //a = {};a(1:2, 1:2) -> {}
1253 delete[] piCountDim;
1255 cleanIndexesArguments(_pArgs, &pArg);
1256 return createEmpty();
1259 if (iDims < m_iDims)
1261 for (int i = 0; i < iDims; i++)
1263 int iDimToCheck = 0;
1264 if (i == (iDims - 1))
1266 iDimToCheck = getVarMaxDim(i, iDims);
1270 iDimToCheck = m_piDims[i];
1273 if (piMaxDim[i] > iDimToCheck)
1276 delete[] piCountDim;
1278 cleanIndexesArguments(_pArgs, &pArg);
1285 if (iDims > m_iDims)
1287 for (int i = m_iDims; i < iDims; i++)
1289 if (piMaxDim[i] > 1)
1292 delete[] piCountDim;
1294 cleanIndexesArguments(_pArgs, &pArg);
1301 for (int i = 0; i < m_iDims; i++)
1303 if (piMaxDim[i] > m_piDims[i])
1306 delete[] piCountDim;
1308 cleanIndexesArguments(_pArgs, &pArg);
1309 //exrtact must be in dimension limits
1315 //remove last dimension if are == 1
1316 for (int i = (iDims - 1); i >= 2; i--)
1318 if (piCountDim[i] == 1)
1328 //linear indexing (one subscript)
1331 if (piCountDim[0] == 0)
1334 delete[] piCountDim;
1336 cleanIndexesArguments(_pArgs, &pArg);
1337 return createEmpty();
1341 int *i_piDims = pArg[0]->getAs<GenericType>()->getDimsArray();
1342 if (!isScalar() && isVector() && (i_piDims[0] == 1 || i_piDims[1] == 1))
1344 //vector with vector subscript
1345 int piRealDim[2] = { 1, 1 };
1346 piRealDim[(int)(m_piDims[0] == 1)] = piCountDim[0];
1347 pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
1351 if ((*_pArgs)[0]->isBool() || (*_pArgs)[0]->isSparseBool())
1353 //boolean extraction must return a column vector
1354 int piRealDim[2] = { piCountDim[0], 1 };
1355 pOut = createEmpty(2, piRealDim, m_pImgData != NULL);
1360 pOut = createEmpty(pArg[0]->getAs<GenericType>()->getDims(), i_piDims, m_pImgData != NULL);
1367 //indexing with more than one subscript
1368 pOut = createEmpty(iDims, piCountDim, m_pImgData != NULL);
1371 int* piIndex = new int[_pArgs->size()];
1372 int* piCoord = new int[_pArgs->size()];
1373 int* piViewDims = new int[iDims];
1374 memset(piIndex, 0x00, sizeof(int) * _pArgs->size());
1376 for (int i = 0; i < iDims; i++)
1378 piViewDims[i] = getVarMaxDim(i, iDims);
1381 bool bIsComplex = false;
1382 for (int i = 0; i < iSeqCount; i++)
1384 //increment last dimension
1385 computeTuples(piCountDim, (int)_pArgs->size(), (int)_pArgs->size() - 1, piIndex);
1388 for (int j = 0; j < (int)_pArgs->size(); j++)
1390 piCoord[j] = getIntValueFromDouble(pArg[j], piIndex[j]) - 1;
1391 //InternalType* pVar = pArg[i];
1392 //piCoord[j] = static_cast<int>(pVar->getAs<Double>()->get(piIndex[j]) - 1);
1393 //std::cout << piCoord[j] << " ";
1395 // try to access somewhere wrong.
1400 delete[] piViewDims;
1402 delete[] piCountDim;
1405 cleanIndexesArguments(_pArgs, &pArg);
1410 //std::cout << "]" << std::endl;
1413 //put vlaue in the new matrix
1414 if ((int)_pArgs->size() < m_iDims)
1416 //compute index based on viewed matrix
1417 iPos = getIndexWithDims(piCoord, piViewDims, iDims);
1421 //compute vector index
1422 iPos = getIndex(piCoord);
1425 //convert flat dimension to 0
1426 for (int j = 0; j < iDims; j++)
1428 if (piCountDim[j] == 1)
1434 pOut->set(i, get(iPos));
1437 T iValue = getImg(iPos);
1438 pOut->setImg(i, iValue);
1441 bIsComplex |= (iValue != 0);
1445 bIsComplex |= (isComplexElement(iPos) != 0);
1452 pOut->setComplex(bIsComplex);
1455 cleanIndexesArguments(_pArgs, &pArg);
1459 delete[] piViewDims;
1461 delete[] piCountDim;
1466 template <typename T>
1467 ArrayOf<T>* ArrayOf<T>::reshape(int* _piDims, int _iDims)
1469 typedef ArrayOf<T>* (ArrayOf<T>::*reshape_t)(int*, int);
1470 ArrayOf<T>* pIT = checkRef(this, (reshape_t)&ArrayOf<T>::reshape, _piDims, _iDims);
1476 int iNewSize = get_max_size(_piDims, _iDims);
1477 if (iNewSize != m_iSize)
1482 for (int i = 0 ; i < _iDims ; i++)
1484 m_piDims[i] = _piDims[i];
1494 for (int i = iDims - 1; i >= 2; --i)
1496 if (m_piDims[i] == 1)
1506 m_iRows = m_piDims[0];
1507 m_iCols = m_piDims[1];
1514 template <typename T>
1515 ArrayOf<T>* ArrayOf<T>::resize(int* _piDims, int _iDims)
1517 typedef ArrayOf<T>* (ArrayOf<T>::*resize_t)(int*, int);
1518 ArrayOf<T>* pIT = checkRef(this, (resize_t)&ArrayOf::resize, _piDims, _iDims);
1524 if (_iDims == m_iDims)
1526 bool bChange = false;
1527 for (int i = 0; i < _iDims; i++)
1529 if (m_piDims[i] != _piDims[i])
1536 if (bChange == false)
1543 //alloc new data array
1544 T* pRealData = NULL;
1548 if (m_pImgData != NULL)
1550 iNewSize = get_max_size(_piDims, _iDims);
1551 if (m_iSizeMax < iNewSize)
1553 //alloc 10% bigger than asked to prevent future resize
1554 int iOldSizeMax = m_iSizeMax;
1555 m_iSizeMax = static_cast<int>(iNewSize * 1.1);
1556 pRealData = allocData(m_iSizeMax);
1557 pImgData = allocData(m_iSizeMax);
1559 //copy values into new one
1560 int* piIndexes = new int[std::max(m_iDims, _iDims)];
1561 memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1562 for (int i = 0; i < _iDims; i++)
1567 int iPreviousNewIdx = 0;
1568 for (int i = 0; i < m_iSize; i++)
1570 getIndexes(i, piIndexes);
1571 int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1572 pRealData[iNewIdx] = m_pRealData[i];
1573 pImgData[iNewIdx] = m_pImgData[i];
1574 for (int j = iPreviousNewIdx; j < iNewIdx; ++j)
1576 T pTemp = getNullValue();
1577 pRealData[j] = copyValue(pTemp);
1578 pImgData[j] = copyValue(pTemp);
1579 if (pTemp != pRealData[j])
1585 iPreviousNewIdx = iNewIdx + 1;
1588 // if it's not the first resize,
1589 // fill new data with element of last allocation
1590 if (iPreviousNewIdx < iOldSizeMax)
1592 for (int i = iPreviousNewIdx; i < iOldSizeMax; ++i)
1594 pRealData[i] = m_pRealData[i];
1595 pImgData[i] = m_pImgData[i];
1600 // first resize, iOldSizeMax don't contain the 10%
1601 iOldSizeMax = iPreviousNewIdx;
1604 for (int i = iOldSizeMax; i < m_iSizeMax; ++i)
1606 T pTemp = getNullValue();
1607 pRealData[i] = copyValue(pTemp);
1608 pImgData[i] = copyValue(pTemp);
1609 if (pTemp != pRealData[i])
1617 delete[] m_pRealData;
1618 delete[] m_pImgData;
1619 //replace old array by new one
1620 m_pRealData = pRealData;
1621 m_pImgData = pImgData;
1625 //check if only the last dims change
1626 bool bNonLastDimChange = false;
1627 for (int i = 0; i < (m_iDims - 1); i++)
1629 if (m_piDims[i] != _piDims[i])
1631 bNonLastDimChange = true;
1636 //if vector or if row dimension not change, we don't need to shift data
1637 if (m_iDims != _iDims || (!isVector() && bNonLastDimChange))
1639 //copy values into new one
1640 int* piIndexes = new int[std::max(m_iDims, _iDims)];
1641 memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1642 for (int i = m_iSize - 1; i >= 0; i--)
1644 getIndexes(i, piIndexes);
1645 int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1648 T pTemp = m_pRealData[iNewIdx];
1649 m_pRealData[iNewIdx] = m_pRealData[i];
1650 m_pRealData[i] = pTemp;
1652 pTemp = m_pImgData[iNewIdx];
1653 m_pImgData[iNewIdx] = m_pImgData[i];
1654 m_pImgData[i] = pTemp;
1663 iNewSize = get_max_size(_piDims, _iDims);
1664 if (iNewSize > m_iSizeMax)
1666 //alloc 10% bigger than asked to prevent future resize
1667 int iOldSizeMax = m_iSizeMax;
1668 m_iSizeMax = static_cast<int>(iNewSize * 1.1);
1669 pRealData = allocData(m_iSizeMax);
1671 //copy values into new one
1672 int* piIndexes = new int[std::max(m_iDims, _iDims)];
1673 memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1674 for (int i = 0; i < _iDims; i++)
1679 int iPreviousNewIdx = 0;
1680 for (int i = 0; i < m_iSize; i++)
1682 getIndexes(i, piIndexes);
1683 int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1684 pRealData[iNewIdx] = m_pRealData[i];
1685 m_pRealData[i] = T();
1687 for (int j = iPreviousNewIdx; j < iNewIdx; ++j)
1689 T pTemp = getNullValue();
1690 T pTemp2 = copyValue(pTemp);
1691 pRealData[j] = pTemp2;
1692 if (pTemp != pTemp2)
1698 iPreviousNewIdx = iNewIdx + 1;
1701 //clean section between m_iSize and iOldSizeMax
1702 for (int i = m_iSize; i < iOldSizeMax; ++i)
1704 deleteData(m_pRealData[i]);
1705 m_pRealData[i] = T();
1708 //if (iPreviousNewIdx < iOldSizeMax)
1710 // for (int i = iPreviousNewIdx; i < iOldSizeMax; ++i)
1712 // pRealData[i] = m_pRealData[i];
1713 // m_pRealData[i] = T();
1718 // iOldSizeMax = iPreviousNewIdx;
1721 //fill exceeded with NullValue
1722 for (int i = iPreviousNewIdx; i < m_iSizeMax; ++i)
1724 T pTemp = getNullValue();
1725 T pTemp2 = copyValue(pTemp);
1726 pRealData[i] = pTemp2;
1727 if (pTemp != pTemp2)
1735 delete[] m_pRealData;
1736 //replace old array by new one
1737 m_pRealData = pRealData;
1741 //check if only the last dims change
1742 bool bNonLastDimChange = false;
1743 for (int i = 0; i < (m_iDims - 1); i++)
1745 if (m_piDims[i] != _piDims[i])
1747 bNonLastDimChange = true;
1752 //if vector or if row dimension not change, we don't need to shift data
1753 if (m_iDims != _iDims || (!isVector() && bNonLastDimChange))
1755 //copy values into new one
1756 int* piIndexes = new int[std::max(m_iDims, _iDims)];
1757 memset(piIndexes, 0x00, sizeof(int) * std::max(m_iDims, _iDims));
1758 for (int i = m_iSize - 1; i >= 0; i--)
1760 getIndexes(i, piIndexes);
1761 int iNewIdx = getIndexWithDims(piIndexes, _piDims, _iDims);
1764 T pTemp = m_pRealData[iNewIdx];
1765 m_pRealData[iNewIdx] = m_pRealData[i];
1766 m_pRealData[i] = pTemp;
1774 if (_iDims != m_iDims)
1776 //int* piDims = new int[_iDims];
1777 for (int i = 0; i < _iDims; i++)
1779 m_piDims[i] = _piDims[i];
1781 //delete[] m_piDims;
1782 //m_piDims = piDims;
1787 for (int i = 0; i < m_iDims; i++)
1789 m_piDims[i] = _piDims[i];
1792 m_iRows = m_piDims[0];
1793 m_iCols = m_piDims[1];
1798 template <typename T>
1799 bool ArrayOf<T>::isTrue()
1801 return type_traits::isTrue<T>(m_iSize, m_pRealData);
1804 template<typename T>
1805 bool ArrayOf<T>::neg(InternalType *& out)
1807 out = new Bool(this->m_iDims, this->m_piDims);
1808 type_traits::neg<T, int>(this->m_iSize, this->m_pRealData, static_cast<Bool *>(out)->get());
1813 template<typename T>
1814 bool ArrayOf<T>::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, const ast::Exp & e)
1818 out.push_back(this);
1822 InternalType * _out = extract(&in);
1825 std::wostringstream os;
1826 os << _W("Invalid index.\n");
1827 throw ast::InternalError(os.str(), 999, e.getLocation());
1829 out.push_back(_out);
1835 template<typename T>
1836 bool ArrayOf<T>::isInvokable() const
1841 template<typename T>
1842 bool ArrayOf<T>::hasInvokeOption() const
1847 template<typename T>
1848 int ArrayOf<T>::getInvokeNbIn()
1853 template<typename T>
1854 int ArrayOf<T>::getInvokeNbOut()
1860 // used to allow definition of ArrayOf methode in this cpp file.
1861 template class EXTERN_AST ArrayOf < char >;
1862 template class EXTERN_AST ArrayOf < unsigned char >;
1863 template class EXTERN_AST ArrayOf < short >;
1864 template class EXTERN_AST ArrayOf < unsigned short >;
1865 template class EXTERN_AST ArrayOf < int >;
1866 template class EXTERN_AST ArrayOf < unsigned int >;
1867 template class EXTERN_AST ArrayOf < long long >;
1868 template class EXTERN_AST ArrayOf < unsigned long long >;
1869 template class EXTERN_AST ArrayOf < double >;
1870 template class EXTERN_AST ArrayOf < wchar_t* >;
1871 template class EXTERN_AST ArrayOf < SinglePoly* >;
1872 template class EXTERN_AST ArrayOf < SingleStruct* >;
1873 template class EXTERN_AST ArrayOf < InternalType* >; // Cell