$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r52382 - in sandbox/numeric_bindings: boost/numeric/bindings/lapack/computational boost/numeric/bindings/lapack/detail libs/numeric/bindings/tools libs/numeric/bindings/tools/templates/computational
From: rutger_at_[hidden]
Date: 2009-04-14 05:10:20
Author: rutger
Date: 2009-04-14 05:10:19 EDT (Tue, 14 Apr 2009)
New Revision: 52382
URL: http://svn.boost.org/trac/boost/changeset/52382
Log:
Added support for lapack/stemr
Added:
   sandbox/numeric_bindings/boost/numeric/bindings/lapack/computational/stemr.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/stemr.hpp   (contents, props changed)
Text files modified: 
   sandbox/numeric_bindings/boost/numeric/bindings/lapack/detail/lapack.h       |    30 ++++++++++++++++++++++++++++++          
   sandbox/numeric_bindings/boost/numeric/bindings/lapack/detail/lapack_names.h |     6 ++++++                                  
   sandbox/numeric_bindings/libs/numeric/bindings/tools/lapack_generator.py     |     2 +-                                      
   3 files changed, 37 insertions(+), 1 deletions(-)
Added: sandbox/numeric_bindings/boost/numeric/bindings/lapack/computational/stemr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/boost/numeric/bindings/lapack/computational/stemr.hpp	2009-04-14 05:10:19 EDT (Tue, 14 Apr 2009)
@@ -0,0 +1,333 @@
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_COMPUTATIONAL_STEMR_HPP
+#define BOOST_NUMERIC_BINDINGS_LAPACK_COMPUTATIONAL_STEMR_HPP
+
+#include <boost/assert.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/numeric/bindings/lapack/detail/lapack.h>
+#include <boost/numeric/bindings/lapack/workspace.hpp>
+#include <boost/numeric/bindings/traits/detail/array.hpp>
+#include <boost/numeric/bindings/traits/detail/utils.hpp>
+#include <boost/numeric/bindings/traits/is_complex.hpp>
+#include <boost/numeric/bindings/traits/is_real.hpp>
+#include <boost/numeric/bindings/traits/traits.hpp>
+#include <boost/numeric/bindings/traits/type_traits.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost {
+namespace numeric {
+namespace bindings {
+namespace lapack {
+
+//$DESCRIPTION
+
+// overloaded functions to call lapack
+namespace detail {
+    inline void stemr( char const jobz, char const range, integer_t const n,
+            float* d, float* e, float const vl, float const vu,
+            integer_t const il, integer_t const iu, integer_t& m, float* w,
+            float* z, integer_t const ldz, integer_t const nzc,
+            integer_t* isuppz, logical_t& tryrac, float* work,
+            integer_t const lwork, integer_t* iwork, integer_t const liwork,
+            integer_t& info ) {
+        LAPACK_SSTEMR( &jobz, &range, &n, d, e, &vl, &vu, &il, &iu, &m, w, z,
+                &ldz, &nzc, isuppz, &tryrac, work, &lwork, iwork, &liwork,
+                &info );
+    }
+    inline void stemr( char const jobz, char const range, integer_t const n,
+            double* d, double* e, double const vl, double const vu,
+            integer_t const il, integer_t const iu, integer_t& m, double* w,
+            double* z, integer_t const ldz, integer_t const nzc,
+            integer_t* isuppz, logical_t& tryrac, double* work,
+            integer_t const lwork, integer_t* iwork, integer_t const liwork,
+            integer_t& info ) {
+        LAPACK_DSTEMR( &jobz, &range, &n, d, e, &vl, &vu, &il, &iu, &m, w, z,
+                &ldz, &nzc, isuppz, &tryrac, work, &lwork, iwork, &liwork,
+                &info );
+    }
+    inline void stemr( char const jobz, char const range, integer_t const n,
+            float* d, float* e, float const vl, float const vu,
+            integer_t const il, integer_t const iu, integer_t& m, float* w,
+            traits::complex_f* z, integer_t const ldz, integer_t const nzc,
+            integer_t* isuppz, logical_t& tryrac, float* work,
+            integer_t const lwork, integer_t* iwork, integer_t const liwork,
+            integer_t& info ) {
+        LAPACK_CSTEMR( &jobz, &range, &n, d, e, &vl, &vu, &il, &iu, &m, w,
+                traits::complex_ptr(z), &ldz, &nzc, isuppz, &tryrac, work,
+                &lwork, iwork, &liwork, &info );
+    }
+    inline void stemr( char const jobz, char const range, integer_t const n,
+            double* d, double* e, double const vl, double const vu,
+            integer_t const il, integer_t const iu, integer_t& m, double* w,
+            traits::complex_d* z, integer_t const ldz, integer_t const nzc,
+            integer_t* isuppz, logical_t& tryrac, double* work,
+            integer_t const lwork, integer_t* iwork, integer_t const liwork,
+            integer_t& info ) {
+        LAPACK_ZSTEMR( &jobz, &range, &n, d, e, &vl, &vu, &il, &iu, &m, w,
+                traits::complex_ptr(z), &ldz, &nzc, isuppz, &tryrac, work,
+                &lwork, iwork, &liwork, &info );
+    }
+}
+
+// value-type based template
+template< typename ValueType, typename Enable = void >
+struct stemr_impl{};
+
+// real specialization
+template< typename ValueType >
+struct stemr_impl< ValueType, typename boost::enable_if< traits::is_real<ValueType> >::type > {
+
+    typedef ValueType value_type;
+    typedef typename traits::type_traits<ValueType>::real_type real_type;
+
+    // user-defined workspace specialization
+    template< typename VectorD, typename VectorE, typename VectorW,
+            typename MatrixZ, typename VectorISUPPZ, typename WORK,
+            typename IWORK >
+    static void invoke( char const jobz, char const range, integer_t const n,
+            VectorD& d, VectorE& e, real_type const vl, real_type const vu,
+            integer_t const il, integer_t const iu, integer_t& m, VectorW& w,
+            MatrixZ& z, integer_t const nzc, VectorISUPPZ& isuppz,
+            logical_t& tryrac, integer_t& info, detail::workspace2< WORK,
+            IWORK > work ) {
+        BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
+                VectorD >::value_type, typename traits::vector_traits<
+                VectorE >::value_type >::value) );
+        BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
+                VectorD >::value_type, typename traits::vector_traits<
+                VectorW >::value_type >::value) );
+        BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
+                VectorD >::value_type, typename traits::matrix_traits<
+                MatrixZ >::value_type >::value) );
+        BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
+        BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
+        BOOST_ASSERT( n >= 0 );
+        BOOST_ASSERT( traits::vector_size(d) >= n );
+        BOOST_ASSERT( traits::vector_size(e) >= n );
+        BOOST_ASSERT( traits::vector_size(w) >= n );
+        BOOST_ASSERT( traits::vector_size(work.select(real_type())) >=
+                min_size_work( n, jobz ));
+        BOOST_ASSERT( traits::vector_size(work.select(integer_t())) >=
+                min_size_iwork( n, jobz ));
+        detail::stemr( jobz, range, n, traits::vector_storage(d),
+                traits::vector_storage(e), vl, vu, il, iu, m,
+                traits::vector_storage(w), traits::matrix_storage(z),
+                traits::leading_dimension(z), nzc,
+                traits::vector_storage(isuppz), tryrac,
+                traits::vector_storage(work.select(real_type())),
+                traits::vector_size(work.select(real_type())),
+                traits::vector_storage(work.select(integer_t())),
+                traits::vector_size(work.select(integer_t())), info );
+    }
+
+    // minimal workspace specialization
+    template< typename VectorD, typename VectorE, typename VectorW,
+            typename MatrixZ, typename VectorISUPPZ >
+    static void invoke( char const jobz, char const range, integer_t const n,
+            VectorD& d, VectorE& e, real_type const vl, real_type const vu,
+            integer_t const il, integer_t const iu, integer_t& m, VectorW& w,
+            MatrixZ& z, integer_t const nzc, VectorISUPPZ& isuppz,
+            logical_t& tryrac, integer_t& info, minimal_workspace work ) {
+        traits::detail::array< real_type > tmp_work( min_size_work( n,
+                jobz ) );
+        traits::detail::array< integer_t > tmp_iwork( min_size_iwork( n,
+                jobz ) );
+        invoke( jobz, range, n, d, e, vl, vu, il, iu, m, w, z, nzc, isuppz,
+                tryrac, info, workspace( tmp_work, tmp_iwork ) );
+    }
+
+    // optimal workspace specialization
+    template< typename VectorD, typename VectorE, typename VectorW,
+            typename MatrixZ, typename VectorISUPPZ >
+    static void invoke( char const jobz, char const range, integer_t const n,
+            VectorD& d, VectorE& e, real_type const vl, real_type const vu,
+            integer_t const il, integer_t const iu, integer_t& m, VectorW& w,
+            MatrixZ& z, integer_t const nzc, VectorISUPPZ& isuppz,
+            logical_t& tryrac, integer_t& info, optimal_workspace work ) {
+        real_type opt_size_work;
+        integer_t opt_size_iwork;
+        detail::stemr( jobz, range, n, traits::vector_storage(d),
+                traits::vector_storage(e), vl, vu, il, iu, m,
+                traits::vector_storage(w), traits::matrix_storage(z),
+                traits::leading_dimension(z), nzc,
+                traits::vector_storage(isuppz), tryrac, &opt_size_work, -1,
+                &opt_size_iwork, -1, info );
+        traits::detail::array< real_type > tmp_work(
+                traits::detail::to_int( opt_size_work ) );
+        traits::detail::array< integer_t > tmp_iwork( opt_size_iwork );
+        invoke( jobz, range, n, d, e, vl, vu, il, iu, m, w, z, nzc, isuppz,
+                tryrac, info, workspace( tmp_work, tmp_iwork ) );
+    }
+
+    static integer_t min_size_work( integer_t const n, char const jobz ) {
+        if ( jobz == 'V' ) {
+            return std::max( 1, 18*n );
+        } else {
+            return std::max( 1, 12*n );
+        }
+    }
+
+    static integer_t min_size_iwork( integer_t const n, char const jobz ) {
+        if ( jobz == 'V' ) {
+            return std::max( 1, 10*n );
+        } else {
+            return std::max( 1, 8*n );
+        }
+    }
+};
+
+// complex specialization
+template< typename ValueType >
+struct stemr_impl< ValueType, typename boost::enable_if< traits::is_complex<ValueType> >::type > {
+
+    typedef ValueType value_type;
+    typedef typename traits::type_traits<ValueType>::real_type real_type;
+
+    // user-defined workspace specialization
+    template< typename VectorD, typename VectorE, typename VectorW,
+            typename MatrixZ, typename VectorISUPPZ, typename WORK,
+            typename IWORK >
+    static void invoke( char const jobz, char const range, integer_t const n,
+            VectorD& d, VectorE& e, real_type const vl, real_type const vu,
+            integer_t const il, integer_t const iu, integer_t& m, VectorW& w,
+            MatrixZ& z, integer_t const nzc, VectorISUPPZ& isuppz,
+            logical_t& tryrac, integer_t& info, detail::workspace2< WORK,
+            IWORK > work ) {
+        BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
+                VectorD >::value_type, typename traits::vector_traits<
+                VectorE >::value_type >::value) );
+        BOOST_STATIC_ASSERT( (boost::is_same< typename traits::vector_traits<
+                VectorD >::value_type, typename traits::vector_traits<
+                VectorW >::value_type >::value) );
+        BOOST_ASSERT( jobz == 'N' || jobz == 'V' );
+        BOOST_ASSERT( range == 'A' || range == 'V' || range == 'I' );
+        BOOST_ASSERT( n >= 0 );
+        BOOST_ASSERT( traits::vector_size(d) >= n );
+        BOOST_ASSERT( traits::vector_size(e) >= n );
+        BOOST_ASSERT( traits::vector_size(w) >= n );
+        BOOST_ASSERT( traits::vector_size(work.select(real_type())) >=
+                min_size_work( n, jobz ));
+        BOOST_ASSERT( traits::vector_size(work.select(integer_t())) >=
+                min_size_iwork( n, jobz ));
+        detail::stemr( jobz, range, n, traits::vector_storage(d),
+                traits::vector_storage(e), vl, vu, il, iu, m,
+                traits::vector_storage(w), traits::matrix_storage(z),
+                traits::leading_dimension(z), nzc,
+                traits::vector_storage(isuppz), tryrac,
+                traits::vector_storage(work.select(real_type())),
+                traits::vector_size(work.select(real_type())),
+                traits::vector_storage(work.select(integer_t())),
+                traits::vector_size(work.select(integer_t())), info );
+    }
+
+    // minimal workspace specialization
+    template< typename VectorD, typename VectorE, typename VectorW,
+            typename MatrixZ, typename VectorISUPPZ >
+    static void invoke( char const jobz, char const range, integer_t const n,
+            VectorD& d, VectorE& e, real_type const vl, real_type const vu,
+            integer_t const il, integer_t const iu, integer_t& m, VectorW& w,
+            MatrixZ& z, integer_t const nzc, VectorISUPPZ& isuppz,
+            logical_t& tryrac, integer_t& info, minimal_workspace work ) {
+        traits::detail::array< real_type > tmp_work( min_size_work( n,
+                jobz ) );
+        traits::detail::array< integer_t > tmp_iwork( min_size_iwork( n,
+                jobz ) );
+        invoke( jobz, range, n, d, e, vl, vu, il, iu, m, w, z, nzc, isuppz,
+                tryrac, info, workspace( tmp_work, tmp_iwork ) );
+    }
+
+    // optimal workspace specialization
+    template< typename VectorD, typename VectorE, typename VectorW,
+            typename MatrixZ, typename VectorISUPPZ >
+    static void invoke( char const jobz, char const range, integer_t const n,
+            VectorD& d, VectorE& e, real_type const vl, real_type const vu,
+            integer_t const il, integer_t const iu, integer_t& m, VectorW& w,
+            MatrixZ& z, integer_t const nzc, VectorISUPPZ& isuppz,
+            logical_t& tryrac, integer_t& info, optimal_workspace work ) {
+        real_type opt_size_work;
+        integer_t opt_size_iwork;
+        detail::stemr( jobz, range, n, traits::vector_storage(d),
+                traits::vector_storage(e), vl, vu, il, iu, m,
+                traits::vector_storage(w), traits::matrix_storage(z),
+                traits::leading_dimension(z), nzc,
+                traits::vector_storage(isuppz), tryrac, &opt_size_work, -1,
+                &opt_size_iwork, -1, info );
+        traits::detail::array< real_type > tmp_work(
+                traits::detail::to_int( opt_size_work ) );
+        traits::detail::array< integer_t > tmp_iwork( opt_size_iwork );
+        invoke( jobz, range, n, d, e, vl, vu, il, iu, m, w, z, nzc, isuppz,
+                tryrac, info, workspace( tmp_work, tmp_iwork ) );
+    }
+
+    static integer_t min_size_work( integer_t const n, char const jobz ) {
+        if ( jobz == 'V' ) {
+            return std::max( 1, 18*n );
+        } else {
+            return std::max( 1, 12*n );
+        }
+    }
+
+    static integer_t min_size_iwork( integer_t const n, char const jobz ) {
+        if ( jobz == 'V' ) {
+            return std::max( 1, 10*n );
+        } else {
+            return std::max( 1, 8*n );
+        }
+    }
+};
+
+
+// template function to call stemr
+template< typename VectorD, typename VectorE, typename VectorW,
+        typename MatrixZ, typename VectorISUPPZ, typename Workspace >
+inline integer_t stemr( char const jobz, char const range,
+        integer_t const n, VectorD& d, VectorE& e,
+        typename traits::type_traits< typename traits::matrix_traits<
+        MatrixZ >::value_type >::real_type const vl,
+        typename traits::type_traits< typename traits::matrix_traits<
+        MatrixZ >::value_type >::real_type const vu, integer_t const il,
+        integer_t const iu, integer_t& m, VectorW& w, MatrixZ& z,
+        integer_t const nzc, VectorISUPPZ& isuppz, logical_t& tryrac,
+        Workspace work ) {
+    typedef typename traits::matrix_traits< MatrixZ >::value_type value_type;
+    integer_t info(0);
+    stemr_impl< value_type >::invoke( jobz, range, n, d, e, vl, vu, il,
+            iu, m, w, z, nzc, isuppz, tryrac, info, work );
+    return info;
+}
+
+// template function to call stemr, default workspace type
+template< typename VectorD, typename VectorE, typename VectorW,
+        typename MatrixZ, typename VectorISUPPZ >
+inline integer_t stemr( char const jobz, char const range,
+        integer_t const n, VectorD& d, VectorE& e,
+        typename traits::type_traits< typename traits::matrix_traits<
+        MatrixZ >::value_type >::real_type const vl,
+        typename traits::type_traits< typename traits::matrix_traits<
+        MatrixZ >::value_type >::real_type const vu, integer_t const il,
+        integer_t const iu, integer_t& m, VectorW& w, MatrixZ& z,
+        integer_t const nzc, VectorISUPPZ& isuppz, logical_t& tryrac ) {
+    typedef typename traits::matrix_traits< MatrixZ >::value_type value_type;
+    integer_t info(0);
+    stemr_impl< value_type >::invoke( jobz, range, n, d, e, vl, vu, il,
+            iu, m, w, z, nzc, isuppz, tryrac, info, optimal_workspace() );
+    return info;
+}
+
+}}}} // namespace boost::numeric::bindings::lapack
+
+#endif
Modified: sandbox/numeric_bindings/boost/numeric/bindings/lapack/detail/lapack.h
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/lapack/detail/lapack.h	(original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/lapack/detail/lapack.h	2009-04-14 05:10:19 EDT (Tue, 14 Apr 2009)
@@ -1849,6 +1849,36 @@
         integer_t const* isplit, dcomplex_t* z, integer_t const* ldz,
         double* work, integer_t* iwork, integer_t* ifail, integer_t* info );
 
