/// <summary> /// Deep reference from this ILCell /// </summary> /// <returns>ILCell having all elements replaced with references to their originals.</returns> /// <remarks>For all elements of supported types (ILBaseArray,ILCell), the reference creation will be done /// recursively. </remarks> public override ILBaseArray CreateReference() { ILArray <ILBaseArray> ret1 = (ILArray <ILBaseArray>)base.CreateReference(); ILCell ret2 = new ILCell(ret1); ret1.Dispose(); ret2.DeepReferenceElements(); return(ret2); }
/// <summary> /// get/set/remove single element /// </summary> /// The type of access depends on the length of indices. /// <paramref name="indices" value="index to element"/> /// <value>inner element, new inner element or null</value> /// <remarks>If indices contains only one element, the array will be accessed via sequential index access. /// This is sometimes called "linear" index access also. Sequential index access reflects the index of internal storage /// the way the data are actually organized in memory. This access method is mainly convinient for vectors where you are not interested of orientation. /// The following example demonstrates sequential index access for ILArray's (which also holds for ILCells): /// <example><code> /// ILArray<double> A = new ILArray<double>(1.0,12.0); /// A[2] gives: 3.0 /// </code>But the transpose /// <code> /// A.T[2] gives also: 3.0 /// </code> /// For matrices and N-dimensional arrays this holds as well: /// <code> /// ILArray<double> A = new ILArray<double>(1.0,12.0); /// A = /// [1.0 4.0 /// 2.0 5.0 /// 3.0 6.0 /// /// 7.0 10.0 /// 8.0 11.0 /// 9.0 12.0] /// /// A = ILMath.Reshape(A,3,2,2); /// A[10] gives 11.0 /// A[10,1] gives ILArgumentException -> out of range /// A[2,1,1] gives 12.0 /// A[2,1] gives 6.0 (set trailing dimension to '0')</code></example> /// <para>For get access the array returned will be a reference to the element addressed.</para> /// <para>If the element addressed is a ILCell itself, a deep reference to this element will be returned instead. /// I.e. all elements of the ILCell will be recursively replaced with references to itself.</para> /// <para> /// <list type="bullet"> /// <listheader>The type of the element returned depends on the type of the element addressed:</listheader> /// <item>For ILArray<BaseT> the array returned will be a reference to the original array (same type and size).</item> /// <item>For ILCell the ILBaseArray returned is a deep reference of the original element stored.</item> /// <item>for other types the behavior is undefined. (since other types are not implemented yet ;)</item> /// </list> </para> /// <para>This indexer may also be used for direct access to elements of elements of this cell: /// <example> /// <code> /// ILCell innerCell = new ILCell(2,1); /// innerCell[0] = ILMath.vector(10,200); /// innerCell[1] = ILArray<int>(-10,-20,-30); /// ILCell cell = new ILCell(2,1); /// cell[0] = innerCell; /// cell[1] = new ILArray<string>("foobla"); /// // cell is now: /// // [ILCell,(1x2)] /// // [innerCell[0], ILArray<double>(1x181)] /// // [innerCell[0], ILArray<double>(1x3)] /// // [ILArray<string>,(1x1)] /// /// cell[0,0] -> will give innerCell eq. ILCell (1x2) /// cell[0,1] -> will give ILArray<string> /// cell[0,0,0,1] -> will give innerCell[1] eq. ILArray<int>(1x3) /// </code> /// </example> /// In the last example above the trailing indices specified make the indexer walk down into the ILCell element and retrieve /// the content of this element. This kind of index access may be done as deep as you want. Just /// append the inner indices into inner elements to the right side of index specification. Addressing inner elements /// this way is the only way to alter elements <b>directly</b> inside the ILCell. </para> /// <para>For set access the element <code>value</code> will directly be stored in the ILCell. No copy/reference will be done for it!</para></remarks> public new ILBaseArray this[params int[] indices] { get{ int mydimlen = m_dimensions.NumberOfDimensions; if (indices.Length <= mydimlen) { // address this ILCell ILBaseArray ret = base[indices].GetValue(0, 0); if (object.Equals(ret, null)) { return(null); } else if (ret is ILArray <ILBaseArray> ) { ILArray <ILBaseArray> tmp = (ILArray <ILBaseArray>)ret; ILCell retC = new ILCell(tmp).DeepReferenceElements(); return(retC); } else if (ret is ILLogicalArray) { return(((ILLogicalArray)ret).C); } else { return((ILBaseArray)ret.Clone()); } } else { // address element of an element of this ILCell int[] innerIndices = new int[indices.Length - mydimlen]; int[] myIndices = new int[mydimlen]; int i = 0; for (; i < mydimlen; i++) { myIndices[i] = indices[i]; } for (int n = 0; i < indices.Length; i++) { innerIndices[n++] = indices[i]; } ILBaseArray innerElement = GetValue(myIndices); if (innerElement is ILCell) { return(((ILCell)innerElement)[innerIndices]); } else if (innerElement is ILArray <double> ) { return(((ILArray <double>)innerElement)[innerIndices]); } else { throw new ILArgumentTypeException("inner cell element type is not supported for deep index access!"); } } } set { if (Object.ReferenceEquals(value, null)) { throw new ILArgumentException("cell removal is not supported for single integer indexing! The value specified must not be null!"); } int mydimlen = m_dimensions.NumberOfDimensions; if (indices.Length <= mydimlen) { // address this ILCell SetValue((ILBaseArray)value.Clone(), indices); } else { // address element of an element of this ILCell int[] innerIndices = new int[indices.Length - mydimlen]; int[] myIndices = new int[mydimlen]; int i = 0; for (; i < mydimlen; i++) { myIndices[i] = indices[i]; } for (int n = 0; i < indices.Length; i++) { innerIndices[n++] = indices[i]; } ILBaseArray innerElement = GetValue(myIndices); if (innerElement is ILCell) { ((ILCell)innerElement)[innerIndices] = (ILBaseArray)value.Clone(); } else if (value is ILArray <double> && innerElement is ILArray <double> ) { ((ILArray <double>)innerElement)[innerIndices] = ((ILArray <double>)value).C; } else if (value is ILArray <complex> && innerElement is ILArray <complex> ) { ((ILArray <complex>)innerElement)[innerIndices] = ((ILArray <complex>)value).C; } else if (value is ILArray <byte> && innerElement is ILArray <byte> ) { ((ILArray <byte>)innerElement)[innerIndices] = ((ILArray <byte>)value).C; } else { throw new ILArgumentTypeException("right side argument type is not supported in this context! The value must have the same type as the inner array of the cell!"); } } } }