示例#1
0
        /// <summary>
        /// Applys the function (delegate) given to all elements of the storage
        /// </summary>
        /// <param name="inArray">storage array to apply the function to</param>
        /// <param name="operation">operation to apply to the elements of inArray. This
        /// acts like a function pointer.</param>
        /// <returns>new ILArray<double> with result</returns>
        /// <remarks> the values of inArray will not be altered.</remarks>
        private static ILArray <double> DoubleUnaryDoubleOperator(ILArray <double> inArray, ILApplyDouble_Double operation)
        {
            ILDimension inDim = inArray.Dimensions;

            double[] retDblArr;
            // build ILDimension
            int newLength = inDim.NumberOfElements;

            retDblArr = new double[newLength];
            int leadDim    = 0;
            int leadDimLen = inDim[0];

            if (inArray.IsReference)
            {
                #region Reference storage
                // walk along the longest dimension (for performance reasons)
                for (int i = 1; i < inDim.NumberOfDimensions; i++)
                {
                    if (leadDimLen < inDim[i])
                    {
                        leadDimLen = inDim[i];
                        leadDim    = i;
                    }
                }
                ILIndexOffset idxOffset = inArray.m_indexOffset;
                int           incOut    = inDim.SequentialIndexDistance(leadDim);
                // ========================  REFERENCE double Storage ===========
                if (inArray.IsMatrix)
                {
                    #region Matrix
                    ////////////////////////////   MATRIX   ////////////////////
                    int secDim = (leadDim + 1) % 2;
                    unsafe
                    {
                        fixed(int *leadDimStart = idxOffset[leadDim],
                              secDimStart       = idxOffset[secDim])
                        {
                            fixed(double *pOutArr = retDblArr,
                                  pInArr          = inArray.m_data)
                            {
                                double *tmpOut     = pOutArr;
                                double *tmpIn      = pInArr;
                                double *tmpOutEnd  = pOutArr + inDim.NumberOfElements - 1;
                                int *   secDimEnd  = secDimStart + idxOffset[secDim].Length;
                                int *   secDimIdx  = secDimStart;
                                int *   leadDimIdx = leadDimStart;
                                int *   leadDimEnd = leadDimStart + idxOffset[secDim].Length;;

                                while (secDimIdx < secDimEnd)
                                {
                                    tmpIn      = pInArr + *secDimIdx++;
                                    leadDimIdx = leadDimStart;
                                    while (leadDimIdx < leadDimEnd)
                                    {
                                        *tmpOut = operation(*(tmpIn + *leadDimIdx++));
                                        tmpOut += incOut;
                                    }
                                    if (tmpOut > tmpOutEnd)
                                    {
                                        tmpOut = pOutArr + (tmpOutEnd - tmpOut);
                                    }
                                }
                            }
                        }
                    }
                    #endregion
                }
                else if (inArray.IsVector)
                {
                    #region Vector
                    ////////////////////////////   VECTOR   ///////////////////////
                    unsafe
                    {
                        fixed(int *leadDimStart = idxOffset[leadDim])
                        {
                            fixed(double *pOutArr = retDblArr,
                                  pInArr          = inArray.m_data)
                            {
                                double *tmpOut     = pOutArr;
                                double *tmpIn      = pInArr + idxOffset[((leadDim + 1) % 2), 0];
                                int *   leadDimIdx = leadDimStart;
                                int *   leadDimEnd = leadDimStart + leadDimLen;

                                // start at first element
                                while (leadDimIdx < leadDimEnd)
                                {
                                    *tmpOut++ = operation(*(tmpIn + *leadDimIdx++));
                                }
                            }
                        }
                    }
                    #endregion
                }
                else
                {
                    /////////////////////////////   ARBITRARY DIMENSIONS //////////
                    #region arbitrary size
                    unsafe {
                        int[] curPosition = new int[inArray.Dimensions.NumberOfDimensions];
                        fixed(int *leadDimStart = idxOffset[leadDim])
                        {
                            fixed(double *pOutArr = retDblArr,
                                  pInArr          = inArray.m_data)
                            {
                                double *tmpOut    = pOutArr;
                                double *tmpOutEnd = tmpOut + retDblArr.Length;
                                // init lesezeiger: add alle Dimensionen mit 0 (außer leadDim)
                                double *tmpIn = pInArr + inArray.getBaseIndex(0, 0);

                                tmpIn -= idxOffset[leadDim, 0];
                                int *leadDimIdx = leadDimStart;
                                int *leadDimEnd = leadDimStart + leadDimLen;
                                int  dimLen = curPosition.Length;
                                int  d, curD;

                                // start at first element
                                while (tmpOut < tmpOutEnd)
                                {
                                    leadDimIdx = leadDimStart;
                                    while (leadDimIdx < leadDimEnd)
                                    {
                                        *tmpOut = operation(*(tmpIn + *leadDimIdx++));
                                        tmpOut += incOut;
                                    }
                                    if (tmpOut > tmpOutEnd)
                                    {
                                        tmpOut = pOutArr + (tmpOutEnd - tmpOut);
                                    }

                                    // increment higher dimensions
                                    d = 1;
                                    while (d < dimLen)
                                    {
                                        curD   = (d + leadDim) % dimLen;
                                        tmpIn -= idxOffset[curD, curPosition[curD]];
                                        curPosition[curD]++;
                                        if (curPosition[curD] < idxOffset[curD].Length)
                                        {
                                            tmpIn += idxOffset[curD, curPosition[curD]];
                                            break;
                                        }
                                        curPosition[curD] = 0;
                                        tmpIn            += idxOffset[curD, 0];
                                        d++;
                                    }
                                }
                            }
                        }
                    }
                    #endregion
                }
                // ==============================================================
                #endregion
            }
            else
            {
                // physical -> pointer arithmetic
                #region physical storage
                unsafe
                {
                    fixed(double *pOutArr = retDblArr,
                          pInArr          = inArray.m_data)
                    {
                        double *lastElement = pOutArr + retDblArr.Length;
                        double *tmpOut      = pOutArr;
                        double *tmpIn       = pInArr;

                        while (tmpOut < lastElement)
                        {
                            *tmpOut++ = operation(*tmpIn++);
                        }
                    }
                }
                #endregion
            }
            return(new ILArray <double>(retDblArr, inDim.ToIntArray()));
        }