+// Value-type variants of stemr
+void LAPACK_SSTEMR( char const* jobz, char const* range, integer_t const* n,
+        float* d, float* e, float const* vl, float const* vu,
+        integer_t const* il, integer_t const* iu, integer_t* m, float* w,
+        float* z, integer_t const* ldz, integer_t const* nzc,
+        integer_t* isuppz, logical_t* tryrac, float* work,
+        integer_t const* lwork, integer_t* iwork, integer_t const* liwork,
+        integer_t* info );
+void LAPACK_DSTEMR( char const* jobz, char const* range, integer_t const* n,
+        double* d, double* e, double const* vl, double const* vu,
+        integer_t const* il, integer_t const* iu, integer_t* m, double* w,
+        double* z, integer_t const* ldz, integer_t const* nzc,
+        integer_t* isuppz, logical_t* tryrac, double* work,
+        integer_t const* lwork, integer_t* iwork, integer_t const* liwork,
+        integer_t* info );
+void LAPACK_CSTEMR( char const* jobz, char const* range, integer_t const* n,
+        float* d, float* e, float const* vl, float const* vu,
+        integer_t const* il, integer_t const* iu, integer_t* m, float* w,
+        fcomplex_t* z, integer_t const* ldz, integer_t const* nzc,
+        integer_t* isuppz, logical_t* tryrac, float* work,
+        integer_t const* lwork, integer_t* iwork, integer_t const* liwork,
+        integer_t* info );
+void LAPACK_ZSTEMR( char const* jobz, char const* range, integer_t const* n,
+        double* d, double* e, double const* vl, double const* vu,
+        integer_t const* il, integer_t const* iu, integer_t* m, double* w,
+        dcomplex_t* z, integer_t const* ldz, integer_t const* nzc,
+        integer_t* isuppz, logical_t* tryrac, double* work,
+        integer_t const* lwork, integer_t* iwork, integer_t const* liwork,
+        integer_t* info );
+
 // Value-type variants of steqr
 void LAPACK_SSTEQR( char const* compz, integer_t const* n, float* d, float* e,
         float* z, integer_t const* ldz, float* work, integer_t* info );
