///
/// 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.Linq;
using System.Text;
using ILNumerics.Storage;
using ILNumerics.Exceptions;
namespace ILNumerics {
///
/// Rectangular array, used as output parameter only
///
/// Inner type. This will mostly be a system numeric type or a
/// complex floating point type.
/// This class extends the primary ILArray by optimizing its behavior for the case when used as an
/// output parameter of functions.When writing your own function all output parameters should be of type ILOutArray. Do not
/// use out ILArray! Similary, all return types should be of type and all input parameters of type .
/// Other than being used to retrieve results from functions, ILOutArray should not be used.
///
///
///
///
[Serializable]
public sealed class ILOutArray : ILDenseArray {
#region attributes
private ILArray m_originalArray;
private static bool s_isTempArray = false;
#endregion
#region constructors
///
/// Create new output parameter array
///
/// Dense storage for the new array
internal ILOutArray(ILDenseStorage storage)
: base(storage, s_isTempArray) {
//ILScope.Context.RegisterArray(this);
}
#endregion
#region implicit cast operators
#region constructional operators
/////
///// Implicitly convert scalar to array of size 1x1 (scalar).
/////
///// System type of size scalar
///// New ILOutArray of type ILOutArray ]]> of size 1x1
///// holding the only element with value of val.
/////
//public static implicit operator ILOutArray (ElementType val) {
// ILOutArray ret = new ILOutArray(
// new ILDenseStorage(
// new ElementType[1] {val},
// new ILSize(1,1)));
// return ret;
//}
/////
///// implicitly cast one dimensional System.Array to ILNumerics array (vector)
/////
///// 1 dimensional system array, arbitrary type
///// ILNumerics array of same element type as elements of A.
///// Row vector. If A is null: empty array.
///// The System.Array A will directly be used for the new ILNumerics array!
///// No copy will be done! Make sure, not to reference A after this conversion!
//public static implicit operator ILOutArray (ElementType[] A) {
// if (A == null) {
// ILDenseStorage dS = new ILDenseStorage(new ElementType[0], ILSize.Empty00);
// return new ILOutArray(dS);
// }
// return new ILOutArray(A,1,A.Length); // constructor will register the array in scope context!
//}
/////
///// implicitly convert n-dimensional System.Array to ILNumerics array
/////
///// arbitrarily sized System.Array
///// If A is null: empty array. Else: new ILNumerics array of the same size as A
///// The inner type of input array must match the requested type
///// . The resulting ILOutArray will reflect all dimensions of
///// A. Elements of A will get copied to elements of output array (shallow copy).
///// if type of input does not match
///// ElementType
//public static implicit operator ILOutArray (Array elements) {
// if (elements == null || elements.Length == 0) {
// return new ILOutArray(ILSize.Empty00);
// }
// if (elements.GetType().GetElementType() != typeof(ElementType))
// throw new ILCastException("inner type of System.Array must match");
// int [] dims = new int[elements.Rank];
// ElementType [] retArr = ILMemoryPool.Pool.New(elements.Length);
// int posArr = 0;
// for (int i = 0; i < dims.Length; i++) {
// dims[i] = elements.GetLength(dims.Length-i-1);
// }
// foreach (ElementType item in elements)
// retArr[posArr++] = item;
// ILOutArray ret = new ILOutArray(retArr,dims);
// return ret;
//}
/////
///// implicitly cast two dimensional System.Array to ILNumerics array
/////
///// 2D System.Array
///// If A is null: empty array. ILNumerics array of same size and type as A otherwise.
//public static implicit operator ILOutArray(ElementType[,] A) {
// if (A == null || A.Length == 0) {
// return new ILOutArray(ILSize.Empty00);
// }
// int[] dims = new int[2];
// ElementType[] retArr = ILMemoryPool.Pool.New(A.Length);
// int posArr = 0;
// for (int i = 0; i < 2; i++) {
// dims[i] = A.GetLength(dims.Length - i - 1);
// }
// foreach (ElementType item in A)
// retArr[posArr++] = item;
// ILOutArray ret = new ILOutArray(retArr, dims);
// return ret;
//}
/////
///// implicitly cast three dimensional System.Array to ILNumerics array
/////
///// 3D System.Array
///// If A is null: empty array. ILNumerics array of same size and type as A otherwise.
//public static implicit operator ILOutArray(ElementType[,,] A) {
// if (A == null || A.Length == 0) {
// return new ILOutArray(ILSize.Empty00);
// }
// int[] dims = new int[3];
// ElementType[] retArr = ILMemoryPool.Pool.New(A.Length);
// int posArr = 0;
// for (int i = 0; i < 3; i++) {
// dims[i] = A.GetLength(dims.Length - i - 1);
// }
// foreach (ElementType item in A)
// retArr[posArr++] = item;
// ILOutArray ret = new ILOutArray(retArr, dims);
// return ret;
//}
#endregion
#region conversional operators
///
/// Creates an output parameter type array from regular array
///
/// Original array
/// Output parameter type array, references the original array
public static implicit operator ILOutArray(ILArray A) {
if (object.Equals(A, null))
return null;
// we over take the storage (identical reference) to the new OutArray
// and store the reference to the original as well.
// It will be needed to synchronize changes to the denseStorage later (on Remove and Expand).
ILOutArray ret = new ILOutArray(A.Storage);
ret.m_originalArray = A;
return ret;
}
#endregion
#endregion
#region memory management
///
/// Replace the elements of this array with another array's elements, preventing memory leaks
///
/// New array
public ILRetArray a {
set { Assign(value); }
get { return this.C; }
}
///
/// Replaces storage of this array with new array elements, registers this array for out-of-scope disposal
///
/// New array
public void Assign(ILRetArray value) {
if (!IsDisposed)
Storage.Dispose();
ILDenseStorage storage = value.GiveStorageAwayOrClone();
m_storage = storage;
if (!object.ReferenceEquals(m_originalArray, null)) {
// update original array as well
(m_originalArray as ILDenseArray).Storage = storage;
}
//ILScope.Context.RegisterArray(this);
}
internal override bool EnterScope() {
return false;
}
#endregion
#region mutability + indexer
///
/// Set single value to element at index specified
///
/// New value
/// Index of element to be altered
public void SetValue(ElementType value, params int[] idx) {
Storage.SetValueTyped(value, idx);
}
///
/// Alter range of this array
///
/// Array with new values
/// Range specification
public void SetRange(ILInArray value, params ILBaseArray[] range) {
using (ILScope.Enter(value))
using (ILScope.Enter(range)) {
if (object.Equals(value, null)) {
Storage.IndexSubrange(null, range);
} else {
using (ILScope.Enter(value))
Storage.IndexSubrange(value.Storage, range);
}
}
}
///
/// Subarray creation/manipulation/deletion
///
/// Range specification, defining the size of the subarray
/// Subarray as copy of this array
public ILRetArray this[params ILBaseArray[] range] {
get {
using (ILScope.Enter(range))
return new ILRetArray(Storage.Subarray(range));
}
set {
SetRange(value, range);
}
}
#endregion
}
}