export { Base };

/**
 * A placeholder for tensor.
 *
 *   - In Operation.TwinArray.operation_append_Xxx(), it is used for tracking a tensor's final operation which should be responsible
 *       for destroying the tensor.
 *
 *   - In operation's .apply(), it is used for transferring tensor to the next sub operation.
 *
 *
 * @member {Operation.Base} finalOperationOld
 *   The previous finalOperation. When new finalOperation is set, the finalOperationOld.setKeepInputTensor_IfNotLastOperation_Or_In()
 * usually should be called to adjust tensor destroying behavior (since it is no longer the final operation of the tensor).
 *
 * @member {Operation.Base} finalOperation
 *   The operation uses this tensor at final. It should be responsible for destroying this tensor. If null, this tensor is
 * not used by any operation.
 *
 * @member {tf.tensor} realTensor
 *   The real tensor represented by this placeholder. It is filled dynamically in an operation's apply() method.
 *
 * @member {ActivationEscaping.ScaleBoundsArray} scaleBoundsArray
 *   The element value bounds (per channel) of the tensor. Usually, it is from the output of the previous operation's value bounds
 * set. It will be kept (not cloned) directly. So caller should use them carefully.
 *
 */
class Base {

  /**
   *
   */
  constructor() {
    this.finalOperationOld = null;
    this.finalOperation = null;
    this.realTensor = null;
  }

  /**
   *
   * @param {ActivationEscaping.ScaleBoundsArray} scaleBoundsArray  The tensor placeholder's ScaleBoundsArray.
   */
  set_height_width_channelCount_scaleBoundsArray(
    height, width, channelCount, channelCount_lowerHalf, channelCount_higherHalf, scaleBoundsArray ) {
    this.height = height;
    this.width = width;
    this.channelCount = channelCount;
    this.channelCount_lowerHalf = channelCount_lowerHalf;
    this.channelCount_higherHalf = channelCount_higherHalf;
    this.scaleBoundsArray = scaleBoundsArray;
  }

  /**
   * Note: The .finalOperationOld, finalOperation and .realTensor are not modified by this method.
   *
   * @param {TensorPlaceholder} aTensorPlaceholder
   *   The tensor placeholder's height, width, channelCount, scaleBoundsArray will be used directly (i.e. not cloned) by this
   * tensor placeholder. If null, these properties will be set to undefined.
   */
  set_height_width_channelCount_scaleBoundsArray_byTensorPlaceholder( aTensorPlaceholder ) {
    if ( aTensorPlaceholder ) {
      this.set_height_width_channelCount_scaleBoundsArray(
        aTensorPlaceholder.height, aTensorPlaceholder.width,
        aTensorPlaceholder.channelCount, aTensorPlaceholder.channelCount_lowerHalf, aTensorPlaceholder.channelCount_higherHalf,
        aTensorPlaceholder.scaleBoundsArray );
    } else {
      this.set_height_width_channelCount_scaleBoundsArray(
        undefined, undefined,
        undefined, undefined, undefined,
        undefined );
    }
  }

}

@@ -2915,10 +2915,838 @@
  %7D%0A  %7D%0A%0A
+  /**%0A   *%0A   * @param %7BTensorPlaceholder%7D aTensorPlaceholder  The tensor placeholder to be comapred.%0A   *%0A   * @return %7Bboolean%7D%0A   *   Return true, if this tensor placeholder's height, width, channelCount are the same as aTensorPlaceholder. Note: the%0A   * .channelCount_lowerHalf and .channelCount_higherHalf are not compared.%0A   */%0A  is_height_width_channelCount_same_byTensorPlaceholder( aTensorPlaceholder ) %7B%0A    if (   ( this.height != aTensorPlaceholder.height )%0A        %7C%7C ( this.width != aTensorPlaceholder.width )%0A        %7C%7C ( this.channelCount != aTensorPlaceholder.channelCount )%0A%0A        //%7C%7C ( this.channelCount_lowerHalf != aTensorPlaceholder.channelCount_lowerHalf )%0A        //%7C%7C ( this.channelCount_higherHalf != aTensorPlaceholder.channelCount_higherHalf )%0A       )%0A      return false;%0A%0A    return true;%0A  %7D%0A%0A
 %7D%0A

Update TensorPlaceholder.js