function layer = flattenLayer(nameValueArgs)
% flattenLayer   Flatten Layer
%
% The flatten layer flattens the spatial dimensions of the input into a
% single channel. The layer preserves the observation dimension and the
% sequence dimension after flattening. For example:
%
%   Description         | Size                        | Flattened size
%   ----------------------------------------------------------------------
%   Feature data        | C x N                       | C x N
%   Images              | H x W x C x N               | (H*W*C) x N
%   3-D images          | H x W x D x C x N           | (H*W*D*C) x N
%   Vector sequences    | C x N x S                   | C x N x S
%   Image sequences     | H x W x C x N x S           | (H*W*C) x N x S
%   3-D image sequences | H x W x D x C x N x S       | (H*W*D*C) x N x S
%
%   layer = flattenLayer creates a flatten layer.
%
%   layer = flattenLayer('Name',name) also specifies the layer name.
%
%   Example:
%       % Apply 2-D convolution to sequences of images.
%
%       % Create layer array
%       layers = [ ...
%           sequenceInputLayer([28 28 1])
%           sequenceFoldingLayer('Name', 'seqfold')
%           convolution2dLayer(5, 20)
%           reluLayer()
%           maxPooling2dLayer(2, 'Stride', 2)
%           sequenceUnfoldingLayer('Name', 'sequnfold')
%           flattenLayer()
%           lstmLayer(128, 'OutputMode', 'last')
%           fullyConnectedLayer(2)
%           softmaxLayer()
%           classificationLayer() ];
%
%       % Convert layers to a layer graph. 
%       lgraph = layerGraph(layers)
% 
%       % Connect sequence folding and unfolding layers.
%       lgraph = connectLayers(lgraph, 'seqfold/miniBatchSize', 'sequnfold/miniBatchSize');
%
%   See also nnet.cnn.layer.FlattenLayer, sequenceFoldingLayer,
%   sequenceUnfoldingLayer, lstmLayer.
%
%   <a href="matlab:helpview('deeplearning','list_of_layers')">List of Deep Learning Layers</a>

%   Copyright 2018-2021 The MathWorks, Inc.

arguments
    nameValueArgs.Name {iAssertValidLayerName} = '';
end
nameValueArgs.Name = convertStringsToChars(nameValueArgs.Name);

% Create an internal representation of a flatten layer.
internalLayer = nnet.internal.cnn.layer.Flatten(nameValueArgs.Name, []);

% Pass the internal layer to a function to construct a user visible
% flatten layer.
layer = nnet.cnn.layer.FlattenLayer(internalLayer);
end

function iAssertValidLayerName(name)
nnet.internal.cnn.layer.paramvalidation.validateLayerName(name)
end
