///
/// This file is part of ILNumerics Community Edition.
///
/// ILNumerics Community Edition - high performance computing for applications.
/// Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
///
/// ILNumerics Community Edition is free software: you can redistribute it and/or modify
/// it under the terms of the GNU General Public License version 3 as published by
/// the Free Software Foundation.
///
/// ILNumerics Community Edition is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU General Public License for more details.
///
/// You should have received a copy of the GNU General Public License
/// along with ILNumerics Community Edition. See the file License.txt in the root
/// of your distribution package. If not, see .
///
/// In addition this software uses the following components and/or licenses:
///
/// =================================================================================
/// The Open Toolkit Library License
///
/// Copyright (c) 2006 - 2009 the Open Toolkit library.
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights to
/// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
/// the Software, and to permit persons to whom the Software is furnished to do
/// so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all
/// copies or substantial portions of the Software.
///
/// =================================================================================
///
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.CompilerServices;
using System.Numerics;
using ILNumerics.Misc;
using ILNumerics.Data;
using ILNumerics.Exceptions;
using System.Linq.Expressions;
namespace ILNumerics.Storage {
///
/// The class realizes an internal storage wrapper. It stores the internal data array
/// and the dimension specifications for both: ILRetArray and ILDenseStorage (reference and solid).
///
[System.Diagnostics.DebuggerTypeProxy(typeof(ILNumerics.Misc.ILArrayDebuggerProxy<>))]
[System.Diagnostics.DebuggerDisplay("{ShortInfo(),nq}")]
[Serializable]
internal partial class ILDenseStorage : ILStorage {
#region attributes
///
/// Internal storage object. Contains the final System.Array storage and a reference counter.
///
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
protected ILCountableArray m_data;
#endregion
#region properties
///
/// number of storages referencing the current data array
///
internal int ReferenceCount {
get {
return m_data.ReferenceCount;
}
}
///
/// Determine, if this storage has already been disposed.
///
internal override bool IsDisposed {
get {
return m_data == null;
}
}
protected ILCountableArray Data {
get {
return m_data;
}
set {
ILCountableArray old = m_data;
m_data = value;
m_data.IncreaseReference();
if (old != null)
old.DecreaseReference();
}
}
///
/// Get minimum and maximum value of all elements - if these exist.
///
/// Output: minimum value.
/// Output: maximum value.
/// True if the limits exists and could be computed, false otherwise.
/// Empty arrays will return false. The output parameter will be default(type).
internal override bool GetLimits(out ElementType minValue, out ElementType maxValue) {
return GetLimits(out minValue, out maxValue, true);
}
///
/// Get minimum and maximum value of all elements - if existing
///
/// Output: minimum value.
/// Output: maximum value.
/// true: recognize Inf, NaN values; false: ignore those values
/// True if the limits exists and could be computed, false otherwise.
/// Empty arrays will return false. The output parameter will be default(ElementType) then.
internal override bool GetLimits(out ElementType minValue, out ElementType maxValue, bool includeInfNaNs) {
minValue = default(ElementType);
maxValue = default(ElementType);
if (m_size.NumberOfElements == 0)
return false;
if (false) {
} else if (this is ILDenseStorage ) {
double [] data = ( double [])(object) GetArrayForRead();
double curVal;
double curMin = Double.PositiveInfinity ;
double curMax = Double.NegativeInfinity ;
int curMinInd = 0;
int curMaxInd = 0;
int len = m_size.NumberOfElements;
for (int i = 0; i < len; i++) {
curVal = data[i];
if (double.IsInfinity(curVal)) continue;
if (curVal < curMin) {
curMin = curVal;
curMinInd = i;
}
if (curVal > curMax) {
curMax = curVal;
curMaxInd = i;
}
}
maxValue = m_data.Data[curMaxInd];
minValue = m_data.Data[curMinInd];
return (curMax > Double.NegativeInfinity || curMin < Double.PositiveInfinity );
#region HYCALPER AUTO GENERATED CODE
} else if (this is ILDenseStorage ) {
fcomplex [] data = ( fcomplex [])(object) GetArrayForRead();
fcomplex curVal;
fcomplex curMin = new fcomplex(float.PositiveInfinity,float.PositiveInfinity) ;
fcomplex curMax = new fcomplex(float.NegativeInfinity,float.NegativeInfinity) ;
int curMinInd = 0;
int curMaxInd = 0;
int len = m_size.NumberOfElements;
for (int i = 0; i < len; i++) {
curVal = data[i];
if (fcomplex.IsInfinity(curVal)) continue;
if (curVal < curMin) {
curMin = curVal;
curMinInd = i;
}
if (curVal > curMax) {
curMax = curVal;
curMaxInd = i;
}
}
maxValue = m_data.Data[curMaxInd];
minValue = m_data.Data[curMinInd];
return (curMax > new fcomplex(float.NegativeInfinity,float.NegativeInfinity) || curMin < new fcomplex(float.NegativeInfinity,float.NegativeInfinity) );
} else if (this is ILDenseStorage ) {
complex [] data = ( complex [])(object) GetArrayForRead();
complex curVal;
complex curMin = new complex(Double.PositiveInfinity,Double.PositiveInfinity) ;
complex curMax = new complex(Double.NegativeInfinity,Double.NegativeInfinity) ;
int curMinInd = 0;
int curMaxInd = 0;
int len = m_size.NumberOfElements;
for (int i = 0; i < len; i++) {
curVal = data[i];
if (complex.IsInfinity(curVal)) continue;
if (curVal < curMin) {
curMin = curVal;
curMinInd = i;
}
if (curVal > curMax) {
curMax = curVal;
curMaxInd = i;
}
}
maxValue = m_data.Data[curMaxInd];
minValue = m_data.Data[curMinInd];
return (curMax > new complex(Double.NegativeInfinity,Double.NegativeInfinity) || curMin < new complex(Double.NegativeInfinity,Double.NegativeInfinity) );
} else if (this is ILDenseStorage ) {
byte [] data = ( byte [])(object) GetArrayForRead();
byte curVal;
byte curMin = Byte.MaxValue ;
byte curMax = Byte.MinValue ;
int curMinInd = 0;
int curMaxInd = 0;
int len = m_size.NumberOfElements;
for (int i = 0; i < len; i++) {
curVal = data[i];
if (curVal < curMin) {
curMin = curVal;
curMinInd = i;
}
if (curVal > curMax) {
curMax = curVal;
curMaxInd = i;
}
}
maxValue = m_data.Data[curMaxInd];
minValue = m_data.Data[curMinInd];
return (curMax > Byte.MinValue || curMin < Byte.MinValue );
} else if (this is ILDenseStorage ) {
Int64 [] data = ( Int64 [])(object) GetArrayForRead();
Int64 curVal;
Int64 curMin = Int64.MaxValue ;
Int64 curMax = Int64.MinValue ;
int curMinInd = 0;
int curMaxInd = 0;
int len = m_size.NumberOfElements;
for (int i = 0; i < len; i++) {
curVal = data[i];
if (curVal < curMin) {
curMin = curVal;
curMinInd = i;
}
if (curVal > curMax) {
curMax = curVal;
curMaxInd = i;
}
}
maxValue = m_data.Data[curMaxInd];
minValue = m_data.Data[curMinInd];
return (curMax > Int64.MinValue || curMin < Int64.MinValue );
} else if (this is ILDenseStorage ) {
Int32 [] data = ( Int32 [])(object) GetArrayForRead();
Int32 curVal;
Int32 curMin = Int32.MaxValue ;
Int32 curMax = Int32.MinValue ;
int curMinInd = 0;
int curMaxInd = 0;
int len = m_size.NumberOfElements;
for (int i = 0; i < len; i++) {
curVal = data[i];
if (curVal < curMin) {
curMin = curVal;
curMinInd = i;
}
if (curVal > curMax) {
curMax = curVal;
curMaxInd = i;
}
}
maxValue = m_data.Data[curMaxInd];
minValue = m_data.Data[curMinInd];
return (curMax > Int32.MinValue || curMin < Int32.MinValue );
} else if (this is ILDenseStorage ) {
float [] data = ( float [])(object) GetArrayForRead();
float curVal;
float curMin = float.PositiveInfinity ;
float curMax = float.NegativeInfinity ;
int curMinInd = 0;
int curMaxInd = 0;
int len = m_size.NumberOfElements;
for (int i = 0; i < len; i++) {
curVal = data[i];
if(float.IsInfinity(curVal)) continue;
if (curVal < curMin) {
curMin = curVal;
curMinInd = i;
}
if (curVal > curMax) {
curMax = curVal;
curMaxInd = i;
}
}
maxValue = m_data.Data[curMaxInd];
minValue = m_data.Data[curMinInd];
return (curMax > float.NegativeInfinity || curMin < float.NegativeInfinity );
#endregion HYCALPER AUTO GENERATED CODE
} else if ((typeof(ElementType) is IComparable)) {
ElementType[] tmpArr = GetArrayForRead();
for (int i = 0; i < m_size.NumberOfElements; i++) {
ElementType val = tmpArr[i];
if (((IComparable)val).CompareTo(minValue) < 0)
minValue = val;
if (((IComparable)val).CompareTo(minValue) > 0)
maxValue = val;
}
return true;
}
return false;
}
#endregion
#region overriding object.ToString(), Equals()
///
/// Write information about the ILDenseStorage to string.
///
/// String containing general information about the current instance of
/// ILDenseStorage and the formatted elements' values.
/// If the number of elements exceeds a certain amount, the display will be abreviated.
public override string ToString() {
return ValuesToString(0).ToString();
}
///
/// print formated values to string
///
/// Maximum number of characters per line. 0: no limit
/// StringBuilder object filled with formated values.
internal override StringBuilder ValuesToString(int maxLength) {
StringBuilder s = new StringBuilder();
if (maxLength <= 0) maxLength = int.MaxValue;
//if (m_dimensions.NumberOfElements > 100000) {
// s.Append(String.Format("({0})", m_dimensions.ToString()));
// return s;
//}
if (m_size.NumberOfElements < 1)
return new StringBuilder("(Empty)");
int[] acc = new int[m_size.NumberOfDimensions];
int d;
String sElement;
int elemLength = 10;
//string format = "{0,20: E13;-E13; 0.0 } ";
int curLineLength = 0, curRowsCount = 0;
int maxRows = (maxLength == int.MaxValue) ? int.MaxValue : 500; // limit data rows in debugger view
if (false) {
} else if (this.Data.Data.GetType() == typeof( double [] )) {
#region
double element;
double [] elements = (this.Data.Data as double []);
elemLength = 10 ;
double scaling = getScalingForPrint();
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ((scaling == 1 && (int)element == element) ? "{0} " : "{0:f5} ", element / scaling).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
#region HYCALPER AUTO GENERATED CODE
} else if (this.Data.Data.GetType() == typeof( float [] )) {
#region
float element;
float [] elements = (this.Data.Data as float []);
elemLength = 5 ;
float scaling = (float)getScalingForPrint();
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0:f5} ", element / scaling).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( fcomplex [] )) {
#region
fcomplex element;
fcomplex [] elements = (this.Data.Data as fcomplex []);
elemLength = 24 ;
float scaling = (float)getScalingForPrint();
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0} ", (element / scaling).ToString(5)).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( complex [] )) {
#region
complex element;
complex [] elements = (this.Data.Data as complex []);
elemLength = 36 ;
double scaling = getScalingForPrint();
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0} ", (element / scaling).ToString(5)).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( Complex [] )) {
#region
Complex element;
Complex [] elements = (this.Data.Data as Complex []);
elemLength = 36 ;
double scaling = getScalingForPrint();
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0} ", ComplexHelper(element / scaling,5)).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( byte [] )) {
#region
byte element;
byte [] elements = (this.Data.Data as byte []);
elemLength = 3 ;
double scaling = 1.0;
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0,3:G} ", element).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( char [] )) {
#region
char element;
char [] elements = (this.Data.Data as char []);
elemLength = 3 ;
double scaling = 1.0;
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0,3:G} ", element).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( UInt64 [] )) {
#region
UInt64 element;
UInt64 [] elements = (this.Data.Data as UInt64 []);
elemLength = 18 ;
double scaling = 1.0;
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0,18:G} ", element).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( UInt32 [] )) {
#region
UInt32 element;
UInt32 [] elements = (this.Data.Data as UInt32 []);
elemLength = 10 ;
double scaling = 1.0;
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0,10:G} ", element).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( UInt16 [] )) {
#region
UInt16 element;
UInt16 [] elements = (this.Data.Data as UInt16 []);
elemLength = 5 ;
double scaling = 1.0;
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0,5:G} ", element).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( Int64 [] )) {
#region
Int64 element;
Int64 [] elements = (this.Data.Data as Int64 []);
elemLength = 18 ;
double scaling = 1.0;
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0,18:G} ", element).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( Int32 [] )) {
#region
Int32 element;
Int32 [] elements = (this.Data.Data as Int32 []);
elemLength = 10 ;
double scaling = 1.0;
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0,10:G} ", element).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( Int16 [] )) {
#region
Int16 element;
Int16 [] elements = (this.Data.Data as Int16 []);
elemLength = 5 ;
double scaling = 1.0;
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0,5:G} ", element).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( ILStorage [] )) {
#region
ILStorage element;
ILStorage [] elements = (this.Data.Data as ILStorage []);
elemLength = 0 ;
double scaling = 1.0;
for (int i = 0; i < m_size.NumberOfElements; i++) {
element = elements[i];
int l = (element == null)? 6 : element.ShortInfo().Length;
if (l > elemLength) elemLength = l;
}
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = element.ShortInfo().PadRight(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else if (this.Data.Data.GetType() == typeof( object [] )) {
#region
object element;
object [] elements = (this.Data.Data as object []);
elemLength = 18 ;
double scaling = 1.0;
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2 || scaling != 1) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") " + ((scaling!=1.0)? (scaling.ToString("e0") + " * "):""));
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements [m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element,null)) {
sElement = String.Format ("{0} ", element).PadLeft(elemLength);
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
#endregion HYCALPER AUTO GENERATED CODE
} else if (this is ILDenseStorage ) {
#region
string element;
string[] elements = (this.Data.Data as string[]);
elemLength = 18;
int maxElemLength = 50; // todo: may better be a setting? abreviate after as many chars
elemLength++;
while (acc[m_size.NumberOfDimensions - 1] <
m_size[m_size.NumberOfDimensions - 1]) {
// show only two first dimensions at the same time ...
// print header
if (m_size.NumberOfDimensions > 2) {
if (s.Length > 0) s.Append(Environment.NewLine);
s.Append("(:,:");
for (d = 2; d < m_size.NumberOfDimensions; d++)
s.Append(String.Format(",{0}", acc[d]));
s.Append(") ");
}
// show this for 2 leading dimensions
for (int d0 = 0; d0 < m_size[0]; d0++) {
if (++curRowsCount > maxRows) {
s.Append(Environment.NewLine + "( ... more rows exist)");
return s;
}
if (s.Length > 0) s.Append(Environment.NewLine);
acc[0] = d0; curLineLength = 0;
for (int d1 = 0; d1 < m_size[1]; d1++) {
acc[1] = d1;
element = elements[m_size.IndexFromArray(acc)];
if (!Object.ReferenceEquals(element, null)) {
if (element.Length > maxElemLength) {
sElement = element.Substring(0,maxElemLength - 3) + "...";
} else {
sElement = String.Format("{0} ", element).PadLeft(elemLength);
}
} else {
sElement = "(null)".PadLeft(elemLength);
}
curLineLength += sElement.Length;
if (curLineLength > maxLength - " ...".Length) {
s.Append(" ...");
break;
} else {
s.Append(sElement);
}
}
}
// increase higher dimension
d = 2;
while (d <= m_size.NumberOfDimensions - 1) {
acc[d]++;
if (acc[d] < m_size[d]) break;
acc[d] = 0;
d++;
}
if (d >= m_size.NumberOfDimensions) break;
}
#endregion
} else {
return new StringBuilder ("(Unknown data type.)");
}
return s;
}
private double getScalingForPrint() {
ElementType min, max;
if (GetLimits(out min, out max, false)) {
try {
double scaling = Math.Max(
Math.Abs(double.Parse(min.ToString())),
Math.Abs( double.Parse(max.ToString()))
);
if (scaling == 0 || (scaling > 1e-1 && scaling < 1e1))
scaling = 1;
scaling = Math.Pow(10,Math.Floor(Math.Log10(scaling)));
if (scaling < 10000 && scaling >= 1)
scaling = 1;
return scaling;
} catch (Exception) {
return 1.0;
}
} else {
return 1.0;
}
}
private int GetTypedElementStringProperties(double scaling, out string format) {
format = "E+00000000000000;0.0;-E+00000000000000";
if (this is ILDenseStorage) {
return double.MaxValue.ToString().Length;
} else if (this is ILDenseStorage) {
return float.MaxValue.ToString().Length;
} else if (this is ILDenseStorage) {
return double.MaxValue.ToString().Length * 2 + 2;
} else if (this is ILDenseStorage) {
return double.MaxValue.ToString().Length * 2 + 2;
} else if (this is ILDenseStorage) {
return float.MaxValue.ToString().Length * 2 + 2;
} else if (this is ILDenseStorage) {
return char.MaxValue.ToString().Length;
} else if (this is ILDenseStorage) {
return byte.MaxValue.ToString().Length;
} else if (this is ILDenseStorage) {
return Int16.MaxValue.ToString().Length;
} else if (this is ILDenseStorage) {
return Int32.MaxValue.ToString().Length;
} else if (this is ILDenseStorage) {
return Int64.MaxValue.ToString().Length;
} else if (this is ILDenseStorage) {
return UInt16.MaxValue.ToString().Length;
} else if (this is ILDenseStorage) {
return UInt32.MaxValue.ToString().Length;
} else if (this is ILDenseStorage) {
return UInt64.MaxValue.ToString().Length;
} else
return 10;
}
private string ComplexHelper(Complex a, int digits) {
if (digits < 1) return "";
if (a.Imaginary >= 0) {
return String.Format("{0:f10}+{1:f10}", a.Real, a.Imaginary);
} else {
return String.Format("{0:f10}-{1:f10}", a.Real, -a.Imaginary);
}
}
///
/// Check if the content of this array equals the content of obj.
///
/// storage containing the values with which to compare this array.
/// True if all elements contained in obj are equal to the
/// elements of this array, false otherwise.
/// This method compares the object references of corresponding elements.
/// The size and type of both arrays must match. Otherwise false will be returned.
internal override bool Equals(object obj) {
if (object.Equals(obj,null)) return false;
if (obj is ElementType)
if (Size.NumberOfElements == 1
&& obj.ToString() == GetValueTyped(0).ToString())
return true;
else
return false;
ILDenseStorage denseStorage = obj as ILDenseStorage;
if (object.Equals(denseStorage,null))
return false;
return Equals(denseStorage);
}
///
/// Test if this dense storage equals another dense storage.
///
/// storage to compare this storage with
/// True if all elements and dimension sizes match, false otherwise.
internal bool Equals(ILDenseStorage A) {
if (A == null) return false;
if (!A.Size.IsSameSize(m_size))
return false;
int len = m_size.NumberOfElements;
if (typeof(ElementType).IsValueType) {
for (int i = 0; i < len;i++) {
if (!GetValueTyped(i).Equals(A.GetValueTyped(i)))
return false;
}
} else {
// references may contain null element values!
for (int i = 0; i < len;i++) {
ElementType t1 = GetValueTyped(i);
if (t1 == null) {
if (!A.GetValueTyped(i).Equals(null))
return false;
} else {
if (!t1.Equals(A.GetValueTyped(i)))
return false;
}
}
}
return true;
}
///
/// generate a hash code based on the current arrays values
///
/// hash code
/// The hashcode is generated by taking the values currently stored in the array into account.
/// Therefore, the function must iterate over all elements in the array - which makes it somehow a expensive
/// operation. Take this into account, if you consider using large arrays in collections like dictionaries
/// or hashtables, which make great use of hash codes.
public override int GetHashCode() {
if (IsDisposed) return base.GetHashCode();
int ret = Size.GetHashCode();
ElementType[] data = GetArrayForRead();
ret = (ret * 17) + data.Length;
foreach (ElementType t in data) {
ret = unchecked( ret * 17 );
if (t != null)
ret = unchecked(ret + t.GetHashCode());
}
return (int)ret;
}
#endregion
#region subarray + range get / set
///
/// Alter values specified by range.
///
/// ILRange specifying the dimensions/indices to be altered.
/// new values
///
/// The values pointed to by range will be replaced with the values
/// found in 'values'. Important: the range cannot specify indices outside of my dimensions!
/// Therefore, the storage must have been expanded in advance, if needed!
public virtual void SetRange(ILRange range, ILDenseStorage values) {
if (range.Size.NumberOfElements == 0) return;
int rangeDimLen = range.RangeArray.Length,higherDimSum = 0;
int leadDimLenRange = range[0].Count, leadDimLen = m_size[0];
int d, outElemCount = range.Size.NumberOfElements;
ElementType[] myArr = GetArrayForWrite();
int[] idxArr = new int[rangeDimLen]; // used to store current position inside higher dims
ILIntList[] rng = range.RangeArray;
int[] seqDistances = m_size.GetSequentialIndexDistances(range.Size.NumberOfDimensions);
int[] inFullDim = new int[rangeDimLen];
// initialize higher dimension summand and inFullDim[] flag array
for (int i = 1; i < idxArr.Length; i++) {
if (rng[i][0] < 0) {
inFullDim[i] = rng[i][0];
} else {
inFullDim[i] = 0;
higherDimSum += seqDistances[i] * rng[i][0];
}
}
//for (int lIdx = 0; lIdx < leadDimLenRange; lIdx ++) {
// retArr[curPosOut++] = myArr[higherDimSum + rleadDim[lIdx]];
//}
if (values.Size.NumberOfElements == 1) {
#region scalar case
ElementType scalar = values.GetValueTyped(0);
while (true) {
// copy along leading dimension
for (int i = 0; i < rng[0].Count; i++) {
if (rng[0][i] < 0) {
for (int c = -rng[0][i]; c-- >= 0; ) {
// we need a upward counter variable anyway, initialized with
// higherDimSum. So we simply take that and reset it after the loop:
myArr[ higherDimSum++ ] = scalar;
}
higherDimSum += (rng[0][i]-1); // negative value in rng!
} else {
myArr[ higherDimSum + rng[0][i] ] = scalar;
}
}
// increase higher dims
d = 1;
while (d < idxArr.Length) {
if (inFullDim[d] < 0) {
higherDimSum += seqDistances[d];
inFullDim[d]++;
break;
}
if (rng[d][idxArr[d]] >= 0) {
higherDimSum -= (rng[d][idxArr[d]] * seqDistances[d]);
} else {
higherDimSum += (rng[d][idxArr[d]] * seqDistances[d]);
}
idxArr[d]++;
if (idxArr[d] == rng[d].Count) {
idxArr[d] = 0;
if (rng[d][0] < 0) {
inFullDim[d] = rng[d][idxArr[d]];
} else {
higherDimSum += (rng[d][0] * seqDistances[d]);
}
d++;
} else if (rng[d][idxArr[d]] < 0) {
inFullDim[d] = rng[d][idxArr[d]];
break;
} else {
higherDimSum += seqDistances[d] * rng[d][idxArr[d]];
break;
}
}
if (d >= idxArr.Length)
break;
}
#endregion
} else {
#region non scalar case
ElementType [] valuesArr = values.GetArrayForRead();
int valuesPos = 0;
while (true) {
// copy along leading dimension
for (int i = 0; i < rng[0].Count; i++) {
if (rng[0][i] < 0) {
for (int c = -rng[0][i]; c-- >= 0; ) {
myArr[ higherDimSum++ ] = valuesArr[ valuesPos++ ];
}
higherDimSum += (rng[0][i]-1); // negative value in rng!
} else {
myArr[ higherDimSum + rng[0][i] ] = valuesArr[ valuesPos++ ];
}
}
// increase higher dims
d = 1;
while (d < idxArr.Length) {
if (inFullDim[d] < 0) {
higherDimSum += seqDistances[d];
inFullDim[d]++;
break;
}
if (rng[d][idxArr[d]] >= 0) {
higherDimSum -= (rng[d][idxArr[d]] * seqDistances[d]);
} else {
higherDimSum += (rng[d][idxArr[d]] * seqDistances[d]);
}
idxArr[d]++;
if (idxArr[d] == rng[d].Count) {
idxArr[d] = 0;
if (rng[d][idxArr[d]] < 0) {
inFullDim[d] = rng[d][idxArr[d]];
} else {
higherDimSum += (rng[d][0] * seqDistances[d]);
}
d++;
} else if (rng[d][idxArr[d]] < 0) {
inFullDim[d] = rng[d][idxArr[d]];
break;
} else {
higherDimSum += seqDistances[d] * rng[d][idxArr[d]];
break;
}
}
if (d >= idxArr.Length)
break;
}
#endregion
}
}
internal virtual void SetRangeFull(ILDenseStorage values) {
if (values.Size.NumberOfElements != 1 && values.Size.NumberOfElements != Size.NumberOfElements)
throw new ILArgumentException("source and destination array must have the same number of arguments");
ElementType[] myArr = GetArrayForWrite();
if (values.Size.NumberOfElements == 1) {
ElementType scal = values.GetValueTyped(0);
for (int i = 0; i < myArr.Length; i++) {
myArr[i] = scal;
}
} else {
ElementType[] valArr = values.GetArrayForRead();
System.Array.Copy(valArr,myArr,Size.NumberOfElements);
}
}
///
/// Alter elements of this storage adressed by sequential indices
///
/// array specifying the elements to be altered, sequential indexing
/// ILBaseArray of the same type than this array, holding the new values.
/// The number of elements of storage must match the
/// number of elements of indices. The only exception to this rule is if 'values' is a scalar array. The
/// single value of 'values' is than used to set all elements addressed by 'indices'.
/// For empty arrays, scalar or vectors, indices outside the current bounds for
/// this array will expand this array to the size neccessary.
/// For other arrays the sequential indices given must fit inside this arrays dimensions.
public virtual void SetRange(ILBaseArray indices, ILDenseStorage values) {
//if (object.Equals(indices,null))
// throw new ILArgumentException("indices given must not be null");
if (object.Equals(values, null))
throw new ILArgumentException("values given must not be null. Use A[ind] = null; if removal was intended.");
using (ILScope.Enter(indices)) {
#region set full shortcut
if (indices is ILFullRange || object.Equals(indices, null)) {
int pos;
ElementType[] myArray = GetArrayForWrite();
if (values.Size.NumberOfElements == 1) {
pos = Size.NumberOfElements;
ElementType val = values.GetValueTyped(0);
while (pos-- > 0)
myArray[pos] = val;
} else {
if (values.Size.NumberOfElements != Size.NumberOfElements)
throw new ILArgumentException("number of elements in source must match number of elements in destination array");
pos = 0;
foreach (ElementType val in values) {
myArray[pos++] = val;
}
}
} else if (indices.Size.NumberOfElements != values.Size.NumberOfElements
&& values.Size.NumberOfElements != 1)
throw new ILArgumentException("number of elements in source must match number of elements in destination array");
#endregion
if (indices.IsEmpty)
return;
if (indices.Storage is ILDenseStorage< double>) {
double maxIndex, minIndex;
ILDenseStorage< double> indStorage = indices.Storage as ILDenseStorage< double>;
indStorage.GetLimits(out minIndex, out maxIndex);
if (minIndex < 0)
throw new ILArgumentException("sequential indices can not be negative");
if ((int)maxIndex >= m_size.NumberOfElements) {
// handle resize
if (m_size.NumberOfDimensions == 2) {
if (m_size.NumberOfElements <= 1) {
// scalar or empty -> expand along 1
ExpandArray(new int[] { (int)maxIndex + 1, 1 });
} else if (m_size[0] > 1 && m_size[1] == 1) {
ExpandArray(new int[] { (int)maxIndex + 1, 1 });
} else if (m_size[0] == 1 && m_size[1] > 1) {
ExpandArray(new int[] { 1, (int)maxIndex + 1 });
} else
throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
} else
throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
}
ElementType[] myArray = GetArrayForWrite();
double[] indArray = indStorage.GetArrayForRead();
int len = indices.Size.NumberOfElements;
if (values.Size.NumberOfElements == 1) {
ElementType scalarElement = values.GetValueTyped(0);
for (int i = 0; i < len; ) {
myArray[(int)indArray[i++]] = scalarElement;
}
} else {
ElementType[] valArray = values.GetArrayForRead();
for (int i = 0; i < len; ) {
myArray[(int)indArray[i]] = valArray[i++];
}
}
} else {
throw new ILArgumentException("storage type of given indices is not supported");
}
}
}
#region HYCALPER AUTO GENERATED CODE
///
/// Alter elements of this storage adressed by sequential indices
///
/// array specifying the elements to be altered, sequential indexing
/// ILBaseArray of the same type than this array, holding the new values.
/// The number of elements of storage must match the
/// number of elements of indices. The only exception to this rule is if 'values' is a scalar array. The
/// single value of 'values' is than used to set all elements addressed by 'indices'.
/// For empty arrays, scalar or vectors, indices outside the current bounds for
/// this array will expand this array to the size neccessary.
/// For other arrays the sequential indices given must fit inside this arrays dimensions.
public virtual void SetRange(ILBaseArray indices, ILDenseStorage values) {
//if (object.Equals(indices,null))
// throw new ILArgumentException("indices given must not be null");
if (object.Equals(values, null))
throw new ILArgumentException("values given must not be null. Use A[ind] = null; if removal was intended.");
using (ILScope.Enter(indices)) {
#region set full shortcut
if (indices is ILFullRange || object.Equals(indices, null)) {
int pos;
ElementType[] myArray = GetArrayForWrite();
if (values.Size.NumberOfElements == 1) {
pos = Size.NumberOfElements;
ElementType val = values.GetValueTyped(0);
while (pos-- > 0)
myArray[pos] = val;
} else {
if (values.Size.NumberOfElements != Size.NumberOfElements)
throw new ILArgumentException("number of elements in source must match number of elements in destination array");
pos = 0;
foreach (ElementType val in values) {
myArray[pos++] = val;
}
}
} else if (indices.Size.NumberOfElements != values.Size.NumberOfElements
&& values.Size.NumberOfElements != 1)
throw new ILArgumentException("number of elements in source must match number of elements in destination array");
#endregion
if (indices.IsEmpty)
return;
if (indices.Storage is ILDenseStorage< Int64>) {
Int64 maxIndex, minIndex;
ILDenseStorage< Int64> indStorage = indices.Storage as ILDenseStorage< Int64>;
indStorage.GetLimits(out minIndex, out maxIndex);
if (minIndex < 0)
throw new ILArgumentException("sequential indices can not be negative");
if ((int)maxIndex >= m_size.NumberOfElements) {
// handle resize
if (m_size.NumberOfDimensions == 2) {
if (m_size.NumberOfElements <= 1) {
// scalar or empty -> expand along 1
ExpandArray(new int[] { (int)maxIndex + 1, 1 });
} else if (m_size[0] > 1 && m_size[1] == 1) {
ExpandArray(new int[] { (int)maxIndex + 1, 1 });
} else if (m_size[0] == 1 && m_size[1] > 1) {
ExpandArray(new int[] { 1, (int)maxIndex + 1 });
} else
throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
} else
throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
}
ElementType[] myArray = GetArrayForWrite();
Int64[] indArray = indStorage.GetArrayForRead();
int len = indices.Size.NumberOfElements;
if (values.Size.NumberOfElements == 1) {
ElementType scalarElement = values.GetValueTyped(0);
for (int i = 0; i < len; ) {
myArray[(int)indArray[i++]] = scalarElement;
}
} else {
ElementType[] valArray = values.GetArrayForRead();
for (int i = 0; i < len; ) {
myArray[(int)indArray[i]] = valArray[i++];
}
}
} else {
throw new ILArgumentException("storage type of given indices is not supported");
}
}
}
///
/// Alter elements of this storage adressed by sequential indices
///
/// array specifying the elements to be altered, sequential indexing
/// ILBaseArray of the same type than this array, holding the new values.
/// The number of elements of storage must match the
/// number of elements of indices. The only exception to this rule is if 'values' is a scalar array. The
/// single value of 'values' is than used to set all elements addressed by 'indices'.
/// For empty arrays, scalar or vectors, indices outside the current bounds for
/// this array will expand this array to the size neccessary.
/// For other arrays the sequential indices given must fit inside this arrays dimensions.
public virtual void SetRange(ILBaseArray indices, ILDenseStorage values) {
//if (object.Equals(indices,null))
// throw new ILArgumentException("indices given must not be null");
if (object.Equals(values, null))
throw new ILArgumentException("values given must not be null. Use A[ind] = null; if removal was intended.");
using (ILScope.Enter(indices)) {
#region set full shortcut
if (indices is ILFullRange || object.Equals(indices, null)) {
int pos;
ElementType[] myArray = GetArrayForWrite();
if (values.Size.NumberOfElements == 1) {
pos = Size.NumberOfElements;
ElementType val = values.GetValueTyped(0);
while (pos-- > 0)
myArray[pos] = val;
} else {
if (values.Size.NumberOfElements != Size.NumberOfElements)
throw new ILArgumentException("number of elements in source must match number of elements in destination array");
pos = 0;
foreach (ElementType val in values) {
myArray[pos++] = val;
}
}
} else if (indices.Size.NumberOfElements != values.Size.NumberOfElements
&& values.Size.NumberOfElements != 1)
throw new ILArgumentException("number of elements in source must match number of elements in destination array");
#endregion
if (indices.IsEmpty)
return;
if (indices.Storage is ILDenseStorage< Int32>) {
Int32 maxIndex, minIndex;
ILDenseStorage< Int32> indStorage = indices.Storage as ILDenseStorage< Int32>;
indStorage.GetLimits(out minIndex, out maxIndex);
if (minIndex < 0)
throw new ILArgumentException("sequential indices can not be negative");
if ((int)maxIndex >= m_size.NumberOfElements) {
// handle resize
if (m_size.NumberOfDimensions == 2) {
if (m_size.NumberOfElements <= 1) {
// scalar or empty -> expand along 1
ExpandArray(new int[] { (int)maxIndex + 1, 1 });
} else if (m_size[0] > 1 && m_size[1] == 1) {
ExpandArray(new int[] { (int)maxIndex + 1, 1 });
} else if (m_size[0] == 1 && m_size[1] > 1) {
ExpandArray(new int[] { 1, (int)maxIndex + 1 });
} else
throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
} else
throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
}
ElementType[] myArray = GetArrayForWrite();
Int32[] indArray = indStorage.GetArrayForRead();
int len = indices.Size.NumberOfElements;
if (values.Size.NumberOfElements == 1) {
ElementType scalarElement = values.GetValueTyped(0);
for (int i = 0; i < len; ) {
myArray[(int)indArray[i++]] = scalarElement;
}
} else {
ElementType[] valArray = values.GetArrayForRead();
for (int i = 0; i < len; ) {
myArray[(int)indArray[i]] = valArray[i++];
}
}
} else {
throw new ILArgumentException("storage type of given indices is not supported");
}
}
}
///
/// Alter elements of this storage adressed by sequential indices
///
/// array specifying the elements to be altered, sequential indexing
/// ILBaseArray of the same type than this array, holding the new values.
/// The number of elements of storage must match the
/// number of elements of indices. The only exception to this rule is if 'values' is a scalar array. The
/// single value of 'values' is than used to set all elements addressed by 'indices'.
/// For empty arrays, scalar or vectors, indices outside the current bounds for
/// this array will expand this array to the size neccessary.
/// For other arrays the sequential indices given must fit inside this arrays dimensions.
public virtual void SetRange(ILBaseArray indices, ILDenseStorage values) {
//if (object.Equals(indices,null))
// throw new ILArgumentException("indices given must not be null");
if (object.Equals(values, null))
throw new ILArgumentException("values given must not be null. Use A[ind] = null; if removal was intended.");
using (ILScope.Enter(indices)) {
#region set full shortcut
if (indices is ILFullRange || object.Equals(indices, null)) {
int pos;
ElementType[] myArray = GetArrayForWrite();
if (values.Size.NumberOfElements == 1) {
pos = Size.NumberOfElements;
ElementType val = values.GetValueTyped(0);
while (pos-- > 0)
myArray[pos] = val;
} else {
if (values.Size.NumberOfElements != Size.NumberOfElements)
throw new ILArgumentException("number of elements in source must match number of elements in destination array");
pos = 0;
foreach (ElementType val in values) {
myArray[pos++] = val;
}
}
} else if (indices.Size.NumberOfElements != values.Size.NumberOfElements
&& values.Size.NumberOfElements != 1)
throw new ILArgumentException("number of elements in source must match number of elements in destination array");
#endregion
if (indices.IsEmpty)
return;
if (indices.Storage is ILDenseStorage< Int16>) {
Int16 maxIndex, minIndex;
ILDenseStorage< Int16> indStorage = indices.Storage as ILDenseStorage< Int16>;
indStorage.GetLimits(out minIndex, out maxIndex);
if (minIndex < 0)
throw new ILArgumentException("sequential indices can not be negative");
if ((int)maxIndex >= m_size.NumberOfElements) {
// handle resize
if (m_size.NumberOfDimensions == 2) {
if (m_size.NumberOfElements <= 1) {
// scalar or empty -> expand along 1
ExpandArray(new int[] { (int)maxIndex + 1, 1 });
} else if (m_size[0] > 1 && m_size[1] == 1) {
ExpandArray(new int[] { (int)maxIndex + 1, 1 });
} else if (m_size[0] == 1 && m_size[1] > 1) {
ExpandArray(new int[] { 1, (int)maxIndex + 1 });
} else
throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
} else
throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
}
ElementType[] myArray = GetArrayForWrite();
Int16[] indArray = indStorage.GetArrayForRead();
int len = indices.Size.NumberOfElements;
if (values.Size.NumberOfElements == 1) {
ElementType scalarElement = values.GetValueTyped(0);
for (int i = 0; i < len; ) {
myArray[(int)indArray[i++]] = scalarElement;
}
} else {
ElementType[] valArray = values.GetArrayForRead();
for (int i = 0; i < len; ) {
myArray[(int)indArray[i]] = valArray[i++];
}
}
} else {
throw new ILArgumentException("storage type of given indices is not supported");
}
}
}
///
/// Alter elements of this storage adressed by sequential indices
///
/// array specifying the elements to be altered, sequential indexing
/// ILBaseArray of the same type than this array, holding the new values.
/// The number of elements of storage must match the
/// number of elements of indices. The only exception to this rule is if 'values' is a scalar array. The
/// single value of 'values' is than used to set all elements addressed by 'indices'.
/// For empty arrays, scalar or vectors, indices outside the current bounds for
/// this array will expand this array to the size neccessary.
/// For other arrays the sequential indices given must fit inside this arrays dimensions.
public virtual void SetRange(ILBaseArray indices, ILDenseStorage values) {
//if (object.Equals(indices,null))
// throw new ILArgumentException("indices given must not be null");
if (object.Equals(values, null))
throw new ILArgumentException("values given must not be null. Use A[ind] = null; if removal was intended.");
using (ILScope.Enter(indices)) {
#region set full shortcut
if (indices is ILFullRange || object.Equals(indices, null)) {
int pos;
ElementType[] myArray = GetArrayForWrite();
if (values.Size.NumberOfElements == 1) {
pos = Size.NumberOfElements;
ElementType val = values.GetValueTyped(0);
while (pos-- > 0)
myArray[pos] = val;
} else {
if (values.Size.NumberOfElements != Size.NumberOfElements)
throw new ILArgumentException("number of elements in source must match number of elements in destination array");
pos = 0;
foreach (ElementType val in values) {
myArray[pos++] = val;
}
}
} else if (indices.Size.NumberOfElements != values.Size.NumberOfElements
&& values.Size.NumberOfElements != 1)
throw new ILArgumentException("number of elements in source must match number of elements in destination array");
#endregion
if (indices.IsEmpty)
return;
if (indices.Storage is ILDenseStorage< float>) {
float maxIndex, minIndex;
ILDenseStorage< float> indStorage = indices.Storage as ILDenseStorage< float>;
indStorage.GetLimits(out minIndex, out maxIndex);
if (minIndex < 0)
throw new ILArgumentException("sequential indices can not be negative");
if ((int)maxIndex >= m_size.NumberOfElements) {
// handle resize
if (m_size.NumberOfDimensions == 2) {
if (m_size.NumberOfElements <= 1) {
// scalar or empty -> expand along 1
ExpandArray(new int[] { (int)maxIndex + 1, 1 });
} else if (m_size[0] > 1 && m_size[1] == 1) {
ExpandArray(new int[] { (int)maxIndex + 1, 1 });
} else if (m_size[0] == 1 && m_size[1] > 1) {
ExpandArray(new int[] { 1, (int)maxIndex + 1 });
} else
throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
} else
throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
}
ElementType[] myArray = GetArrayForWrite();
float[] indArray = indStorage.GetArrayForRead();
int len = indices.Size.NumberOfElements;
if (values.Size.NumberOfElements == 1) {
ElementType scalarElement = values.GetValueTyped(0);
for (int i = 0; i < len; ) {
myArray[(int)indArray[i++]] = scalarElement;
}
} else {
ElementType[] valArray = values.GetArrayForRead();
for (int i = 0; i < len; ) {
myArray[(int)indArray[i]] = valArray[i++];
}
}
} else {
throw new ILArgumentException("storage type of given indices is not supported");
}
}
}
#endregion HYCALPER AUTO GENERATED CODE
///
/// Create referencing or solid array from this array, with shifted dimensions.
///
/// Number of dimensions to shift the array.
/// Shifted ILDenseStorage of the same type.
/// Shift is done 'to the left'.
public virtual ILDenseStorage ShiftDimensions (int shift) {
return CreateShiftedStorage(shift);
}
#endregion
#region Reshape, Concat, Repmat - overriding ILBaseArray
///
/// reshape this storage
///
/// new dimensions of the storage.
/// This storage will be changed! The operation is cheap, since the
/// number of elements (and their values) do not change. The same countable array
/// is used in conjunction with a new dimension specifier.
///
/// If the number of elements in 'newDimension'
/// do not match the number of elements in this storage.
internal void Reshape(ILSize newDimensions) {
if (newDimensions.NumberOfElements != m_size.NumberOfElements)
throw new ILArgumentSizeException ("the number of elements must not change");
m_size = newDimensions;
}
///
/// reshape this storage
///
/// new dimension length of the storage.
/// This storage will be changed! The operation is cheap, since the
/// number of elements (and their values) do not change. The same underlying storage
/// is used in conjunction with the new dimension specifier.
///
/// If the number of elements in 'newDimension'
/// do not match the number of elements in this storage.
public void Reshape(params int[] dims) {
ILSize newDimension = new ILSize(dims);
Reshape(newDimension);
}
///
/// concatenate this storage
///
/// n dimensional storage
/// Index of dimension along which to concatenate the arrays.
/// If dim is larger than the number of dimensions of one of the arrays
/// its value will be used in modulus.
/// Array having the size of both input arrays laid beside one
/// another along the 's-dimension
/// The array returned will be a copy of both arrays involved. None
/// of the input arrays will be altered.
public virtual ILDenseStorage Concat(ILDenseStorage A, int dim) {
ILSize inDim = A.m_size;
for (int i = 0; i < Math.Max(inDim.NumberOfDimensions, m_size.NumberOfDimensions); i++) {
if (i != dim)
if (m_size[i] != inDim[i])
throw new ILArgumentSizeException("the length of dimensions of both arrays (except the dimension "
+ "to be concatenated) must match");
}
// concatenate
if (inDim.NumberOfElements == 1 && m_size.NumberOfElements == 1) {
// both scalars
int[] dims = new int[2] { 1, 1 };
dims[dim] = 2;
ElementType[] retArr = ILMemoryPool.Pool.New(2);
retArr[0] = m_data.Data[0];
retArr[1] = A.m_data.Data[0];
return CreateSelf(retArr, new ILSize(dims));
}
int lenOutArr = m_size.NumberOfElements + inDim.NumberOfElements;
int[] retDims = m_size.ToIntArray(dim+1);
retDims[dim] += inDim[dim];
ILSize retDimension = new ILSize(retDims);
ElementType[] retData = ILMemoryPool.Pool.New(retDimension.NumberOfElements);
ElementType[] myData = GetArrayForRead();
ElementType[] inData = A.GetArrayForRead();
int len1 = m_size.SequentialIndexDistance(dim + 1);
int len2 = inDim.SequentialIndexDistance(dim + 1);
int posOutArr = 0, inPos = 0, myPos = 0;
while (posOutArr < lenOutArr) {
for (int i = 0; i < len1; i++)
retData[posOutArr++] = myData[myPos++];
for (int i = 0; i < len2; i++)
retData[posOutArr++] = inData[inPos++];
}
return CreateSelf(retData,retDimension);
}
///
/// Replicate this storage to create a larger array.
///
/// Sizes description. This may be a
/// list or an array of integer values. If the number of elements in is
/// less the number of dimensions in this array, the trailing dimensions will
/// be set to 1 (singleton dimensions). On the other hand, if the number specified
/// is larger then the number of dimensions of this array, the result
/// will have its number of dimensions extended accordingly.
/// array which is made out of multiple copies of this array along
/// specified dimensions, according to .
internal virtual ILDenseStorage Repmat(params int[] sizes) {
if (m_size.NumberOfElements == 0)
return CreateSelf(new ILSize(sizes));
ILRightSideRange rsRange = new ILRightSideRange(m_size, sizes);
return CreateSubarrayStorage(rsRange);
// experimental: via subindexing full dimensions
//ILBaseArray[] dimArrays = new ILBaseArray[dims.Length];
//for (int i = 0; i < dimArrays.Length; i++) {
// dimArrays[i] = ILMath.cell(ILMath.full)[ILMath.zeros(1,dims[i])];
//}
//return Subarray(dimArrays);
//build return dimensions
//int[] newDim = new int[Math.Max(dims.Length, m_dimensions.NumberOfDimensions)];
//for (int d = 0; d < newDim.Length; d++) {
// if (d < dims.Length) {
// newDim[d] = m_dimensions[d] * dims[d];
// } else {
// newDim[d] = m_dimensions[d];
// }
//}
//ILSize outDim = new ILSize(true, newDim);
//if (m_dimensions.NumberOfElements == 0 || outDim.NumberOfElements == 0)
// return new ILDenseStorage(new ILCountableArray(0), outDim);
//ILDenseStorage ret = new ILDenseStorage(
// new ILCountableArray(outDim.NumberOfElements), outDim);
//ElementType[] retArray = ret.GetArrayForWrite();
//ElementType[] myArray = GetArrayForRead();
//int[] outStrides = outDim.GetSequentialIndexDistances(m_dimensions.NumberOfDimensions);
//int[] myStrides = m_dimensions.GetSequentialIndexDistances(m_dimensions.NumberOfDimensions);
//retArray[0] = myArray[0];
//if (outDim.NumberOfElements < ILNumerics.Settings.s_minParallelElement1Count) {
// for (int outPos = 1; outPos < outDim.NumberOfElements; ) {
// int inPos = 0;
// for (int d = m_dimensions.NumberOfDimensions; d-- > 0; ) {
// inPos += ((outPos / outStrides[d]) % m_dimensions[d])
// * myStrides[d];
// }
// retArray[outPos++] = myArray[inPos];
// }
//} else {
// System.Threading.Tasks.Parallel.For(1,outDim.NumberOfElements, i => {
// int inPos = 0;
// for (int d = m_dimensions.NumberOfDimensions; d-- > 0; ) {
// inPos += ((i / outStrides[d]) % m_dimensions[d])
// * myStrides[d];
// }
// retArray[i] = myArray[inPos];
// });
//}
//return ret;
}
///
/// Remove individual parts of a dimension from this storage
///
/// index of the dimension, where indices are to be removed
/// indices to be removed from , -1 for "wipe" (make this an empty storage)
/// The function directly operates on this storage! After the function returns,
/// this storage may have its dimensions changed!
internal virtual void Remove(int dimension, ILIntList indices) {
using (ILScope.Enter()) {
if (dimension >= Size.NumberOfDimensions)
throw new ILArgumentException("index out of range");
if (dimension == -1) {
Data = new ILCountableArray(0);
m_size = ILSize.Empty00;
return;
}
// TODO: may should be replaced with a faster (&fancier? ) version... ??
ILBaseArray[] dims = new ILBaseArray[Size.NumberOfDimensions];
ILIntList keepInd = ILIntList.Create();
ILIntList remvInd = indices;
int max = Size[dimension];
foreach (int i in indices)
if (i >= max || i < 0) throw new ILArgumentException("removal index out of range");
for (int i = 0; i < max; i++) {
if (!remvInd.Contains(i)) {
keepInd.Add(i);
}
}
// we give the indices to _keep_ to the subarray function
int keepIndCount = keepInd.Count;
ILArray remIndices = ILMath.array(keepInd.GetArray(), new ILSize(1, keepIndCount));
if (remIndices.Size.NumberOfElements == Size[dimension]) {
// nothing to do
return;
}
for (int i = 0; i < dims.Length; i++) {
dims[i] = ILMath.full;
}
dims[dimension] = remIndices;
ILDenseStorage ret = Subarray(dims);
Dispose(); // this will for reference element types (e.g. ILCell) also dispose the removed elements
Data = ret.Data;
m_size = ret.Size;
}
}
#endregion
#region serialize
///
/// Prepare for serialization.
///
/// Streaming Context - provided by the formatter.
/// nothing to do here
[OnSerializing]
private void OnSerialize(StreamingContext context) {
}
///
/// Post operations aftre deserializing is finished.
///
/// Streaming context provided by the formatter.
/// nothing to do here
[OnDeserialized]
void OnDeserialized(StreamingContext context) {
}
#endregion
#region single element access
///
/// Get single value from this storage.
///
/// Integer array holding the dimension specifier
/// Element at the position pointed to by idx.
internal override object GetValue(params int[] idx) {
return GetValueTyped(idx);
}
///
/// Get single value from this storage.
///
/// Integer array holding the dimension specifier
/// Element at the position pointed to by idx.
internal override ElementType GetValueTyped(params int[] idx) {
if (idx.Length == 1)
return m_data.Data[idx[0]];
int destIdx = idx[0], d, highDims;
if (destIdx >= m_size[0] || destIdx < 0)
throw new ILArgumentException("GetValue: index out of bound for dimensions: 0");
int [] seqDist = m_size.GetSequentialIndexDistances(0);
if (idx.Length <= m_size.NumberOfDimensions) {
for (d = 1; d < idx.Length - 1; d++) {
if (idx[d] >= m_size[d] || idx[d] < 0)
throw new ILArgumentException("GetValue: index out of bound for dimensions: " + d.ToString());
destIdx += idx[d] * seqDist[d];
}
for (highDims = idx[d]; d 0; d++) {
destIdx += (highDims % m_size[d]) * seqDist[d];
highDims /= m_size[d];
}
if (highDims > 0) throw new ILArgumentException ("GetValue: index out of bound!");
return m_data.Data[destIdx];
} else {
highDims = m_size.NumberOfDimensions;
for (d = 1; d < highDims; d++) {
if (idx[d] >= m_size[d] || idx[d] < 0)
throw new ILArgumentException("GetValue: index out of bound for dimensions: " + d.ToString());
destIdx += idx[d] * seqDist[d];
}
for (; d(new ElementType[1] { GetValueTyped(innerIndices) }, ILSize.Scalar1_1);
}
internal override ILBaseArray GetAsBaseArray() {
return new ILRetArray((ILDenseStorage)Clone());
}
///
/// Get single value from this storage by a single sequential access.
///
/// Integer array holding the dimension specifier
/// pointing to the value.
/// Out value: return position mapped to dimensions.
/// Object in the position pointed to by idx.
/// dims is the final position into the array for the sequential index specification idx.
internal override object GetValueSeq(int idx, ref int[] dims) {
int IdxCpy = idx;
for (int d = 0; d
/// Set single value to element at the specified index.
///
/// New value.
/// Index of the element to be altered.
internal override void SetValue(object value, params int[] idx) {
try {
SetValueTyped((ElementType)value, idx);
} catch (InvalidCastException) {
SetValueTyped((ElementType)Convert.ChangeType(value, typeof(ElementType)), idx);
}
}
///
/// Set value of element at the specified position.
///
/// new value
/// position of the element to be altered
/// This function does support automatic expansion of the array
/// if indices lay outside the dimension limits of the array. However, because
/// of ambiguity reasons this is not reliable supported for vector sized arrays.
internal override void SetValueTyped(ElementType value, params int[] idx) {
try {
if (idx.Length < 2) {
if (idx.Length == 1) {
if (idx[0] >= m_size.NumberOfElements)
throw new IndexOutOfRangeException();
GetArrayForWrite()[idx[0]] = value;
}
return;
}
int i = m_size.IndexFromArray(idx);
if (i >= m_size.NumberOfElements)
throw new IndexOutOfRangeException();
GetArrayForWrite()[i] = (ElementType)value;
} catch (Exception exc) {
if (exc is ILArgumentException
|| exc is IndexOutOfRangeException ) {
// expanding ?
int [] dimensions = m_size.ToIntArray(Math.Max(idx.Length,m_size.NumberOfDimensions));
bool mustExpand = false;
int i = m_size.IndexFromArray(ref mustExpand, ref dimensions, idx);
if (mustExpand) {
ExpandArray(dimensions);
m_data.Data[i] = value;
} else {
throw;
}
}
}
}
///
/// [depricated] Convert index array into sequential index for storage access.
///
/// int array with dimension specification.
/// Index of requested value inside the solid storage. This
/// value can directly be used to query the corresponding value via GetArrayForRead()[return_value].
///
/// This function is deprecated! Use instead!
/// If the length of idx is smaler than the number of dimensions
/// of this storage, the trailing dimensions will be replaced with "0". I.e
/// the first index of each non specified dimension will be used.
/// If length of idx is larger than the dimensions of this storage, the behavior
/// is undefined. Therefore this function should be enclosed in try, catch blocks
/// to handle this case!
internal int getBaseIndex(params int[] idx) {
// arghs! -> ugly! piuh!!
if (idx == null) throw new ILArgumentException("indices specified must not be null");
if (idx.Length < m_size.NumberOfDimensions) {
bool dummy;
int [] tmp = ILMemoryPool.Pool.New(m_size.NumberOfDimensions,true, out dummy);
for (int i = 0; i < idx.Length; i++) {
tmp[i] = idx[i];
}
return m_size.IndexFromArray(tmp);
}
return m_size.IndexFromArray(idx);
}
///
/// [depricated] Convert index array into sequential index for storage access. Ommit any bound checking.
///
/// int array with dimensions specification.
/// Output parameter. On return determine, if the index
/// specification points outside of the dimensions of this ILDenseStorage and the array
/// must be expanded before accessing elements on that position.
/// if the array was found to be expanded, this are the
/// needed dimension sizes for the new array. The sizes are computed from the range
/// specification given.
/// Index of requested value inside the solid storage. This
/// value may directly be used to query the value via m_data[return_value].
/// The value returned is valid for solid storages as well as for reference
/// storages.
///
///
/// idx must be not null and must contain at least one element.
/// If the length of idx is smaler than the number of dimensions
/// of this storage, the trailing dimensions will be replaced with "0". I.e
/// the first index of each non specified dimensions will be used.
/// If length of idx is larger than the dimensions of this storage, the index of
/// the expanded array will be returned.
internal int getBaseIndex(ref bool MustExpand, ref int[] dimensions, params int[] idx) {
int destIdx = 0;
if (idx.Length == 1) {
destIdx = idx[0];
if (destIdx < 0)
throw new ILArgumentException("check index for dimension 0!");
if (destIdx >= m_size.NumberOfElements) {
MustExpand = true;
dimensions[0] = destIdx + 1;
}
return destIdx;
}
return m_size.IndexFromArray(ref MustExpand, ref dimensions, idx);
}
///
/// Copy values of all elements into System.Array.
///
/// System.Array, holding all element values of this ILDenseStorage.
/// The System.Array may be predefined. If its length is sufficient, it will be used and
/// its leading elements will be overwritten when function returns. If 'result' is null or has too few elements,
/// it will be recreated from the ILNumerics memory pool.
public void ExportValues(ref ElementType[] result) {
if (result == null || result.Length < m_size.NumberOfElements)
result = ILMemoryPool.Pool.New(m_size.NumberOfElements);
int pos = 0;
foreach (ElementType v in this) {
result[pos++] = v;
}
}
///
/// Get direct reference to inner System.Array storage for write access
///
/// reference to inner System.Array
/// Altering this array can be done directly. If necessary, the array is detached before
/// returned. Watch the column order format of storages in ILNumerics! Keep in minds, the length
/// of the array may exceeds the number of elements.
/// Accessing the inner system array directly should be left to ILNumerics experts only!
/// Unless you really know, what you are doing, you should rather use the higher order access
/// methods provided by ILArray<T>! (You have been warned!)
internal ElementType[] GetArrayForWrite() {
if (m_data.ReferenceCount > 1) {
Detach();
}
return m_data.Data;
}
///
/// Get direct reference to inner System.Array storage for read access
///
/// reference to inner System.Array for reading
/// This method is provided for experts only! Altering elements of this
/// array may cause the data to be invalidated or corrupted! Use this array only for reading! Note
/// the ILNumerics array storage format (column major). Keep in mind, the length
/// of the array may exceeds the number of elements!
/// Accessing the inner system array directly should be left to ILNumerics experts only!
/// Unless you really know, what you are doing, you should rather use the higher order access
/// methods provided by ILArray<T>! (You have been warned!)
internal ElementType[] GetArrayForRead() {
//if (PendingTasks > 0)
// System.Threading.SpinWait.SpinUntil(() => { return PendingTasks == 0; });
return m_data.Data;
}
#endregion
///
/// Create lazy,shallow copy of this array
///
/// ILDenseStorage as copy of this storage.
/// The ILDenseStorage object returned will be of the same size and type than this object.
/// The copy is done lazy. This means, the new storage will at first share the memory
/// with that storage. This will take almost no memory / processor time. As soon as attempts
/// are made to alter the new storage, it will be detached from this storage and use own memeory.
internal override ILStorage Clone() {
return CreateSelf(m_data,m_size);
}
internal ILCountableArray GetDataArray() {
return m_data;
}
internal virtual void IndexSubrange(ILDenseStorage value, ILBaseArray[] range) {
using (ILScope.Enter(range)) {
if (Object.ReferenceEquals(value, null) || value.Size.NumberOfElements == 0) {
#region remove
if (range == null) return;
ILLeftSideRange rng = new ILLeftSideRange(Size, range);
if (rng.Expanding) {
throw new ILArgumentException("invalid range for removal specified");
}
if (rng.Size.NumberOfElements == 0) {
return;
}
int nonFullDims = 0;
int dimIdx = -1;
// check validity
for (int i = 0; i < rng.RangeArray.Length; i++) {
if (rng[i].Count != 1 || rng[i][0] >= 0) {
if (++nonFullDims > 1)
throw new ILArgumentException("for removal only one dimension can be 'non-full'");
dimIdx = i;
foreach (int ind in rng[i]) {
if (ind < 0) {
throw new ILArgumentException("invalid removal indices: all but at most one dimensions must be specified as 'full'. check dimension #" + i.ToString());
}
}
}
}
// remove
ILSize newDim = new ILSize(Size.ToIntArrayEx(rng.RangeArray.Length));
ILSize oldDimensions = Size;
try {
Reshape(newDim); // <- cheap!
if (dimIdx >= 0) {
Remove(dimIdx, rng[dimIdx]); // <- expensive!
} else {
// all dims full specified
Remove(dimIdx, null); // <- expensive!
}
} catch (Exception) {
Reshape(oldDimensions);
throw;
}
#endregion
} else {
#region setrange
if (range == null || range.Length == 0) {
return;
} else if (range.Length == 1) {
if (range[0] is ILDenseArray) {
SetRange(range[0] as ILDenseArray, value);
return;
} else if (range[0] is ILDenseArray) {
// special case? A[":;0:3;0:end;..."] -> multiple dimensions given as single string
string indStr = (string)(range[0] as ILDenseArray).GetValue(0);
string[] dimParts = indStr.Split(';');
if (dimParts.Length == 0) {
// empty range given
return;
} else if (dimParts.Length > 1) {
range = new ILBaseArray[dimParts.Length];
for (int i = 0; i < dimParts.Length; i++) {
range[i] = dimParts[i];
}
// re-enter function to push the new arrays into scope
IndexSubrange(value,range);
return;
} else {
ILBaseArray indices = ILRange.ParseDimension(indStr, Size.NumberOfElements);
if (indices is ILBaseArray) {
SetRangeFull(value);
} else {
SetRange(indices as ILDenseArray, value);
}
return;
}
} else if (range[0] is ILDenseArray) {
SetRange(range[0] as ILDenseArray, value);
return;
} else if (range[0] is ILDenseArray) {
SetRange(range[0] as ILDenseArray, value);
return;
} else if (range[0] is ILDenseArray) {
SetRange(range[0] as ILDenseArray, value);
return;
} else if (range[0] is ILLogical) {
SetRange(ILNumerics.ILMath.find(range[0] as ILLogical), value);
return;
} else if (range[0] is ILRetLogical) {
SetRange(ILNumerics.ILMath.find(range[0] as ILRetLogical), value);
return;
}
}
ILLeftSideRange rng = new ILLeftSideRange(Size, range);
if (rng.Expanding) {
ExpandArray(rng);
}
SetRange(rng, value);
#endregion
}
}
}
#region IEnumerable> Member
///
/// enumerator returning elements as ElementType
///
public override IEnumerator GetEnumerator ( ) {
int len = m_size.NumberOfElements;
ElementType[] myData = GetArrayForRead();
for (int i = 0; i < len; i++)
yield return myData[i];
}
#endregion
#region private helper
///
/// helper function to gather some parameters for partial dimension removal
///
/// object with index specifications. May be of
/// type ILBaseArray[] with numeric arrays or a string array according
/// to the format of .
///
/// Out parameter: index of dimension the indices to be removed lie in.
/// Indices to be removed.
/// Dimension structure, can be used to reshape the storage before the removal
/// If range comprises a range dimension specification which is smaller than
/// the actual number of dimension of this storage, the storage must be reshaped in advance of the removal.
/// This reshaping proccess will not be done inside this function! However
/// the dimension value returned reflects the size of the storage before removing and therefore
/// can be utilized for reshaping the storage.
/// If:
/// The length of range exceeds the dimensions of this storage.
/// More than one or less than one dimension of range was not null.
/// The type of range was invalid, or
/// Range is of type , but the element type is not numeric
///
internal void ExtractRemovalParameter(ILBaseArray[] rng, out int dimensionIdx, ref ILIntList indices, out ILSize dimensions) {
dimensionIdx = 0;
dimensions = null;
if (rng.Length > m_size.NumberOfDimensions)
throw new ILArgumentException("Error removing: dimension specification exceeds matrix dimensions.");
int specCount = 0;
int tmp = 0;
if (rng.Length == 1 && rng[0] is ILBaseArray) {
string allRangeString = (string)(rng[0] as ILBaseArray).GetValue(0);
string[] ranges = allRangeString.Split(';');
if (ranges.Length > 1) {
rng = new ILBaseArray[ranges.Length];
for (int i = 0; i < ranges.Length; i++) {
rng[i] = ranges[i];
}
}
}
int[] outDim = Size.GetReshapedSize(rng.Length);
for (int i = 0; i < rng.Length; i++) {
if (object.Equals(rng[i], null)) {
// nothing to remove
if (indices != null) {
indices.Clear();
}
return;
} else if (!rng[i].IsEmpty) {
if (rng[i] is ILDenseArray) {
string stringVal = (rng[i] as ILDenseArray).GetValue(0);
ILBaseArray indFromString = ILRange.ParseDimension(stringVal,outDim[i]);
if (!(indFromString is ILBaseArray)) {
if (specCount++ > 0) {
throw new ILArgumentException("only one dimension can be non-fully specified for removal");
}
dimensionIdx = i;
indices = new ILIntList(indFromString as ILDenseArray);
}
continue;
}
dimensionIdx = i;
if (specCount++ > 0) {
throw new ILArgumentException("only one dimension can be non-fully specified for removal");
}
if (rng[i] is ILBaseArray) {
// A[end + ...] given
Expression expr = (rng[i] as ILBaseArray).GetValue(0);
int exprVal = ILExpression.Evaluate(expr, Size[i] - 1);
indices = ILIntList.Create();
for (int p = 0; p < tmp; p++) {
indices.Add(exprVal);
}
} else if (rng[i] is ILLogical) {
ILArray ind = ILNumerics.ILMath.find((ILLogical) rng[i]);
tmp = ind.Size.NumberOfElements;
indices = ILIntList.Create();
for (int p = 0; p < tmp; p++) {
indices.Add((int)ind.GetValue(p));
}
} else if (rng[i] is ILRetLogical) {
ILArray ind = ILNumerics.ILMath.find((ILRetLogical) rng[i]);
tmp = ind.Size.NumberOfElements;
indices = ILIntList.Create();
for (int p = 0; p < tmp; p++) {
indices.Add((int)ind.GetValue(p));
}
/* !HC:TYPELIST:
floatInt16Int32Int64byte
*/
} else if (rng[i] is ILDenseArray ) {
ILDenseArray ind = rng[i] as ILDenseArray ;
tmp = ind.Size.NumberOfElements;
indices = ILIntList.Create();
for (int p = 0; p < tmp; p++) {
indices.Add((int)ind.GetValue(p));
}
#region HYCALPER AUTO GENERATED CODE
/* !HC:TYPELIST:
*/
} else if (rng[i] is ILDenseArray ) {
ILDenseArray ind = rng[i] as ILDenseArray ;
tmp = ind.Size.NumberOfElements;
indices = ILIntList.Create();
for (int p = 0; p < tmp; p++) {
indices.Add((int)ind.GetValue(p));
}
/* !HC:TYPELIST:
*/
} else if (rng[i] is ILDenseArray ) {
ILDenseArray ind = rng[i] as ILDenseArray ;
tmp = ind.Size.NumberOfElements;
indices = ILIntList.Create();
for (int p = 0; p < tmp; p++) {
indices.Add((int)ind.GetValue(p));
}
/* !HC:TYPELIST:
*/
} else if (rng[i] is ILDenseArray ) {
ILDenseArray ind = rng[i] as ILDenseArray ;
tmp = ind.Size.NumberOfElements;
indices = ILIntList.Create();
for (int p = 0; p < tmp; p++) {
indices.Add((int)ind.GetValue(p));
}
/* !HC:TYPELIST:
*/
} else if (rng[i] is ILDenseArray ) {
ILDenseArray ind = rng[i] as ILDenseArray ;
tmp = ind.Size.NumberOfElements;
indices = ILIntList.Create();
for (int p = 0; p < tmp; p++) {
indices.Add((int)ind.GetValue(p));
}
/* !HC:TYPELIST:
*/
} else if (rng[i] is ILDenseArray ) {
ILDenseArray ind = rng[i] as ILDenseArray ;
tmp = ind.Size.NumberOfElements;
indices = ILIntList.Create();
for (int p = 0; p < tmp; p++) {
indices.Add((int)ind.GetValue(p));
}
#endregion HYCALPER AUTO GENERATED CODE
} else
throw new ILArgumentTypeException("error removing: invalid dimensions specifier, dimension #" + i.ToString());
}
}
if (indices == null) {
dimensionIdx = 0;
dimensions = m_size;
//indices = new int[0] { };
return;
}
// if only one dimension specified -> make row vector
//if (rng.Length < 2) {
// outDim[1] = outDim[0];
// outDim[0] = 1;
// dimensionIdx = 1;
//}
dimensions = new ILSize(outDim);
}
///
/// Expanded this storage for index addressing outside of my dimensions
///
/// range specification with size for destination array
internal void ExpandArray (ILLeftSideRange range) {
int[] outDims;
int i= 0;
ILSize outDimensions;
if (range.Size.NumberOfDimensions > m_size.NumberOfDimensions) {
outDims = new int[range.Size.NumberOfDimensions];
for (; i < m_size.NumberOfDimensions; i ++) {
outDims[i] = (range.ExpandDimensions[i] > m_size[i]) ?
range.ExpandDimensions[i] : m_size[i];
}
for(; i < range.Size.NumberOfDimensions; i++)
outDims[i] = range.ExpandDimensions[i];
} else {
outDims = new int[m_size.NumberOfDimensions];
for (; i < range.Size.NumberOfDimensions; i ++) {
outDims[i] = (range.ExpandDimensions[i] > m_size[i]) ?
range.ExpandDimensions[i] : m_size[i];
}
for(; i < m_size.NumberOfDimensions; i++)
outDims[i] = m_size[i];
}
outDimensions = new ILSize(outDims);
ElementType [] outData = ILMemoryPool.Pool.New(outDimensions.NumberOfElements);
// transfer old data to new array
int [] tmpIdx = new int[outDims.Length];
for (i = 0; i < m_size.NumberOfElements; i++) {
ElementType tmp = (ElementType)GetValueSeq(i,ref tmpIdx);
outData[outDimensions.IndexFromArray(tmpIdx)] = tmp;
}
// exchange my data
Data = new ILCountableArray(outData, outDimensions.NumberOfElements);
m_size = outDimensions;
}
///
/// Expand this storage for index addressing outside of my dimensions
///
/// sizes of dimensions for the new storage
protected void ExpandArray(int[] indices) {
if (indices.Length == 2 && (indices[0] * indices[1] == 0)) {
if (indices[0] > 0)
indices[1] = 1;
else if (indices[1] > 0)
indices[0] = 1;
}
ILSize outDimensions = new ILSize(indices);
bool cleared;
ElementType [] outData = ILMemoryPool.Pool.New(outDimensions.NumberOfElements,true,out cleared);
// transfer old data to new array
int [] tmpIdx = new int[indices.Length];
for (int i = 0; i < m_size.NumberOfElements; i++) {
ElementType tmpData = (ElementType)GetValueSeq(i,ref tmpIdx);
outData[outDimensions.IndexFromArray(tmpIdx)] = tmpData;
}
// replace with my data
Data = new ILCountableArray(outData,outDimensions.NumberOfElements);
m_size = outDimensions;
}
///
/// Copy upper triangular part of this array into new solid array.
///
/// Length of first dimension of destination array.
/// Solid array of size [n x {ThisColumnCount})].
internal ILDenseStorage copyUpperTriangle(int n) {
ILDenseStorage ret = new ILDenseStorage(new ILSize(n,n));
ElementType[] arr = ret.GetArrayForWrite();
ElementType[] myData = GetArrayForRead();
if (m_size[0] == n) {
for (int rcount = 0 , pos = 0; rcount < n; rcount++) {
for (int i = 0; i <= rcount; i++) {
arr[pos] = myData[pos++];
}
pos += (n - rcount - 1);
}
} else {
for (int rcount = 0 , posIn = 0, posOut = 0, lenA = m_size[0]; rcount < n; rcount++) {
for (int i = 0; i <= rcount; i++) {
arr[posOut++] = myData[posIn++];
}
posOut += (n - rcount - 1);
posIn += (lenA - rcount - 1);
}
}
return ret;
}
///
/// Copy lower triangular part of this array into new solid array.
///
/// Solid array of same size than this array.
/// If this is not a 2D array, only the first dimension is referenced.
internal ILDenseStorage copyLowerTriangle() {
int n = m_size[0],pos = 0;
ILDenseStorage ret = new ILDenseStorage(new ILSize(n,n));
ElementType[] arr = ret.GetArrayForRead();
ElementType[] myData = GetArrayForRead();
for (int c = 0; c < m_size[1]; c++) {
pos += c;
for (int r = c; r < n; r++,pos++) {
arr[pos] = myData[pos];
pos++;
}
}
return ret;
}
#endregion
}
}