Modified: sandbox/numeric_bindings/boost/numeric/bindings/lapack/detail/lapack_names.h
==============================================================================
--- sandbox/numeric_bindings/boost/numeric/bindings/lapack/detail/lapack_names.h	(original)
+++ sandbox/numeric_bindings/boost/numeric/bindings/lapack/detail/lapack_names.h	2009-04-14 05:10:19 EDT (Tue, 14 Apr 2009)
@@ -678,6 +678,12 @@
 #define LAPACK_CSTEIN FORTRAN_ID( cstein )
 #define LAPACK_ZSTEIN FORTRAN_ID( zstein )
 
+// Value-type variants of stemr
+#define LAPACK_SSTEMR FORTRAN_ID( sstemr )
+#define LAPACK_DSTEMR FORTRAN_ID( dstemr )
+#define LAPACK_CSTEMR FORTRAN_ID( cstemr )
+#define LAPACK_ZSTEMR FORTRAN_ID( zstemr )
+
 // Value-type variants of steqr
 #define LAPACK_SSTEQR FORTRAN_ID( ssteqr )
 #define LAPACK_DSTEQR FORTRAN_ID( dsteqr )
Modified: sandbox/numeric_bindings/libs/numeric/bindings/tools/lapack_generator.py
==============================================================================
--- sandbox/numeric_bindings/libs/numeric/bindings/tools/lapack_generator.py	(original)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/lapack_generator.py	2009-04-14 05:10:19 EDT (Tue, 14 Apr 2009)
@@ -521,7 +521,7 @@
 
 # based on LAPACK Users' Guide, table 2.10
 routines[ 'computational' ][ 'symmetric_eigen' ] = {}
