elementary_functions module.
[scilab.git] / scilab / modules / elementary_functions / src / cpp / min.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Cedric Delamarre
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12 /*--------------------------------------------------------------------------*/
13 #include <algorithm>
14 #include <vector>
15
16 #include "types_tools.hxx"
17 #include "min.hxx"
18
19 /*--------------------------- Double ---------------------------------------*/
20 void min(std::vector<types::Double*> vectIn, int iOrientation, types::Double* pDblIndex, types::Double* pOut)
21 {
22     int iDims       = vectIn[0]->getDims();
23     int* iDimsArray = vectIn[0]->getDimsArray();
24     int iSize       = vectIn[0]->getSize();
25     int iInit       = 0;
26     double dValue   = 0;
27
28     if (vectIn.size() > 1) // Find the min value between all inputs matrix
29     {
30         //Find the first non scalar to init output matrix.
31         for (int iter = 0; iter < vectIn.size(); iter++)
32         {
33             if (vectIn[iter]->isScalar() == false)
34             {
35                 iInit = iter;
36                 break;
37             }
38         }
39
40         iDims = vectIn[iInit]->getDims();
41         iDimsArray = vectIn[iInit]->getDimsArray();
42         iSize = vectIn[iInit]->getSize();
43
44         // Init output matrix
45         for (int i = 0; i < iSize; i++)
46         {
47             pOut->set(i, vectIn[iInit]->get(i));
48         }
49
50         if (pDblIndex)
51         {
52             for (int i = 0; i < pDblIndex->getSize(); i++)
53             {
54                 pDblIndex->set(i, 1);
55             }
56
57             for (int i = 0; i < iSize; i++)
58             {
59                 for (int iter = 0; iter < vectIn.size(); iter++)
60                 {
61                     int iPos = i;
62                     if (vectIn[iter]->isScalar())
63                     {
64                         iPos = 0;
65                     }
66
67                     dValue = vectIn[iter]->get(iPos);
68                     if (pOut->get(i) > dValue || ISNAN(pOut->get(i)))
69                     {
70                         pOut->set(i, dValue);
71                         pDblIndex->set(i, iter + 1);
72                     }
73                 }
74             }
75         }
76         else
77         {
78             for (int i = 0; i < iSize; i++)
79             {
80                 for (int iter = 0; iter < vectIn.size(); iter++)
81                 {
82                     int iPos = i;
83                     if (vectIn[iter]->isScalar())
84                     {
85                         iPos = 0;
86                     }
87
88                     dValue = vectIn[iter]->get(iPos);
89                     if (pOut->get(i) > dValue || ISNAN(pOut->get(i)))
90                     {
91                         pOut->set(i, dValue);
92                     }
93                 }
94             }
95         }
96     }
97     else
98     {
99         if (iOrientation == 0) // Find the min value between all matrix elements
100         {
101             double dMin = vectIn[0]->get(0);
102             int iIndex = 0;
103             for (int i = 1; i < iSize; i++)
104             {
105                 dValue = vectIn[0]->get(i);
106                 if (dMin > dValue || ISNAN(dMin))
107                 {
108                     dMin = dValue;
109                     iIndex = i;
110                 }
111             }
112
113             pOut->set(0, dMin);
114             if (pDblIndex)
115             {
116                 if (pDblIndex->isScalar())
117                 {
118                     pDblIndex->set(0, iIndex + 1);
119                 }
120                 else
121                 {
122                     int* piIndexes = new int[iDims];
123                     types::getIndexesWithDims(iIndex, piIndexes, iDimsArray, iDims);
124                     for (int i = 0; i < pDblIndex->getSize(); i++)
125                     {
126                         pDblIndex->set(i, piIndexes[i] + 1);
127                     }
128                     delete piIndexes;
129                 }
130             }
131         }
132         else // Find the min value between all elements of the dimension N (iOrientation)
133         {
134             int iSizeOfDimN = iDimsArray[iOrientation - 1];
135             int iIncrement  = 1;
136             int iIncrOut    = 0;
137
138             for (int i = 0; i < iOrientation - 1; i++)
139             {
140                 iIncrement *= iDimsArray[i];
141             }
142
143             for (int j = 0; j < iSize; j += (iIncrement * iSizeOfDimN))
144             {
145                 for (int i = j; i < iIncrement + j; i++)
146                 {
147                     // init pOut with the first values of the dim N
148                     pOut->set(iIncrOut, vectIn[0]->get(i));
149
150                     if (pDblIndex)
151                     {
152                         pDblIndex->set(iIncrOut, 1);
153                     }
154
155                     for (int k = 1; k < iSizeOfDimN; k++)
156                     {
157                         dValue = vectIn[0]->get(k * iIncrement + i);
158                         if (pOut->get(iIncrOut) > dValue || ISNAN(pOut->get(iIncrOut)))
159                         {
160                             pOut->set(iIncrOut, dValue);
161                             if (pDblIndex)
162                             {
163                                 pDblIndex->set(iIncrOut, k + 1);
164                             }
165                         }
166                     }
167                     iIncrOut++;
168                 }
169             }
170         }
171     }
172 }