示例#2
0
文件: ILMath.cs 项目: wdxa/ILNumerics
        /// <summary>
		/// Applys the function (delegate) given to all elements of the storage
		/// </summary>
		/// <param name="inArray">storage array to apply the function to</param>
		/// <param name="operation">operation to apply to the elements of inArray. This
		/// acts like a function pointer.</param>
		/// <returns>new ILArray<double> with result</returns>
		/// <remarks> the values of inArray will not be altered.</remarks>
		private static ILArray<double> DoubleUnaryDoubleOperator(ILArray<double> inArray, ILApplyDouble_Double operation) {
			ILDimension inDim = inArray.Dimensions;
			double[] retDblArr;
			// build ILDimension
			int newLength = inDim.NumberOfElements;
			retDblArr = new double[newLength];
			int leadDim = 0;
			int leadDimLen = inDim[0];
			if (inArray.IsReference) {
				#region Reference storage
				// walk along the longest dimension (for performance reasons)
				for (int i = 1; i < inDim.NumberOfDimensions; i++) {
					if (leadDimLen < inDim[i]) {
						leadDimLen = inDim[i];
						leadDim = i;
					}
				}
				ILIndexOffset idxOffset = inArray.m_indexOffset;
				int incOut = inDim.SequentialIndexDistance(leadDim);
				// ========================  REFERENCE double Storage ===========
				if (inArray.IsMatrix) {
					#region Matrix
					////////////////////////////   MATRIX   ////////////////////
					int secDim = (leadDim + 1) % 2;
					unsafe {
						fixed (int* leadDimStart = idxOffset[leadDim],
								secDimStart = idxOffset[secDim]) {
							fixed (double* pOutArr = retDblArr,
									pInArr = inArray.m_data) {
								double* tmpOut = pOutArr;
								double* tmpIn = pInArr;
								double* tmpOutEnd = pOutArr + inDim.NumberOfElements - 1;
								int* secDimEnd = secDimStart + idxOffset[secDim].Length;
								int* secDimIdx = secDimStart;
								int* leadDimIdx = leadDimStart;
								int* leadDimEnd = leadDimStart + idxOffset[secDim].Length; ;
								while (secDimIdx < secDimEnd) {
									tmpIn = pInArr + *secDimIdx++;
									leadDimIdx = leadDimStart;
									while (leadDimIdx < leadDimEnd) {
										*tmpOut = operation(*(tmpIn + *leadDimIdx++));
										tmpOut += incOut;
									}
									if (tmpOut > tmpOutEnd)
										tmpOut = pOutArr + (tmpOutEnd - tmpOut);
								}
							}
						}
					}
					#endregion
				} else if (inArray.IsVector) {
					#region Vector
					////////////////////////////   VECTOR   ///////////////////////
					unsafe {
						fixed (int* leadDimStart = idxOffset[leadDim]) {
							fixed (double* pOutArr = retDblArr,
									pInArr = inArray.m_data) {
								double* tmpOut = pOutArr;
								double* tmpIn = pInArr + idxOffset[((leadDim + 1) % 2), 0];
								int* leadDimIdx = leadDimStart;
								int* leadDimEnd = leadDimStart + leadDimLen;
								// start at first element
								while (leadDimIdx < leadDimEnd)
									*tmpOut++ = operation(*(tmpIn + *leadDimIdx++));
							}
						}
					}
					#endregion
				} else {
					/////////////////////////////   ARBITRARY DIMENSIONS //////////
					#region arbitrary size
					unsafe {
						int[] curPosition = new int[inArray.Dimensions.NumberOfDimensions];
						fixed (int* leadDimStart = idxOffset[leadDim]) {
							fixed (double* pOutArr = retDblArr,
									pInArr = inArray.m_data) {
								double* tmpOut = pOutArr;
								double* tmpOutEnd = tmpOut + retDblArr.Length;
								// init lesezeiger: add alle Dimensionen mit 0 (außer leadDim)
								double* tmpIn = pInArr + inArray.getBaseIndex(0, 0);
								tmpIn -= idxOffset[leadDim, 0];
								int* leadDimIdx = leadDimStart;
								int* leadDimEnd = leadDimStart + leadDimLen;
								int dimLen = curPosition.Length;
								int d, curD;
								// start at first element
								while (tmpOut < tmpOutEnd) {
									leadDimIdx = leadDimStart;
									while (leadDimIdx < leadDimEnd) {
										*tmpOut = operation(*(tmpIn + *leadDimIdx++));
										tmpOut += incOut;
									}
									if (tmpOut > tmpOutEnd)
										tmpOut = pOutArr + (tmpOutEnd - tmpOut);

									// increment higher dimensions 
									d = 1;
									while (d < dimLen) {
										curD = (d + leadDim) % dimLen;
										tmpIn -= idxOffset[curD, curPosition[curD]];
										curPosition[curD]++;
										if (curPosition[curD] < idxOffset[curD].Length) {
											tmpIn += idxOffset[curD, curPosition[curD]];
											break;
										}
										curPosition[curD] = 0;
										tmpIn += idxOffset[curD, 0];
										d++;
									}
								}
							}
						}
					}
					#endregion
				}
				// ==============================================================
				#endregion
			} else {
				// physical -> pointer arithmetic
				#region physical storage
				unsafe {
					fixed (double* pOutArr = retDblArr,
							pInArr = inArray.m_data) {
						double* lastElement = pOutArr + retDblArr.Length;
						double* tmpOut = pOutArr;
						double* tmpIn = pInArr;
						while (tmpOut < lastElement)
							*tmpOut++ = operation(*tmpIn++);
					}
				}
				#endregion
			}
			return new ILArray<double>(retDblArr, inDim.ToIntArray());
		}