-routines[ 'computational' ][ 'symmetric_eigen' ][ 'endings' ] = [ 'TRD', 'MTR', 'GTR', 'TEQR', 'ERF', 'EDC', 'EGR', 'EBZ', 'TEIN' ]
+routines[ 'computational' ][ 'symmetric_eigen' ][ 'endings' ] = [ 'TRD', 'MTR', 'GTR', 'TEQR', 'ERF', 'EDC', 'EGR', 'EBZ', 'TEIN', 'EMR' ]
 
 # based on LAPACK Users' Guide, table 2.11
 routines[ 'computational' ][ 'nonsymmetric_eigen' ] = {}
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/stemr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/stemr.hpp	2009-04-14 05:10:19 EDT (Tue, 14 Apr 2009)
@@ -0,0 +1,17 @@
+$TEMPLATE[stemr.all.min_size_work.args]
+N, JOBZ
+$TEMPLATE[stemr.all.min_size_work]
+if ( jobz == 'V' ) {
+    return std::max( 1, 18*n );
+} else {
+    return std::max( 1, 12*n );
+}
+$TEMPLATE[stemr.all.min_size_iwork.args]
+N,JOBZ
+$TEMPLATE[stemr.all.min_size_iwork]
+if ( jobz == 'V' ) {
+    return std::max( 1, 10*n );
+} else {
+    return std::max( 1, 8*n );
+}
+$TEMPLATE[end]