diff --git a/mex/sources/korderpert/Dyn_pp/extern/include/pthread.h b/mex/sources/korderpert/Dyn_pp/extern/include/pthread.h new file mode 100644 index 000000000..9f2868bcc --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/extern/include/pthread.h @@ -0,0 +1,1368 @@ +/* This is an implementation of the threads API of POSIX 1003.1-2001. + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#if !defined( PTHREAD_H ) +#define PTHREAD_H + +/* + * See the README file for an explanation of the pthreads-win32 version + * numbering scheme and how the DLL is named etc. + */ +#define PTW32_VERSION 2,8,0,0 +#define PTW32_VERSION_STRING "2, 8, 0, 0\0" + +/* There are three implementations of cancel cleanup. + * Note that pthread.h is included in both application + * compilation units and also internally for the library. + * The code here and within the library aims to work + * for all reasonable combinations of environments. + * + * The three implementations are: + * + * WIN32 SEH + * C + * C++ + * + * Please note that exiting a push/pop block via + * "return", "exit", "break", or "continue" will + * lead to different behaviour amongst applications + * depending upon whether the library was built + * using SEH, C++, or C. For example, a library built + * with SEH will call the cleanup routine, while both + * C++ and C built versions will not. + */ + +/* + * Define defaults for cleanup code. + * Note: Unless the build explicitly defines one of the following, then + * we default to standard C style cleanup. This style uses setjmp/longjmp + * in the cancelation and thread exit implementations and therefore won't + * do stack unwinding if linked to applications that have it (e.g. + * C++ apps). This is currently consistent with most/all commercial Unix + * POSIX threads implementations. + */ +#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) +# define __CLEANUP_C +#endif + +#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC)) +#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler. +#endif + +/* + * Stop here if we are being included by the resource compiler. + */ +#ifndef RC_INVOKED + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#ifdef _UWIN +# define HAVE_STRUCT_TIMESPEC 1 +# define HAVE_SIGNAL_H 1 +# undef HAVE_CONFIG_H +# pragma comment(lib, "pthread") +#endif + +/* + * ------------------------------------------------------------- + * + * + * Module: pthread.h + * + * Purpose: + * Provides an implementation of PThreads based upon the + * standard: + * + * POSIX 1003.1-2001 + * and + * The Single Unix Specification version 3 + * + * (these two are equivalent) + * + * in order to enhance code portability between Windows, + * various commercial Unix implementations, and Linux. + * + * See the ANNOUNCE file for a full list of conforming + * routines and defined constants, and a list of missing + * routines and constants not defined in this implementation. + * + * Authors: + * There have been many contributors to this library. + * The initial implementation was contributed by + * John Bossom, and several others have provided major + * sections or revisions of parts of the implementation. + * Often significant effort has been contributed to + * find and fix important bugs and other problems to + * improve the reliability of the library, which sometimes + * is not reflected in the amount of code which changed as + * result. + * As much as possible, the contributors are acknowledged + * in the ChangeLog file in the source code distribution + * where their changes are noted in detail. + * + * Contributors are listed in the CONTRIBUTORS file. + * + * As usual, all bouquets go to the contributors, and all + * brickbats go to the project maintainer. + * + * Maintainer: + * The code base for this project is coordinated and + * eventually pre-tested, packaged, and made available by + * + * Ross Johnson + * + * QA Testers: + * Ultimately, the library is tested in the real world by + * a host of competent and demanding scientists and + * engineers who report bugs and/or provide solutions + * which are then fixed or incorporated into subsequent + * versions of the library. Each time a bug is fixed, a + * test case is written to prove the fix and ensure + * that later changes to the code don't reintroduce the + * same error. The number of test cases is slowly growing + * and therefore so is the code reliability. + * + * Compliance: + * See the file ANNOUNCE for the list of implemented + * and not-implemented routines and defined options. + * Of course, these are all defined is this file as well. + * + * Web site: + * The source code and other information about this library + * are available from + * + * http://sources.redhat.com/pthreads-win32/ + * + * ------------------------------------------------------------- + */ + +/* Try to avoid including windows.h */ +#if defined(__MINGW32__) && defined(__cplusplus) +#define PTW32_INCLUDE_WINDOWS_H +#endif + +#ifdef PTW32_INCLUDE_WINDOWS_H +#include +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__) +/* + * VC++6.0 or early compiler's header has no DWORD_PTR type. + */ +typedef unsigned long DWORD_PTR; +#endif +/* + * ----------------- + * autoconf switches + * ----------------- + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifndef NEED_FTIME +#include +#else /* NEED_FTIME */ +/* use native WIN32 time API */ +#endif /* NEED_FTIME */ + +#if HAVE_SIGNAL_H +#include +#endif /* HAVE_SIGNAL_H */ + +#include +#include + +/* + * Boolean values to make us independent of system includes. + */ +enum { + PTW32_FALSE = 0, + PTW32_TRUE = (! PTW32_FALSE) +}; + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Several systems don't define some error numbers. + */ +#ifndef ENOTSUP +# define ENOTSUP 48 /* This is the value in Solaris. */ +#endif + +#ifndef ETIMEDOUT +# define ETIMEDOUT 10060 /* This is the value in winsock.h. */ +#endif + +#ifndef ENOSYS +# define ENOSYS 140 /* Semi-arbitrary value */ +#endif + +#ifndef EDEADLK +# ifdef EDEADLOCK +# define EDEADLK EDEADLOCK +# else +# define EDEADLK 36 /* This is the value in MSVC. */ +# endif +#endif + +#include + +/* + * To avoid including windows.h we define only those things that we + * actually need from it. + */ +#ifndef PTW32_INCLUDE_WINDOWS_H +#ifndef HANDLE +# define PTW32__HANDLE_DEF +# define HANDLE void * +#endif +#ifndef DWORD +# define PTW32__DWORD_DEF +# define DWORD unsigned long +#endif +#endif + +#ifndef HAVE_STRUCT_TIMESPEC +#define HAVE_STRUCT_TIMESPEC 1 +struct timespec { + long tv_sec; + long tv_nsec; +}; +#endif /* HAVE_STRUCT_TIMESPEC */ + +#ifndef SIG_BLOCK +#define SIG_BLOCK 0 +#endif /* SIG_BLOCK */ + +#ifndef SIG_UNBLOCK +#define SIG_UNBLOCK 1 +#endif /* SIG_UNBLOCK */ + +#ifndef SIG_SETMASK +#define SIG_SETMASK 2 +#endif /* SIG_SETMASK */ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* + * ------------------------------------------------------------- + * + * POSIX 1003.1-2001 Options + * ========================= + * + * Options are normally set in , which is not provided + * with pthreads-win32. + * + * For conformance with the Single Unix Specification (version 3), all of the + * options below are defined, and have a value of either -1 (not supported) + * or 200112L (supported). + * + * These options can neither be left undefined nor have a value of 0, because + * either indicates that sysconf(), which is not implemented, may be used at + * runtime to check the status of the option. + * + * _POSIX_THREADS (== 200112L) + * If == 200112L, you can use threads + * + * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) + * If == 200112L, you can control the size of a thread's + * stack + * pthread_attr_getstacksize + * pthread_attr_setstacksize + * + * _POSIX_THREAD_ATTR_STACKADDR (== -1) + * If == 200112L, you can allocate and control a thread's + * stack. If not supported, the following functions + * will return ENOSYS, indicating they are not + * supported: + * pthread_attr_getstackaddr + * pthread_attr_setstackaddr + * + * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) + * If == 200112L, you can use realtime scheduling. + * This option indicates that the behaviour of some + * implemented functions conforms to the additional TPS + * requirements in the standard. E.g. rwlocks favour + * writers over readers when threads have equal priority. + * + * _POSIX_THREAD_PRIO_INHERIT (== -1) + * If == 200112L, you can create priority inheritance + * mutexes. + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PRIO_PROTECT (== -1) + * If == 200112L, you can create priority ceiling mutexes + * Indicates the availability of: + * pthread_mutex_getprioceiling + * pthread_mutex_setprioceiling + * pthread_mutexattr_getprioceiling + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprioceiling + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PROCESS_SHARED (== -1) + * If set, you can create mutexes and condition + * variables that can be shared with another + * process.If set, indicates the availability + * of: + * pthread_mutexattr_getpshared + * pthread_mutexattr_setpshared + * pthread_condattr_getpshared + * pthread_condattr_setpshared + * + * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) + * If == 200112L you can use the special *_r library + * functions that provide thread-safe behaviour + * + * _POSIX_READER_WRITER_LOCKS (== 200112L) + * If == 200112L, you can use read/write locks + * + * _POSIX_SPIN_LOCKS (== 200112L) + * If == 200112L, you can use spin locks + * + * _POSIX_BARRIERS (== 200112L) + * If == 200112L, you can use barriers + * + * + These functions provide both 'inherit' and/or + * 'protect' protocol, based upon these macro + * settings. + * + * ------------------------------------------------------------- + */ + +/* + * POSIX Options + */ +#undef _POSIX_THREADS +#define _POSIX_THREADS 200112L + +#undef _POSIX_READER_WRITER_LOCKS +#define _POSIX_READER_WRITER_LOCKS 200112L + +#undef _POSIX_SPIN_LOCKS +#define _POSIX_SPIN_LOCKS 200112L + +#undef _POSIX_BARRIERS +#define _POSIX_BARRIERS 200112L + +#undef _POSIX_THREAD_SAFE_FUNCTIONS +#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L + +#undef _POSIX_THREAD_ATTR_STACKSIZE +#define _POSIX_THREAD_ATTR_STACKSIZE 200112L + +/* + * The following options are not supported + */ +#undef _POSIX_THREAD_ATTR_STACKADDR +#define _POSIX_THREAD_ATTR_STACKADDR -1 + +#undef _POSIX_THREAD_PRIO_INHERIT +#define _POSIX_THREAD_PRIO_INHERIT -1 + +#undef _POSIX_THREAD_PRIO_PROTECT +#define _POSIX_THREAD_PRIO_PROTECT -1 + +/* TPS is not fully supported. */ +#undef _POSIX_THREAD_PRIORITY_SCHEDULING +#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 + +#undef _POSIX_THREAD_PROCESS_SHARED +#define _POSIX_THREAD_PROCESS_SHARED -1 + + +/* + * POSIX 1003.1-2001 Limits + * =========================== + * + * These limits are normally set in , which is not provided with + * pthreads-win32. + * + * PTHREAD_DESTRUCTOR_ITERATIONS + * Maximum number of attempts to destroy + * a thread's thread-specific data on + * termination (must be at least 4) + * + * PTHREAD_KEYS_MAX + * Maximum number of thread-specific data keys + * available per process (must be at least 128) + * + * PTHREAD_STACK_MIN + * Minimum supported stack size for a thread + * + * PTHREAD_THREADS_MAX + * Maximum number of threads supported per + * process (must be at least 64). + * + * SEM_NSEMS_MAX + * The maximum number of semaphores a process can have. + * (must be at least 256) + * + * SEM_VALUE_MAX + * The maximum value a semaphore can have. + * (must be at least 32767) + * + */ +#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 + +#undef PTHREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS + +#undef _POSIX_THREAD_KEYS_MAX +#define _POSIX_THREAD_KEYS_MAX 128 + +#undef PTHREAD_KEYS_MAX +#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX + +#undef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN 0 + +#undef _POSIX_THREAD_THREADS_MAX +#define _POSIX_THREAD_THREADS_MAX 64 + + /* Arbitrary value */ +#undef PTHREAD_THREADS_MAX +#define PTHREAD_THREADS_MAX 2019 + +#undef _POSIX_SEM_NSEMS_MAX +#define _POSIX_SEM_NSEMS_MAX 256 + + /* Arbitrary value */ +#undef SEM_NSEMS_MAX +#define SEM_NSEMS_MAX 1024 + +#undef _POSIX_SEM_VALUE_MAX +#define _POSIX_SEM_VALUE_MAX 32767 + +#undef SEM_VALUE_MAX +#define SEM_VALUE_MAX INT_MAX + + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifndef PTW32_STATIC_LIB +# ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * The Open Watcom C/C++ compiler uses a non-standard calling convention + * that passes function args in registers unless __cdecl is explicitly specified + * in exposed function prototypes. + * + * We force all calls to cdecl even though this could slow Watcom code down + * slightly. If you know that the Watcom compiler will be used to build both + * the DLL and application, then you can probably define this as a null string. + * Remember that pthread.h (this file) is used for both the DLL and application builds. + */ +#define PTW32_CDECL __cdecl + +#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX +# include +#else +/* + * Generic handle type - intended to extend uniqueness beyond + * that available with a simple pointer. It should scale for either + * IA-32 or IA-64. + */ +typedef struct { + void * p; /* Pointer to actual object */ + unsigned int x; /* Extra information - reuse count etc */ +} ptw32_handle_t; + +typedef ptw32_handle_t pthread_t; +typedef struct pthread_attr_t_ * pthread_attr_t; +typedef struct pthread_once_t_ pthread_once_t; +typedef struct pthread_key_t_ * pthread_key_t; +typedef struct pthread_mutex_t_ * pthread_mutex_t; +typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; +typedef struct pthread_cond_t_ * pthread_cond_t; +typedef struct pthread_condattr_t_ * pthread_condattr_t; +#endif +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +typedef struct pthread_spinlock_t_ * pthread_spinlock_t; +typedef struct pthread_barrier_t_ * pthread_barrier_t; +typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; + +/* + * ==================== + * ==================== + * POSIX Threads + * ==================== + * ==================== + */ + +enum { +/* + * pthread_attr_{get,set}detachstate + */ + PTHREAD_CREATE_JOINABLE = 0, /* Default */ + PTHREAD_CREATE_DETACHED = 1, + +/* + * pthread_attr_{get,set}inheritsched + */ + PTHREAD_INHERIT_SCHED = 0, + PTHREAD_EXPLICIT_SCHED = 1, /* Default */ + +/* + * pthread_{get,set}scope + */ + PTHREAD_SCOPE_PROCESS = 0, + PTHREAD_SCOPE_SYSTEM = 1, /* Default */ + +/* + * pthread_setcancelstate paramters + */ + PTHREAD_CANCEL_ENABLE = 0, /* Default */ + PTHREAD_CANCEL_DISABLE = 1, + +/* + * pthread_setcanceltype parameters + */ + PTHREAD_CANCEL_ASYNCHRONOUS = 0, + PTHREAD_CANCEL_DEFERRED = 1, /* Default */ + +/* + * pthread_mutexattr_{get,set}pshared + * pthread_condattr_{get,set}pshared + */ + PTHREAD_PROCESS_PRIVATE = 0, + PTHREAD_PROCESS_SHARED = 1, + +/* + * pthread_barrier_wait + */ + PTHREAD_BARRIER_SERIAL_THREAD = -1 +}; + +/* + * ==================== + * ==================== + * Cancelation + * ==================== + * ==================== + */ +#define PTHREAD_CANCELED ((void *) -1) + + +/* + * ==================== + * ==================== + * Once Key + * ==================== + * ==================== + */ +#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} + +struct pthread_once_t_ +{ + int done; /* indicates if user function has been executed */ + void * lock; + int reserved1; + int reserved2; +}; + + +/* + * ==================== + * ==================== + * Object initialisers + * ==================== + * ==================== + */ +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1) +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3) + +/* + * Compatibility with LinuxThreads + */ +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1) + +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1) + +#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1) + + +/* + * Mutex types. + */ +enum +{ + /* Compatibility with LinuxThreads */ + PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, + /* For compatibility with POSIX */ + PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL +}; + + +typedef struct ptw32_cleanup_t ptw32_cleanup_t; + +#if defined(_MSC_VER) +/* Disable MSVC 'anachronism used' warning */ +#pragma warning( disable : 4229 ) +#endif + +typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); + +#if defined(_MSC_VER) +#pragma warning( default : 4229 ) +#endif + +struct ptw32_cleanup_t +{ + ptw32_cleanup_callback_t routine; + void *arg; + struct ptw32_cleanup_t *prev; +}; + +#ifdef __CLEANUP_SEH + /* + * WIN32 SEH version of cancel cleanup. + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ + _cleanup.arg = (_arg); \ + __try \ + { \ + +#define pthread_cleanup_pop( _execute ) \ + } \ + __finally \ + { \ + if( _execute || AbnormalTermination()) \ + { \ + (*(_cleanup.routine))( _cleanup.arg ); \ + } \ + } \ + } + +#else /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_C + + /* + * C implementation of PThreads cancel cleanup + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ + +#define pthread_cleanup_pop( _execute ) \ + (void) ptw32_pop_cleanup( _execute ); \ + } + +#else /* __CLEANUP_C */ + +#ifdef __CLEANUP_CXX + + /* + * C++ version of cancel cleanup. + * - John E. Bossom. + */ + + class PThreadCleanup { + /* + * PThreadCleanup + * + * Purpose + * This class is a C++ helper class that is + * used to implement pthread_cleanup_push/ + * pthread_cleanup_pop. + * The destructor of this class automatically + * pops the pushed cleanup routine regardless + * of how the code exits the scope + * (i.e. such as by an exception) + */ + ptw32_cleanup_callback_t cleanUpRout; + void * obj; + int executeIt; + + public: + PThreadCleanup() : + cleanUpRout( 0 ), + obj( 0 ), + executeIt( 0 ) + /* + * No cleanup performed + */ + { + } + + PThreadCleanup( + ptw32_cleanup_callback_t routine, + void * arg ) : + cleanUpRout( routine ), + obj( arg ), + executeIt( 1 ) + /* + * Registers a cleanup routine for 'arg' + */ + { + } + + ~PThreadCleanup() + { + if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) + { + (void) (*cleanUpRout)( obj ); + } + } + + void execute( int exec ) + { + executeIt = exec; + } + }; + + /* + * C++ implementation of PThreads cancel cleanup; + * This implementation takes advantage of a helper + * class who's destructor automatically calls the + * cleanup routine if we exit our scope weirdly + */ +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ + (void *) (_arg) ); + +#define pthread_cleanup_pop( _execute ) \ + cleanup.execute( _execute ); \ + } + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */ + +/* + * =============== + * =============== + * Methods + * =============== + * =============== + */ + +/* + * PThread Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, + int *detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, + void **stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, + size_t * stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, + int detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, + void *stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, + size_t stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (pthread_attr_t *, + int *); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, + int inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(pthread_attr_t * attr, + int * inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, + int *); + +/* + * PThread Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, + const pthread_attr_t * attr, + void *(*start) (void *), + void *arg); + +PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); + +PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, + pthread_t t2); + +PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); + +PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, + void **value_ptr); + +PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, + int *oldstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, + int *oldtype); + +PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, + void (*init_routine) (void)); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); + +PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, + void (*routine) (void *), + void *arg); +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread Specific Data Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, + void (*destructor) (void *)); + +PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); + +PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, + const void *value); + +PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); + + +/* + * Mutex Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, + int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind); + +/* + * Barrier Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, + int pshared); + +/* + * Mutex Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, + const pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t *mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); + +/* + * Spinlock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); + +/* + * Barrier Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, + const pthread_barrierattr_t * attr, + unsigned int count); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); + +/* + * Condition Variable Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, + int pshared); + +/* + * Condition Variable Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, + const pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, + pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, + pthread_mutex_t * mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); + +/* + * Scheduling + */ +PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, + int policy, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, + int *policy, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); + +PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); + +/* + * Read-Write Lock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, + const pthread_rwlockattr_t *attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, + int pshared); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 + +/* + * Signal Functions. Should be defined in but MSVC and MinGW32 + * already have signal.h that don't define these. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); + +/* + * Non-portable functions + */ + +/* + * Compatibility with Linux. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, + int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, + int *kind); + +/* + * Possibly supported by other POSIX threads implementations + */ +PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); +PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); + +/* + * Useful if an application wants to statically link + * the lib rather than load the DLL at run-time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); + +/* + * Features that are auto-detected at load/run time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); +enum ptw32_features { + PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ + PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ +}; + +/* + * Register a system time change with the library. + * Causes the library to perform various functions + * in response to the change. Should be called whenever + * the application's top level window receives a + * WM_TIMECHANGE message. It can be passed directly to + * pthread_create() as a new thread if desired. + */ +PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); + +#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* + * Returns the Win32 HANDLE for the POSIX thread. + */ +PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); + + +/* + * Protected Methods + * + * This function blocks until the given WIN32 handle + * is signaled or pthread_cancel had been called. + * This function allows the caller to hook into the + * PThreads cancel mechanism. It is implemented using + * + * WaitForMultipleObjects + * + * on 'waitHandle' and a manually reset WIN32 Event + * used to implement pthread_cancel. The 'timeout' + * argument to TimedWait is simply passed to + * WaitForMultipleObjects. + */ +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, + DWORD timeout); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread-Safe C Runtime Library Mappings. + */ +#ifndef _UWIN +# if defined(NEED_ERRNO) + PTW32_DLLPORT int * PTW32_CDECL _errno( void ); +# else +# ifndef errno +# if (defined(_MT) || defined(_DLL)) + __declspec(dllimport) extern int * __cdecl _errno(void); +# define errno (*_errno()) +# endif +# endif +# endif +#endif + +/* + * WIN32 C runtime library had been made thread-safe + * without affecting the user interface. Provide + * mappings from the UNIX thread-safe versions to + * the standard C runtime library calls. + * Only provide function mappings for functions that + * actually exist on WIN32. + */ + +#if !defined(__MINGW32__) +#define strtok_r( _s, _sep, _lasts ) \ + ( *(_lasts) = strtok( (_s), (_sep) ) ) +#endif /* !__MINGW32__ */ + +#define asctime_r( _tm, _buf ) \ + ( strcpy( (_buf), asctime( (_tm) ) ), \ + (_buf) ) + +#define ctime_r( _clock, _buf ) \ + ( strcpy( (_buf), ctime( (_clock) ) ), \ + (_buf) ) + +#define gmtime_r( _clock, _result ) \ + ( *(_result) = *gmtime( (_clock) ), \ + (_result) ) + +#define localtime_r( _clock, _result ) \ + ( *(_result) = *localtime( (_clock) ), \ + (_result) ) + +#define rand_r( _seed ) \ + ( _seed == _seed? rand() : rand() ) + + +/* + * Some compiler environments don't define some things. + */ +#if defined(__BORLANDC__) +# define _ftime ftime +# define _timeb timeb +#endif + +#ifdef __cplusplus + +/* + * Internal exceptions + */ +class ptw32_exception {}; +class ptw32_exception_cancel : public ptw32_exception {}; +class ptw32_exception_exit : public ptw32_exception {}; + +#endif + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* FIXME: This is only required if the library was built using SEH */ +/* + * Get internal SEH tag + */ +PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#ifndef PTW32_BUILD + +#ifdef __CLEANUP_SEH + +/* + * Redefine the SEH __except keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#define __except( E ) \ + __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ + ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) + +#endif /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_CXX + +/* + * Redefine the C++ catch keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#ifdef _MSC_VER + /* + * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' + * if you want Pthread-Win32 cancelation and pthread_exit to work. + */ + +#ifndef PtW32NoCatchWarn + +#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") +#pragma message("------------------------------------------------------------------") +#pragma message("When compiling applications with MSVC++ and C++ exception handling:") +#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") +#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") +#pragma message(" cancelation and pthread_exit to work. For example:") +#pragma message("") +#pragma message(" #ifdef PtW32CatchAll") +#pragma message(" PtW32CatchAll") +#pragma message(" #else") +#pragma message(" catch(...)") +#pragma message(" #endif") +#pragma message(" {") +#pragma message(" /* Catchall block processing */") +#pragma message(" }") +#pragma message("------------------------------------------------------------------") + +#endif + +#define PtW32CatchAll \ + catch( ptw32_exception & ) { throw; } \ + catch( ... ) + +#else /* _MSC_VER */ + +#define catch( E ) \ + catch( ptw32_exception & ) { throw; } \ + catch( E ) + +#endif /* _MSC_VER */ + +#endif /* __CLEANUP_CXX */ + +#endif /* ! PTW32_BUILD */ + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#ifdef PTW32__HANDLE_DEF +# undef HANDLE +#endif +#ifdef PTW32__DWORD_DEF +# undef DWORD +#endif + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* ! RC_INVOKED */ + +#endif /* PTHREAD_H */ diff --git a/mex/sources/korderpert/Dyn_pp/extern/include/sched.h b/mex/sources/korderpert/Dyn_pp/extern/include/sched.h new file mode 100644 index 000000000..10ecb5d7e --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/extern/include/sched.h @@ -0,0 +1,178 @@ +/* + * Module: sched.h + * + * Purpose: + * Provides an implementation of POSIX realtime extensions + * as defined in + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#ifndef _SCHED_H +#define _SCHED_H + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifndef PTW32_STATIC_LIB +# ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#if defined(__MINGW32__) || defined(_UWIN) +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +/* For pid_t */ +# include +/* Required by Unix 98 */ +# include +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ +#else +typedef int pid_t; +#endif + +/* Thread scheduling policies */ + +enum { + SCHED_OTHER = 0, + SCHED_FIFO, + SCHED_RR, + SCHED_MIN = SCHED_OTHER, + SCHED_MAX = SCHED_RR +}; + +struct sched_param { + int sched_priority; +}; + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +PTW32_DLLPORT int __cdecl sched_yield (void); + +PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); + +PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); + +PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); + +PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); + +/* + * Note that this macro returns ENOTSUP rather than + * ENOSYS as might be expected. However, returning ENOSYS + * should mean that sched_get_priority_{min,max} are + * not implemented as well as sched_rr_get_interval. + * This is not the case, since we just don't support + * round-robin scheduling. Therefore I have chosen to + * return the same value as sched_setscheduler when + * SCHED_RR is passed to it. + */ +#define sched_rr_get_interval(_pid, _interval) \ + ( errno = ENOTSUP, (int) -1 ) + + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* !_SCHED_H */ + diff --git a/mex/sources/korderpert/Dyn_pp/extern/include/semaphore.h b/mex/sources/korderpert/Dyn_pp/extern/include/semaphore.h new file mode 100644 index 000000000..ea42ce370 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/extern/include/semaphore.h @@ -0,0 +1,166 @@ +/* + * Module: semaphore.h + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined( SEMAPHORE_H ) +#define SEMAPHORE_H + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifndef PTW32_STATIC_LIB +# ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#define _POSIX_SEMAPHORES + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifndef HAVE_MODE_T +typedef unsigned int mode_t; +#endif + + +typedef struct sem_t_ * sem_t; + +PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, + int pshared, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, + const struct timespec * abstime); + +PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, + int count); + +PTW32_DLLPORT int __cdecl sem_open (const char * name, + int oflag, + mode_t mode, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_unlink (const char * name); + +PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, + int * sval); + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* !SEMAPHORE_H */ diff --git a/mex/sources/korderpert/Dyn_pp/extern/matlab/Makefile b/mex/sources/korderpert/Dyn_pp/extern/matlab/Makefile new file mode 100644 index 000000000..3296c6c29 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/extern/matlab/Makefile @@ -0,0 +1,129 @@ +CC = gcc +CC_FLAGS = -Wall -I../../sylv/cc -I../../tl/cc -I../../kord -I../../integ/cc \ + $(CC_INCLUDE_PATH) + +LDFLAGS = -llapack -lcblas -lf77blas -latlas -lg2c -lstdc++ + +ifeq ($(DEBUG),yes) + CC_FLAGS := $(CC_FLAGS) -g -DTL_DEBUG=2 +else + CC_FLAGS := $(CC_FLAGS) -O3 -DPOSIX_THREADS +endif + +ifeq ($(OS),Windows_NT) + CC_FLAGS := -mno-cygwin -mthreads $(CC_FLAGS) + LDFLAGS := -mno-cygwin -mthreads $(LDFLAGS) -lpthreadGC2 + ARCH := w32 + MEX_SUFFIX = dll +else + LDFLAGS := $(LDFLAGS) -lpthread + ARCH := linux + MEX_SUFFIX = mexglx +endif + +sylvcppsource := $(wildcard ../../sylv/cc/*.cpp) +sylvhsource := $(wildcard ../../sylv/cc/*.h) +sylvobjects := $(patsubst %.cpp, %.o, $(sylvcppsource)) + +tlcwebsource := $(wildcard ../../tl/cc/*.cweb) +tlcppsource := $(patsubst %.cweb,%.cpp,$(tlcwebsource)) +tlhwebsource := $(wildcard ../../tl/cc/*.hweb) +tlhsource := $(patsubst %.hweb,%.h,$(tlhwebsource)) +tlobjects := $(patsubst %.cweb,%.o,$(tlcwebsource)) + +kordcwebsource := $(wildcard ../../kord/*.cweb) +kordcppsource := $(patsubst %.cweb,%.cpp,$(kordcwebsource)) +kordhwebsource := $(wildcard ../../kord/*.hweb) +kordhsource := $(patsubst %.hweb,%.h,$(kordhwebsource)) +kordobjects := $(patsubst %.cweb,%.o,$(kordcwebsource)) + +integcwebsource := $(wildcard ../../integ/cc/*.cweb) +integcppsource := $(patsubst %.cweb,%.cpp,$(integcwebsource)) +integhwebsource := $(wildcard ../../integ/cc/*.hweb) +integhsource := $(patsubst %.hweb,%.h,$(integhwebsource)) +integobjects := $(patsubst %.cweb,%.o,$(integcwebsource)) + +cppsource := $(wildcard *.cpp) +mexobjects := $(patsubst %.cpp,%_.$(MEX_SUFFIX),$(cppsource)) + +all: $(mexobjects) + +../../tl/cc/dummy.ch: + make -C ../../tl/cc dummy.ch + +../../tl/cc/%.cpp: ../../tl/cc/%.cweb ../../tl/cc/dummy.ch + make -C ../../tl/cc $*.cpp + +../../tl/cc/%.h: ../../tl/cc/%.hweb ../../tl/cc/dummy.ch + make -C ../../tl/cc $*.h + +../../tl/cc/%.o: ../../tl/cc/%.cpp $(tlhsource) + make -C ../../tl/cc $*.o + +../../integ/cc/dummy.ch: + make -C ../../integ/cc dummy.ch + +../../integ/cc/%.cpp: ../../integ/cc/%.cweb ../../integ/cc/dummy.ch + make -C ../../integ/cc $*.cpp + +../../integ/cc/%.h: ../../integ/cc/%.hweb ../../integ/cc/dummy.ch + make -C ../../integ/cc $*.h + +../../integ/cc/%.o: ../../integ/cc/%.cpp $(integhsource) $(tlhsource) + make -C ../../integ/cc $*.o + + +../../sylv/cc/%.o: ../../sylv/cc/%.cpp $(sylvhsource) + make -C ../../sylv/cc $*.o + +../../kord/dummy.ch: + make -C ../../kord dummy.ch + +../../kord/%.cpp: ../../kord/%.cweb ../../kord/dummy.ch + make -C ../../kord $*.cpp + +../../kord/%.h: ../../kord/%.hweb ../../kord/dummy.ch + make -C ../../kord $*.h + +../../kord/%.o: ../../kord/%.cpp $(tlhsource) $(kordhsource) $(integhsource) + make -C ../../kord $*.o + + +dynarelib.a: $(tlhwebsource) $(tlcwebsoure) $(tlhsource) $(tlcppsource) \ + $(integhwebsource) $(integcwebsoure) $(integhsource) $(integcppsource) \ + $(kordhwebsource) $(kordcwebsoure) $(kordhsource) $(kordcppsource) \ + $(sylvhsource) $(sylvcppsource) \ + $(kordobjects) $(tlobjects) $(integobjects) $(sylvobjects) + ar cr dynarelib.a $(kordobjects) $(tlobjects) $(integobjects) $(sylvobjects) + ranlib dynarelib.a + + +# to compile mex objects for Windows do: +# 1. install gnumex +# 2. create mexopts.bat via gnumex in this directory, specify MinGW compilation, and dll output +# 3. change -Ic:/MATLAB71/extern/include according your Matlab setup +# 4. pray it works +# OR: just use the mexopt.bat from the repository and check MATLAB root directory +%_.$(MEX_SUFFIX): %.cpp $(tlhwebsource) $(tlcwebsoure) $(tlhsource) $(tlcppsource) \ + $(integhwebsource) $(integcwebsoure) $(integhsource) $(integcppsource) \ + $(kordhwebsource) $(kordcwebsoure) $(kordhsource) $(kordcppsource) \ + $(sylvhsource) $(sylvcppsource) \ + dynarelib.a +ifeq ($(OS),Windows_NT) + mex.bat -I../../sylv/cc -I../../tl/cc -I../../kord -I../../integ/cc COMPFLAGS\#"-c -DMATLAB_MEX_FILE -DPOSIX_THREADS" OPTIMFLAGS\#"-O3 -fexceptions -Ic:/MATLAB71/extern/include" GM_ADD_LIBS\#"$(LDFLAGS)" $*.cpp dynarelib.a +else + mex -I../../sylv/cc/ -I../../tl/cc -I../../kord -I../../integ/cc $*.cpp CFLAGS='$$CFLAGS -fexceptions' dynarelib.a +endif + mv $*.$(MEX_SUFFIX) $*_.$(MEX_SUFFIX) + +clear: + rm -f dynarelib.a + rm -f *.mexglx + rm -f *.dll + make -C ../../tl/testing clear + make -C ../../tl/cc clear + make -C ../../integ/testing clear + make -C ../../integ/cc clear + make -C ../../sylv/testing clear + make -C ../../sylv/cc clear + make -C ../../kord clear diff --git a/mex/sources/korderpert/Dyn_pp/extern/matlab/dynare_simul.cpp b/mex/sources/korderpert/Dyn_pp/extern/matlab/dynare_simul.cpp new file mode 100644 index 000000000..5a9d9c8ca --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/extern/matlab/dynare_simul.cpp @@ -0,0 +1,133 @@ +// $Id: dynare_simul.cpp 1488 2007-12-19 14:16:30Z kamenik $ + +// Copyright 2005, Ondra Kamenik + +// This is the mexFunction providing interface to +// DecisionRule<>::simulate(). It takes the following input +// parameters: +// order the order of approximation, needs order+1 derivatives +// nstat +// npred +// nboth +// nforw +// nexog +// ystart starting value (full vector of endogenous) +// shocks matrix of shocks (nexog x number of period) +// vcov covariance matrix of shocks (nexog x nexog) +// seed integer seed +// ysteady full vector of decision rule's steady +// ... order+1 matrices of derivatives + +// output: +// res simulated results + +#include "mex.h" + +#include "decision_rule.h" +#include "fs_tensor.h" +#include "SylvException.h" + +extern "C" { + void mexFunction(int nhls, mxArray* plhs[], + int nhrs, const mxArray* prhs[]) + { + if (nhrs < 12) + mexErrMsgTxt("Must have at least 12 input parameters.\n"); + if (nhls != 1) + mexErrMsgTxt("Must have exactly 1 output parameter.\n"); + + int order = (int)mxGetScalar(prhs[0]); + if (nhrs != 12 + order) { + mexErrMsgTxt("Must have exactly 11+order input parameters.\n"); + return; + } + + int nstat = (int)mxGetScalar(prhs[1]); + int npred = (int)mxGetScalar(prhs[2]); + int nboth = (int)mxGetScalar(prhs[3]); + int nforw = (int)mxGetScalar(prhs[4]); + int nexog = (int)mxGetScalar(prhs[5]); + + const mxArray* const ystart = prhs[6]; + const mxArray* const shocks = prhs[7]; + const mxArray* const vcov = prhs[8]; + int seed = (int)mxGetScalar(prhs[9]); + const mxArray* const ysteady = prhs[10]; + const int* const ystart_dim = mxGetDimensions(ystart); + const int* const shocks_dim = mxGetDimensions(shocks); + const int* const vcov_dim = mxGetDimensions(vcov); + const int* const ysteady_dim = mxGetDimensions(ysteady); + + int ny = nstat + npred + nboth + nforw; + if (ny != ystart_dim[0]) + mexErrMsgTxt("ystart has wrong number of rows.\n"); + if (1 != ystart_dim[1]) + mexErrMsgTxt("ystart has wrong number of cols.\n"); + int nper = shocks_dim[1]; + if (nexog != shocks_dim[0]) + mexErrMsgTxt("shocks has a wrong number of rows.\n"); + if (nexog != vcov_dim[0]) + mexErrMsgTxt("vcov has a wrong number of rows.\n"); + if (nexog != vcov_dim[1]) + mexErrMsgTxt("vcov has a wrong number of cols.\n"); + if (ny != ysteady_dim[0]) + mexErrMsgTxt("ysteady has wrong number of rows.\n"); + if (1 != ysteady_dim[1]) + mexErrMsgTxt("ysteady has wrong number of cols.\n"); + + mxArray* res = mxCreateDoubleMatrix(ny, nper, mxREAL); + + try { + // initialize tensor library + tls.init(order, npred+nboth+nexog); + + // form the polynomial + UTensorPolynomial pol(ny, npred+nboth+nexog); + for (int dim = 0; dim <= order; dim++) { + const mxArray* gk = prhs[11+dim]; + const int* const gk_dim = mxGetDimensions(gk); + FFSTensor ft(ny, npred+nboth+nexog, dim); + if (ft.ncols() != gk_dim[1]) { + char buf[1000]; + sprintf(buf, "Wrong number of columns for folded tensor: got %d but I want %d\n", + gk_dim[1], ft.ncols()); + mexErrMsgTxt(buf); + } + if (ft.nrows() != gk_dim[0]) { + char buf[1000]; + sprintf(buf, "Wrong number of rows for folded tensor: got %d but I want %d\n", + gk_dim[0], ft.nrows()); + mexErrMsgTxt(buf); + } + ft.zeros(); + ConstTwoDMatrix gk_mat(ft.nrows(), ft.ncols(), mxGetPr(gk)); + ft.add(1.0, gk_mat); + UFSTensor* ut = new UFSTensor(ft); + pol.insert(ut); + } + // form the decision rule + UnfoldDecisionRule + dr(pol, PartitionY(nstat, npred, nboth, nforw), + nexog, ConstVector(mxGetPr(ysteady), ny)); + // form the shock realization + TwoDMatrix shocks_mat(nexog, nper, (const double*)mxGetPr(shocks)); + TwoDMatrix vcov_mat(nexog, nexog, (const double*)mxGetPr(vcov)); + GenShockRealization sr(vcov_mat, shocks_mat, seed); + // simulate and copy the results + Vector ystart_vec((const double*)mxGetPr(ystart), ny); + TwoDMatrix* res_mat = + dr.simulate(DecisionRule::horner, nper, + ystart_vec, sr); + TwoDMatrix res_tmp_mat(ny, nper, mxGetPr(res)); + res_tmp_mat = (const TwoDMatrix&)(*res_mat); + delete res_mat; + plhs[0] = res; + } catch (const KordException& e) { + mexErrMsgTxt("Caugth Kord exception."); + } catch (const TLException& e) { + mexErrMsgTxt("Caugth TL exception."); + } catch (SylvException& e) { + mexErrMsgTxt("Caught Sylv exception."); + } + } +}; diff --git a/mex/sources/korderpert/Dyn_pp/extern/matlab/dynare_simul.m b/mex/sources/korderpert/Dyn_pp/extern/matlab/dynare_simul.m new file mode 100644 index 000000000..d70b90c83 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/extern/matlab/dynare_simul.m @@ -0,0 +1,160 @@ +% +% SYNOPSIS +% +% r = dynare_simul(name, shocks) +% r = dynare_simul(name, prefix, shocks) +% r = dynare_simul(name, shocks, start) +% r = dynare_simul(name, prefix, shocks, start) +% +% name name of MAT-file produced by dynare++ +% prefix prefix of variables in the MAT-file +% shocks matrix of shocks +% start zero period value +% +% SEMANTICS +% +% The command reads a decision rule from the MAT-file having the given +% prefix. Then it starts simulating the decision rule with zero time value +% equal to the given start. It uses the given shocks for the simulation. If +% the start is not given, the state about which the decision rule is +% centralized is taken (called fix point, or stochastic steady state, take +% your pick). +% +% prefix Use the prefix with which you called dynare++, the default +% prefix in dynare++ is 'dyn'. +% shocks Number of rows must be a number of exogenous shocks, +% number of columns gives the number of simulated +% periods. NaNs and Infs in the matrix are substitued by +% draws from the normal distribution using the covariance +% matrix given in the model file. +% start Vector of endogenous variables in the ordering given by +% _vars. +% +% Seed for random generator is derived from calling rand(1,1). Therefore, +% seeding can be controlled with rand('state') and rand('state',some_seed). +% +% EXAMPLES +% +% All examples suppose that the prefix is 'dyn' and that your_model.mat +% has been loaded into Matlab. +% +% 1. response to permanent negative shock to the third exo var EPS3 for +% 100 periods +% +% shocks = zeros(4,100); % 4 exogenous variables in the model +% shocks(dyn_i_EPS3,:) = -0.1; % the permanent shock to EPS3 +% r = dynare_simul('your_model.mat',shocks); +% +% 2. one stochastic simulation for 100 periods +% +% shocks = zeros(4,100)./0; % put NaNs everywhere +% r = dynare_simul('your_model.mat',shocks); +% +% 3. one stochastic simulation starting at 75% undercapitalized economy +% +% shocks = zeros(4,100)./0; % put NaNs everywhere +% ystart = dyn_ss; % get copy of DR fix point +% ystart(dyn_i_K) = 0.75*dyn_ss(dyn_i_K); % scale down the capital +% r = dynare_simul('your_model.mat',shocks,ystart); +% +% +% SEE ALSO +% +% "DSGE Models with Dynare++. A Tutorial.", Ondra Kamenik, 2005 + +function r = dynare_simul(varargin) + +% get the file name and load data +fname = varargin{1}; +eval(['load ' fname]); + +% set prefix, shocks, ystart +if ischar(varargin{2}) + prefix = varargin{2}; + if length(varargin) == 3 + shocks = varargin{3}; + ystart = NaN; + elseif length(varargin) == 4 + shocks = varargin{3}; + ystart = varargin{4}; + else + error('Wrong number of parameters.'); + end +else + prefix = 'dyn'; + if length(varargin) == 2 + shocks = varargin{2}; + ystart = NaN; + elseif length(varargin) == 3 + shocks = varargin{2}; + ystart = varargin{3}; + else + error('Wrong number of parameters.'); + end +end + +% load all needed variables but prefix_g_* +if (exist([prefix '_nstat'])) + nstat = eval([prefix '_nstat']); +else + error(['Could not find variable ' prefix '_nstat in workspace']); +end +if (exist([prefix '_npred'])) + npred = eval([prefix '_npred']); +else + error(['Could not find variable ' prefix '_npred in workspace']); +end +if (exist([prefix '_nboth'])) + nboth = eval([prefix '_nboth']); +else + error(['Could not find variable ' prefix '_nboth in workspace']); +end +if (exist([prefix '_nforw'])) + nforw = eval([prefix '_nforw']); +else + error(['Could not find variable ' prefix '_nforw in workspace']); +end +if (exist([prefix '_ss'])) + ss = eval([prefix '_ss']); +else + error(['Could not find variable ' prefix '_ss in workspace']); +end +if (exist([prefix '_vcov_exo'])) + vcov_exo = eval([prefix '_vcov_exo']); +else + error(['Could not find variable ' prefix '_vcov_exo in workspace']); +end +nexog = size(vcov_exo,1); + +if isnan(ystart) + ystart = ss; +end + +% newer version of dynare++ doesn't return prefix_g_0, we make it here if +% it does not exist in workspace +g_zero = [prefix '_g_0']; +if (~ exist(g_zero)) + eval([ g_zero '= zeros(nstat+npred+nboth+nforw,1);']); +end + +% make derstr a string of comma seperated existing prefix_g_* +derstr = [',' g_zero]; +order = 1; +cont = 1; +while cont == 1 + g_ord = [prefix '_g_' num2str(order)]; + if (exist(g_ord)) + derstr = [derstr ',' g_ord]; + order = order + 1; + else + cont = 0; + end +end + +% set seed +seed = ceil(10000*rand(1,1)); + +% call dynare_simul_ +command = ['r=dynare_simul_(' num2str(order-1) ',nstat,npred,nboth,nforw,' ... + 'nexog,ystart,shocks,vcov_exo,seed,ss' derstr ');']; +eval(command); diff --git a/mex/sources/korderpert/Dyn_pp/extern/matlab/dynarelib.a b/mex/sources/korderpert/Dyn_pp/extern/matlab/dynarelib.a new file mode 100644 index 000000000..23c7f748b Binary files /dev/null and b/mex/sources/korderpert/Dyn_pp/extern/matlab/dynarelib.a differ diff --git a/mex/sources/korderpert/Dyn_pp/extern/matlab/mexopts.bat b/mex/sources/korderpert/Dyn_pp/extern/matlab/mexopts.bat new file mode 100644 index 000000000..1e24bb561 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/extern/matlab/mexopts.bat @@ -0,0 +1,58 @@ +@echo off +rem C:\ondra\tmp\dynare++\extern\matlab\mexopts.bat +rem Generated by gnumex.m script in c:\fs\gnumex-1.11 +rem gnumex version: 1.11 +rem Compile and link options used for building MEX etc files with +rem the Mingw/Cygwin tools. Options here are: +rem Mingw linking +rem Mex (*.dll) creation +rem Safe linking to temporary libraries +rem Language: C / C++ +rem Compiling for pentium and above +rem Matlab version 7 +rem +set MATLAB=C:\MATLAB71 +set GM_PERLPATH=C:\MATLAB71\sys\perl\win32\bin\perl.exe +set GM_UTIL_PATH=c:\fs\gnumex-1.11 +set PATH=c:\fs\mingw\bin;%PATH% +rem +rem Added libraries for linking +set GM_ADD_LIBS= +rem +rem Type of file to compile (mex or engine) +set GM_MEXTYPE=mex +rem +rem Language for compilation +set GM_MEXLANG=c +rem +rem def files to be converted to libs +set GM_DEFS2LINK=libmx.def;libmex.def;libmat.def; +rem +rem dlltool command line +set GM_DLLTOOL=dlltool +rem +rem compiler options; add compiler flags to compflags as desired +set NAME_OBJECT=-o +set COMPILER=gcc +set COMPFLAGS=-c -DMATLAB_MEX_FILE +set OPTIMFLAGS=-O3 -malign-double -fno-exceptions -mcpu=pentium +set DEBUGFLAGS=-g +set CPPCOMPFLAGS=%COMPFLAGS% -x c++ +set CPPOPTIMFLAGS=%OPTIMFLAGS% +set CPPDEBUGFLAGS=%DEBUGFLAGS% +rem +rem NB Library creation commands occur in linker scripts +rem +rem Linker parameters +set LINKER=%GM_PERLPATH% %GM_UTIL_PATH%\linkmex.pl +set LINKFLAGS= +set CPPLINKFLAGS=GM_ISCPP +set LINKOPTIMFLAGS=-s +set LINKDEBUGFLAGS=-g -Wl,--image-base,0x28000000\n +set LINK_FILE= +set LINK_LIB= +set NAME_OUTPUT=-o %OUTDIR%%MEX_NAME%.dll +rem +rem Resource compiler parameters +set RC_COMPILER=%GM_PERLPATH% %GM_UTIL_PATH%\rccompile.pl -o %OUTDIR%mexversion.res +set RC_LINKER= diff --git a/mex/sources/korderpert/Dyn_pp/kord/Copy of journal.cpp b/mex/sources/korderpert/Dyn_pp/kord/Copy of journal.cpp new file mode 100644 index 000000000..738dd1eb9 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/Copy of journal.cpp @@ -0,0 +1,360 @@ +#define _W32_FT_OFFSET (116444736000000000LL) +/*1:*/ +#line 6 "./journal.cweb" + +#include "journal.h" +#include "kord_exception.h" + +#ifndef __MINGW32__ +# include +# include +#endif +#include +#include +#include + +SystemResources _sysres; +#ifdef __MINGW32__ +/*16:*/ +#line 249 "./journal.cweb" + +typedef struct _filetime{ +unsigned long dwLowDateTime; +unsigned long dwHighDateTime; +}filetime; + +extern"C"{ +void __stdcall GetSystemTimeAsFileTime(filetime*); +}; + +typedef union{ +long long ns100; +filetime ft; +}w32_ftv; + +void gettimeofday(struct timeval*p,struct timezone*tz) +{ +w32_ftv _now; +GetSystemTimeAsFileTime(&(_now.ft)); +p->tv_usec= (long)((_now.ns100/10LL)%1000000LL); +p->tv_sec= (long)((_now.ns100-_W32_FT_OFFSET)/10000000LL); +return; +} + +/*:16*/ +#line 20 "./journal.cweb" +; +/*17:*/ +#line 282 "./journal.cweb" + +#define _SC_PAGESIZE 1 +#define _SC_PHYS_PAGES 2 +#define _SC_AVPHYS_PAGES 3 +#define _SC_NPROCESSORS_ONLN 4 + +struct Win32MemoryStatus{ +unsigned long dwLength; +unsigned long dwMemoryLoad; +unsigned int dwTotalPhys; +unsigned int dwAvailPhys; +unsigned int dwTotalPageFile; +unsigned int dwAvailPageFile; +unsigned int dwTotalVirtual; +unsigned int dwAvailVirtual; +Win32MemoryStatus(); +}; + +extern"C"{ +void __stdcall GlobalMemoryStatus(Win32MemoryStatus*); +}; + +Win32MemoryStatus::Win32MemoryStatus() +{ +dwLength= sizeof(Win32MemoryStatus); +GlobalMemoryStatus(this); +} + +long sysconf(int name) +{ +switch(name){ +case _SC_PAGESIZE: +return 1024; +case _SC_PHYS_PAGES: +{ +Win32MemoryStatus memstat; +return memstat.dwTotalPhys/1024; +} +case _SC_AVPHYS_PAGES: +{ +Win32MemoryStatus memstat; +return memstat.dwAvailPhys/1024; +} +case _SC_NPROCESSORS_ONLN: +return-1; +default: +KORD_RAISE("Not implemented in Win32 sysconf."); +return-1; +} +} + +/*:17*/ +#line 21 "./journal.cweb" +; +#endif + +/*2:*/ +#line 40 "./journal.cweb" + +SystemResources::SystemResources() +{ +gettimeofday(&start,NULL); +} + + +/*:2*/ +#line 24 "./journal.cweb" +; +/*3:*/ +#line 48 "./journal.cweb" + +long int SystemResources::pageSize() +{ +return sysconf(_SC_PAGESIZE); +} + +/*:3*/ +#line 25 "./journal.cweb" +; +/*4:*/ +#line 55 "./journal.cweb" + +long int SystemResources::physicalPages() +{ +return sysconf(_SC_PHYS_PAGES); +} + +/*:4*/ +#line 26 "./journal.cweb" +; +/*5:*/ +#line 62 "./journal.cweb" + +long int SystemResources::onlineProcessors() +{ +return sysconf(_SC_NPROCESSORS_ONLN); +} + +/*:5*/ +#line 27 "./journal.cweb" +; +/*6:*/ +#line 69 "./journal.cweb" + +long int SystemResources::availableMemory() +{ +return pageSize()*sysconf(_SC_AVPHYS_PAGES); +} + +/*:6*/ +#line 28 "./journal.cweb" +; +/*7:*/ +#line 78 "./journal.cweb" + +void SystemResources::getRUS(double&load_avg,long int&pg_avail, +double&utime,double&stime,double&elapsed, +long int&idrss,long int&majflt) +{ +struct timeval now; +gettimeofday(&now,NULL); +elapsed= now.tv_sec-start.tv_sec+(now.tv_usec-start.tv_usec)*1.0e-6; + +#ifndef __MINGW32__ +struct rusage rus; +getrusage(RUSAGE_SELF,&rus); +utime= rus.ru_utime.tv_sec+rus.ru_utime.tv_usec*1.0e-6; +stime= rus.ru_stime.tv_sec+rus.ru_stime.tv_usec*1.0e-6; +idrss= rus.ru_idrss; +majflt= rus.ru_majflt; + +getloadavg(&load_avg,1); +#else +utime= -1.0; +stime= -1.0; +idrss= -1; +majflt= -1; +load_avg= -1.0; +#endif +pg_avail= sysconf(_SC_AVPHYS_PAGES); +} + +/*:7*/ +#line 29 "./journal.cweb" +; +/*8:*/ +#line 107 "./journal.cweb" + +SystemResourcesFlash::SystemResourcesFlash() +{ +_sysres.getRUS(load_avg,pg_avail,utime,stime, +elapsed,idrss,majflt); +} + +/*:8*/ +#line 30 "./journal.cweb" +; +/*9:*/ +#line 115 "./journal.cweb" + +void SystemResourcesFlash::diff(const SystemResourcesFlash&pre) +{ +utime-= pre.utime; +stime-= pre.stime; +elapsed-= pre.elapsed; +idrss-= pre.idrss; +majflt-= pre.majflt; +} + +/*:9*/ +#line 31 "./journal.cweb" +; +/*10:*/ +#line 126 "./journal.cweb" + +JournalRecord&JournalRecord::operator<<(const IntSequence&s) +{ +operator<<("["); +for(int i= 0;i (4,1) +{ +stack_sizes[0]= ngss;stack_sizes[1]= ng; +stack_sizes[2]= ny;stack_sizes[3]= nu; +conts[0]= gss; +calculateOffsets(); +} + + +/*:2*/ +#line 12 "./approximation.cweb" +; +/*3:*/ +#line 41 "./approximation.cweb" + +ZAuxContainer::itype ZAuxContainer::getType(int i,const Symmetry&s)const +{ +if(i==0) +if(s[2]> 0) +return zero; +else +return matrix; +return zero; +} + + +/*:3*/ +#line 13 "./approximation.cweb" +; +/*4:*/ +#line 54 "./approximation.cweb" + +Approximation::Approximation(DynamicModel&m,Journal&j,int ns) +:model(m),journal(j),rule_ders(NULL),rule_ders_ss(NULL),fdr(NULL),udr(NULL), +ypart(model.nstat(),model.npred(),model.nboth(),model.nforw()), +mom(UNormalMoments(model.order(),model.getVcov())),nvs(4),steps(ns), +ss(ypart.ny(),steps+1) +{ +nvs[0]= ypart.nys();nvs[1]= model.nexog(); +nvs[2]= model.nexog();nvs[3]= 1; + +ss.nans(); +} + +/*:4*/ +#line 14 "./approximation.cweb" +; +/*5:*/ +#line 68 "./approximation.cweb" + +Approximation::~Approximation() +{ +if(rule_ders_ss)delete rule_ders_ss; +if(rule_ders)delete rule_ders; +if(fdr)delete fdr; +if(udr)delete udr; +} + +/*:5*/ +#line 15 "./approximation.cweb" +; +/*6:*/ +#line 78 "./approximation.cweb" + +const FoldDecisionRule&Approximation::getFoldDecisionRule()const +{ +KORD_RAISE_IF(fdr==NULL, +"Folded decision rule has not been created in Approximation::getFoldDecisionRule"); +return*fdr; +} + + +/*:6*/ +#line 16 "./approximation.cweb" +; +/*7:*/ +#line 88 "./approximation.cweb" + +const UnfoldDecisionRule&Approximation::getUnfoldDecisionRule()const +{ +KORD_RAISE_IF(udr==NULL, +"Unfolded decision rule has not been created in Approximation::getUnfoldDecisionRule"); +return*udr; +} + + +/*:7*/ +#line 17 "./approximation.cweb" +; +/*8:*/ +#line 102 "./approximation.cweb" + +void Approximation::approxAtSteady() +{ +model.calcDerivativesAtSteady(); +FirstOrder fo(model.nstat(),model.npred(),model.nboth(),model.nforw(), +model.nexog(),*(model.getModelDerivatives().get(Symmetry(1))), +journal); +KORD_RAISE_IF_X(!fo.isStable(), +"The model is not Blanchard-Kahn stable", +KORD_MD_NOT_STABLE); + +if(model.order()>=2){ +KOrder korder(model.nstat(),model.npred(),model.nboth(),model.nforw(), +model.getModelDerivatives(),fo.getGy(),fo.getGu(), +model.getVcov(),journal); +korder.switchToFolded(); +for(int k= 2;k<=model.order();k++) +korder.performStep (k); + +saveRuleDerivs(korder.getFoldDers()); +}else{ +FirstOrderDerivs fo_ders(fo); +saveRuleDerivs(fo_ders); +} +check(0.0); +} + +/*:8*/ +#line 18 "./approximation.cweb" +; +/*9:*/ +#line 159 "./approximation.cweb" + +void Approximation::walkStochSteady() +{ +/*10:*/ +#line 186 "./approximation.cweb" + +model.solveDeterministicSteady(); +approxAtSteady(); +Vector steady0(ss,0); +steady0= (const Vector&)model.getSteady(); + +/*:10*/ +#line 162 "./approximation.cweb" +; +double sigma_so_far= 0.0; +double dsigma= (steps==0)?0.0:1.0/steps; +for(int i= 1;i<=steps;i++){ +JournalRecordPair pa(journal); +pa<<"Approximation about stochastic steady for sigma="< fp(*rule_ders,ypart,model.getSteady(),dsigma); +bool converged= fp.calcFixPoint(DecisionRule::horner,model.getSteady()); +JournalRecord rec(journal); +rec<<"Fix point calcs: iter="< hh(ypart,model.nexog(),*rule_ders_ss,mom,dy, +dsigma,sigma_so_far); +JournalRecord rec1(journal); +rec1<<"Calculation of g** expectations done"< (d); +} +saveRuleDerivs(korder_stoch.getFoldDers()); + + +/*:13*/ +#line 173 "./approximation.cweb" +; + +check(sigma_so_far+dsigma); +sigma_so_far+= dsigma; +} + +/*14:*/ +#line 240 "./approximation.cweb" + +if(fdr){ +delete fdr; +fdr= NULL; +} +if(udr){ +delete udr; +udr= NULL; +} + +fdr= new FoldDecisionRule(*rule_ders,ypart,model.nexog(), +model.getSteady(),1.0-sigma_so_far); +if(steps==0){ +/*15:*/ +#line 258 "./approximation.cweb" + +DRFixPoint fp(*rule_ders,ypart,model.getSteady(),1.0); +bool converged= fp.calcFixPoint(DecisionRule::horner,model.getSteady()); +JournalRecord rec(journal); +rec<<"Fix point calcs: iter="<insert(ten); +} +} + +/*:16*/ +#line 20 "./approximation.cweb" +; +/*17:*/ +#line 312 "./approximation.cweb" + +void Approximation::calcStochShift(Vector&out,double at_sigma)const +{ +KORD_RAISE_IF(out.length()!=ypart.ny(), +"Wrong length of output vector for Approximation::calcStochShift"); +out.zeros(); + +ZAuxContainer zaux(rule_ders_ss,ypart.nyss(),ypart.ny(), +ypart.nys(),model.nexog()); + +int dfac= 1; +for(int d= 1;d<=rule_ders->getMaxDim();d++,dfac*= d){ +if(KOrder::is_even(d)){ +Symmetry sym(0,d,0,0); +/*18:*/ +#line 333 "./approximation.cweb" + +FGSTensor*ten= new FGSTensor(ypart.ny(),TensorDimens(sym,nvs)); +ten->zeros(); +for(int l= 1;l<=d;l++){ +const FSSparseTensor*f= model.getModelDerivatives().get(Symmetry(l)); +zaux.multAndAdd(*f,*ten); +} + +/*:18*/ +#line 326 "./approximation.cweb" +; +/*19:*/ +#line 342 "./approximation.cweb" + +FGSTensor*tmp= new FGSTensor(ypart.ny(),TensorDimens(Symmetry(0,0,0,0),nvs)); +tmp->zeros(); +ten->contractAndAdd(1,*tmp,*(mom.get(Symmetry(d)))); + +out.add(pow(at_sigma,d)/dfac,tmp->getData()); +delete ten; +delete tmp; + + +/*:19*/ +#line 327 "./approximation.cweb" +; +} +} +} + +/*:17*/ +#line 21 "./approximation.cweb" +; +/*20:*/ +#line 359 "./approximation.cweb" + +void Approximation::check(double at_sigma)const +{ +Vector stoch_shift(ypart.ny()); +Vector system_resid(ypart.ny()); +Vector xx(model.nexog()); +xx.zeros(); +model.evaluateSystem(system_resid,model.getSteady(),xx); +calcStochShift(stoch_shift,at_sigma); +stoch_shift.add(1.0,system_resid); +JournalRecord rec1(journal); +rec1<<"Error of current approximation for shocks at sigma "<get(Symmetry(1,0,0,0))); +const TwoDMatrix&gu= *(rule_ders->get(Symmetry(0,1,0,0))); +TwoDMatrix G(model.numeq(),model.numeq()); +G.zeros(); +G.place(gy,0,model.nstat()); +TwoDMatrix B((const TwoDMatrix&)G); +B.mult(-1.0); +TwoDMatrix C(G,"transpose"); +TwoDMatrix A(model.numeq(),model.numeq()); +A.zeros(); +for(int i= 0;ibase()); +gs.solve(); + +return X; +} + +/*:21*/ +#line 23 "./approximation.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/approximation.h b/mex/sources/korderpert/Dyn_pp/kord/approximation.h new file mode 100644 index 000000000..928d377a1 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/approximation.h @@ -0,0 +1,71 @@ +/*1:*/ +#line 53 "./approximation.hweb" + +#ifndef APPROXIMATION_H +#define APPROXIMATION_H + +#include "dynamic_model.h" +#include "decision_rule.h" +#include "korder.h" +#include "journal.h" + +/*2:*/ +#line 80 "./approximation.hweb" + +class ZAuxContainer:public StackContainer ,public FoldedStackContainer{ +public: +typedef StackContainer ::_Ctype _Ctype; +typedef StackContainer ::itype itype; +ZAuxContainer(const _Ctype*gss,int ngss,int ng,int ny,int nu); +itype getType(int i,const Symmetry&s)const; +}; + + + +/*:2*/ +#line 62 "./approximation.hweb" +; +/*3:*/ +#line 115 "./approximation.hweb" + +class Approximation{ +DynamicModel&model; +Journal&journal; +FGSContainer*rule_ders; +FGSContainer*rule_ders_ss; +FoldDecisionRule*fdr; +UnfoldDecisionRule*udr; +const PartitionY ypart; +const FNormalMoments mom; +IntSequence nvs; +int steps; +TwoDMatrix ss; +public: +Approximation(DynamicModel&m,Journal&j,int ns); +virtual~Approximation(); + +const FoldDecisionRule&getFoldDecisionRule()const; +const UnfoldDecisionRule&getUnfoldDecisionRule()const; +const TwoDMatrix&getSS()const +{return ss;} +const DynamicModel&getModel()const +{return model;} + +void walkStochSteady(); +TwoDMatrix*calcYCov()const; +protected: +void approxAtSteady(); +void calcStochShift(Vector&out,double at_sigma)const; +void saveRuleDerivs(const FGSContainer&g); +void check(double at_sigma)const; +}; + + +/*:3*/ +#line 63 "./approximation.hweb" +; + +#endif + + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/decision_rule.cpp b/mex/sources/korderpert/Dyn_pp/kord/decision_rule.cpp new file mode 100644 index 000000000..675a53f1a --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/decision_rule.cpp @@ -0,0 +1,793 @@ +/*1:*/ +#line 5 "./decision_rule.cweb" + + +#include "kord_exception.h" +#include "decision_rule.h" +#include "dynamic_model.h" + +#include "SymSchurDecomp.h" +#include "cpplapack.h" + +#include + +template<> +int DRFixPoint ::max_iter= 10000; +template<> +int DRFixPoint ::max_iter= 10000; +template<> +double DRFixPoint ::tol= 1.e-10; +template<> +double DRFixPoint ::tol= 1.e-10; +template<> +int DRFixPoint ::max_newton_iter= 50; +template<> +int DRFixPoint ::max_newton_iter= 50; +template<> +int DRFixPoint ::newton_pause= 100; +template<> +int DRFixPoint ::newton_pause= 100; + +/*2:*/ +#line 72 "./decision_rule.cweb" + +FoldDecisionRule::FoldDecisionRule(const UnfoldDecisionRule&udr) +:DecisionRuleImpl (ctraits ::Tpol(udr.nrows(),udr.nvars()), +udr.ypart,udr.nu,udr.ysteady) +{ +for(ctraits ::Tpol::const_iterator it= udr.begin(); +it!=udr.end();++it){ +insert(new ctraits ::Ttensym(*((*it).second))); +} +} + +/*:2*/ +#line 33 "./decision_rule.cweb" +; +/*3:*/ +#line 84 "./decision_rule.cweb" + +UnfoldDecisionRule::UnfoldDecisionRule(const FoldDecisionRule&fdr) +:DecisionRuleImpl (ctraits ::Tpol(fdr.nrows(),fdr.nvars()), +fdr.ypart,fdr.nu,fdr.ysteady) +{ +for(ctraits ::Tpol::const_iterator it= fdr.begin(); +it!=fdr.end();++it){ +insert(new ctraits ::Ttensym(*((*it).second))); +} +} + +/*:3*/ +#line 34 "./decision_rule.cweb" +; +/*4:*/ +#line 96 "./decision_rule.cweb" + +SimResults::~SimResults() +{ +for(int i= 0;i 0){ +JournalRecord rec(journal); +rec<<"I had to throw "< rsrs; +rsrs.reserve(num_sim); + +THREAD_GROUP gr; +for(int i= 0;inrows()!=num_y, +"Incompatible number of rows for SimResults::addDataSets"); +KORD_RAISE_IF(d->ncols()!=num_per, +"Incompatible number of cols for SimResults::addDataSets"); +if(d->isFinite()){ +data.push_back(d); +shocks.push_back(sr); +return true; +}else{ +delete d; +delete sr; +return false; +} +} + +/*:7*/ +#line 38 "./decision_rule.cweb" +; +/*8:*/ +#line 168 "./decision_rule.cweb" + +void SimResults::writeMat4(const char*base,const char*lname)const +{ +char matfile_name[100]; +sprintf(matfile_name,"%s.mat",base); +FILE*out; +if(NULL!=(out= fopen(matfile_name,"wb"))){ +writeMat4(out,lname); +fclose(out); +} +} + +/*:8*/ +#line 39 "./decision_rule.cweb" +; +/*9:*/ +#line 183 "./decision_rule.cweb" + +void SimResults::writeMat4(FILE*fd,const char*lname)const +{ +char tmp[100]; +for(int i= 0;i 1) +sprintf(tmp,"%s_data%d",lname,i+1); +else +sprintf(tmp,"%s_data",lname); +ConstTwoDMatrix m(*(data[i])); +m.writeMat4(fd,tmp); +} +} + +/*:9*/ +#line 40 "./decision_rule.cweb" +; +/*10:*/ +#line 198 "./decision_rule.cweb" + +void SimResultsStats::simulate(int num_sim,const DecisionRule&dr, +const Vector&start, +const TwoDMatrix&vcov,Journal&journal) +{ +SimResults::simulate(num_sim,dr,start,vcov,journal); +{ +JournalRecordPair paa(journal); +paa<<"Calculating means from the simulations."< 0){ +double mult= 1.0/data.size()/num_per; +for(unsigned int i= 0;i 1){ +vcov.zeros(); +double mult= 1.0/(data.size()*num_per-1); +for(unsigned int i= 0;i 0){ +double mult= 1.0/data.size(); +for(int j= 0;j 1){ +variance.zeros(); +double mult= 1.0/(data.size()-1); +for(int j= 0;j 0){ +for(unsigned int i= 0;i 1){ +variances.zeros(); +for(unsigned int i= 0;i 0){ +JournalRecord rec(journal); +rec<<"I had to throw "< rsrs; +rsrs.reserve(num_sim); + +THREAD_GROUP gr; +for(int i= 0;i &ili, +Journal&journal) +:model(mod),irf_list_ind(ili) +{ +int num_per= control.getNumPer(); +JournalRecordPair pa(journal); +pa<<"Calculating IRFs against control for "<<(int)irf_list_ind.size()<<" shocks and for " +<simulate(dr,model.getSteady(),journal); +irf_res[2*ii+1]->simulate(dr,model.getSteady(),journal); +} +} + +/*:26*/ +#line 57 "./decision_rule.cweb" +; +/*27:*/ +#line 497 "./decision_rule.cweb" + +IRFResults::~IRFResults() +{ +for(unsigned int i= 0;iwriteMat4(fd,tmp); +sprintf(tmp,"%s_irfm_%s",prefix,shockname); +irf_res[2*i+1]->writeMat4(fd,tmp); +} +} + +/*:28*/ +#line 59 "./decision_rule.cweb" +; +/*29:*/ +#line 520 "./decision_rule.cweb" + +void SimulationWorker::operator()() +{ +ExplicitShockRealization*esr= new ExplicitShockRealization(sr,np); +TwoDMatrix*m= dr.simulate(em,np,st,*esr); +{ +SYNCHRO syn(&res,"simulation"); +res.addDataSet(m,esr); +} +} + +/*:29*/ +#line 60 "./decision_rule.cweb" +; +/*30:*/ +#line 534 "./decision_rule.cweb" + +void SimulationIRFWorker::operator()() +{ +ExplicitShockRealization*esr= +new ExplicitShockRealization(res.control.getShocks(idata)); +esr->addToShock(ishock,0,imp); +TwoDMatrix*m= dr.simulate(em,np,st,*esr); +m->add(-1.0,res.control.getData(idata)); +{ +SYNCHRO syn(&res,"simulation"); +res.addDataSet(m,esr); +} +} + +/*:30*/ +#line 61 "./decision_rule.cweb" +; +/*31:*/ +#line 549 "./decision_rule.cweb" + +void RTSimulationWorker::operator()() +{ +NormalConj nc(res.nc.getDim()); +const PartitionY&ypart= dr.getYPart(); +int nu= dr.nexog(); +const Vector&ysteady= dr.getSteady(); + +/*32:*/ +#line 571 "./decision_rule.cweb" + +Vector dyu(ypart.nys()+nu); +ConstVector ystart_pred(ystart,ypart.nstat,ypart.nys()); +ConstVector ysteady_pred(ysteady,ypart.nstat,ypart.nys()); +Vector dy(dyu,0,ypart.nys()); +Vector u(dyu,ypart.nys(),nu); +Vector y(nc.getDim()); +ConstVector ypred(y,ypart.nstat,ypart.nys()); + +/*:32*/ +#line 557 "./decision_rule.cweb" +; +/*33:*/ +#line 581 "./decision_rule.cweb" + +int ip= 0; +dy= ystart_pred; +dy.add(-1.0,ysteady_pred); +sr.get(ip,u); +dr.eval(em,y,dyu); +nc.update(y); + +/*:33*/ +#line 558 "./decision_rule.cweb" +; +/*34:*/ +#line 590 "./decision_rule.cweb" + +while(y.isFinite()&&ip 0){ +res.incomplete_simulations++; +res.thrown_periods+= res.num_per-ip; +} +} +} + +/*:31*/ +#line 62 "./decision_rule.cweb" +; +/*35:*/ +#line 602 "./decision_rule.cweb" + +void RandomShockRealization::choleskyFactor(const TwoDMatrix&v) +{ +factor= v; +int rows= factor.nrows(); +for(int i= 0;i numShocks(), +"Wrong index of shock in ExplicitShockRealization::addToShock"); +int j= iper%shocks.ncols(); +shocks.get(ishock,j)+= val; +} + + +/*:40*/ +#line 68 "./decision_rule.cweb" +; +/*41:*/ +#line 676 "./decision_rule.cweb" + +void GenShockRealization::get(int n,Vector&out) +{ +KORD_RAISE_IF(out.length()!=numShocks(), +"Wrong length of out vector in GenShockRealization::get"); +ExplicitShockRealization::get(n,out); +Vector r(numShocks()); +RandomShockRealization::get(n,r); +for(int j= 0;j +class DecisionRuleImpl:public ctraits ::Tpol,public DecisionRule{ +protected: +typedef typename ctraits ::Tpol _Tparent; +const Vector ysteady; +const PartitionY ypart; +const int nu; +public: +DecisionRuleImpl(const _Tparent&pol,const PartitionY&yp,int nuu, +const Vector&ys) +:ctraits ::Tpol(pol),ysteady(ys),ypart(yp),nu(nuu){} +DecisionRuleImpl(_Tparent&pol,const PartitionY&yp,int nuu, +const Vector&ys) +:ctraits ::Tpol(0,yp.ny(),pol),ysteady(ys),ypart(yp), +nu(nuu){} +DecisionRuleImpl(const _Tg&g,const PartitionY&yp,int nuu, +const Vector&ys,double sigma) +:ctraits ::Tpol(yp.ny(),yp.nys()+nuu),ysteady(ys),ypart(yp),nu(nuu) +{fillTensors(g,sigma);} +DecisionRuleImpl(const DecisionRuleImpl &dr,const ConstVector&fixpoint) +:ctraits ::Tpol(dr.ypart.ny(),dr.ypart.nys()+dr.nu), +ysteady(fixpoint),ypart(dr.ypart),nu(dr.nu) +{centralize(dr);} +const Vector&getSteady()const +{return ysteady;} +/*8:*/ +#line 290 "./decision_rule.hweb" + +TwoDMatrix*simulate(emethod em,int np,const Vector&ystart, +ShockRealization&sr)const +{ +KORD_RAISE_IF(ysteady.length()!=ystart.length(), +"Start and steady lengths differ in DecisionRuleImpl::simulate"); +TwoDMatrix*res= new TwoDMatrix(ypart.ny(),np); + +/*9:*/ +#line 309 "./decision_rule.hweb" + +Vector dyu(ypart.nys()+nu); +ConstVector ystart_pred(ystart,ypart.nstat,ypart.nys()); +ConstVector ysteady_pred(ysteady,ypart.nstat,ypart.nys()); +Vector dy(dyu,0,ypart.nys()); +Vector u(dyu,ypart.nys(),nu); + + +/*:9*/ +#line 298 "./decision_rule.hweb" +; +/*10:*/ +#line 320 "./decision_rule.hweb" + +dy= ystart_pred; +dy.add(-1.0,ysteady_pred); +sr.get(0,u); +Vector out(*res,0); +eval(em,out,dyu); + +/*:10*/ +#line 299 "./decision_rule.hweb" +; +/*11:*/ +#line 330 "./decision_rule.hweb" + +for(int i= 1;incols();i++){ +Vector col(*res,i); +col.add(1.0,ysteady); +} + + +/*:12*/ +#line 301 "./decision_rule.hweb" +; +return res; +} + +/*:8*/ +#line 160 "./decision_rule.hweb" +; +/*13:*/ +#line 360 "./decision_rule.hweb" + +void evaluate(emethod em,Vector&out,const ConstVector&ys, +const ConstVector&u)const +{ +KORD_RAISE_IF(ys.length()!=ypart.nys()||u.length()!=nu, +"Wrong dimensions of input vectors in DecisionRuleImpl::evaluate"); +KORD_RAISE_IF(out.length()!=ypart.ny(), +"Wrong dimension of output vector in DecisionRuleImpl::evaluate"); +ConstVector ysteady_pred(ysteady,ypart.nstat,ypart.nys()); +Vector ys_u(ypart.nys()+nu); +Vector ys_u1(ys_u,0,ypart.nys()); +ys_u1= ys; +ys_u1.add(-1.0,ysteady_pred); +Vector ys_u2(ys_u,ypart.nys(),nu); +ys_u2= u; +eval(em,out,ys_u); +out.add(1.0,ysteady); +} + +/*:13*/ +#line 161 "./decision_rule.hweb" +; +/*14:*/ +#line 382 "./decision_rule.hweb" + +DecisionRule*centralizedClone(const Vector&fixpoint)const +{ +return new DecisionRuleImpl (*this,fixpoint); +} + +/*:14*/ +#line 162 "./decision_rule.hweb" +; +/*16:*/ +#line 401 "./decision_rule.hweb" + +void writeMat4(FILE*fd,const char*prefix)const +{ +ctraits ::Tpol::writeMat4(fd,prefix); +TwoDMatrix dum(ysteady.length(),1); +dum.getData()= ysteady; +char tmp[100]; +sprintf(tmp,"%s_ss",prefix); +ConstTwoDMatrix(dum).writeMat4(fd,tmp); +} + +/*:16*/ +#line 163 "./decision_rule.hweb" +; +int nexog()const +{return nu;} +const PartitionY&getYPart()const +{return ypart;} +protected: +/*5:*/ +#line 210 "./decision_rule.hweb" + +void fillTensors(const _Tg&g,double sigma) +{ +IntSequence tns(2); +tns[0]= ypart.nys();tns[1]= nu; +int dfact= 1; +for(int d= 0;d<=g.getMaxDim();d++,dfact*= d){ +_Ttensym*g_yud= new _Ttensym(ypart.ny(),ypart.nys()+nu,d); +g_yud->zeros(); +/*6:*/ +#line 234 "./decision_rule.hweb" + +for(int i= 0;i<=d;i++){ +int j= d-i; +int kfact= 1; +_Ttensor tmp(ypart.ny(), +TensorDimens(Symmetry(i,j),tns)); +tmp.zeros(); +for(int k= 0;k+d<=g.getMaxDim();k++,kfact*= k){ +Symmetry sym(i,j,0,k); +if(g.check(sym)){ +double mult= pow(sigma,k)/dfact/kfact; +tmp.add(mult,*(g.get(sym))); +} +} +g_yud->addSubTensor(tmp); +} + +/*:6*/ +#line 219 "./decision_rule.hweb" +; +insert(g_yud); +} +} + +/*:5*/ +#line 169 "./decision_rule.hweb" +; +/*7:*/ +#line 260 "./decision_rule.hweb" + +void centralize(const DecisionRuleImpl&dr) +{ +Vector dstate(ypart.nys()+nu); +dstate.zeros(); +Vector dstate_star(dstate,0,ypart.nys()); +ConstVector newsteady_star(ysteady,ypart.nstat,ypart.nys()); +ConstVector oldsteady_star(dr.ysteady,ypart.nstat,ypart.nys()); +dstate_star.add(1.0,newsteady_star); +dstate_star.add(-1.0,oldsteady_star); + +_Tpol pol(dr); +for(int d= 1;d<=dr.getMaxDim();d++){ +pol.derivative(d-1); +_Ttensym*der= pol.evalPartially(d,dstate); +insert(der); +} +} + +/*:7*/ +#line 170 "./decision_rule.hweb" +; +/*15:*/ +#line 391 "./decision_rule.hweb" + +void eval(emethod em,Vector&out,const ConstVector&v)const +{ +if(em==DecisionRule::horner) +_Tparent::evalHorner(out,v); +else +_Tparent::evalTrad(out,v); +} + +/*:15*/ +#line 171 "./decision_rule.hweb" +; +}; + +/*:4*/ +#line 49 "./decision_rule.hweb" +; +/*17:*/ +#line 417 "./decision_rule.hweb" + +class UnfoldDecisionRule; +class FoldDecisionRule:public DecisionRuleImpl { +friend class UnfoldDecisionRule; +public: +FoldDecisionRule(const ctraits ::Tpol&pol,const PartitionY&yp,int nuu, +const Vector&ys) +:DecisionRuleImpl (pol,yp,nuu,ys){} +FoldDecisionRule(ctraits ::Tpol&pol,const PartitionY&yp,int nuu, +const Vector&ys) +:DecisionRuleImpl (pol,yp,nuu,ys){} +FoldDecisionRule(const ctraits ::Tg&g,const PartitionY&yp,int nuu, +const Vector&ys,double sigma) +:DecisionRuleImpl (g,yp,nuu,ys,sigma){} +FoldDecisionRule(const DecisionRuleImpl &dr,const ConstVector&fixpoint) +:DecisionRuleImpl (dr,fixpoint){} +FoldDecisionRule(const UnfoldDecisionRule&udr); +}; + +/*:17*/ +#line 50 "./decision_rule.hweb" +; +/*18:*/ +#line 440 "./decision_rule.hweb" + +class UnfoldDecisionRule:public DecisionRuleImpl { +friend class FoldDecisionRule; +public: +UnfoldDecisionRule(const ctraits ::Tpol&pol,const PartitionY&yp,int nuu, +const Vector&ys) +:DecisionRuleImpl (pol,yp,nuu,ys){} +UnfoldDecisionRule(ctraits ::Tpol&pol,const PartitionY&yp,int nuu, +const Vector&ys) +:DecisionRuleImpl (pol,yp,nuu,ys){} +UnfoldDecisionRule(const ctraits ::Tg&g,const PartitionY&yp,int nuu, +const Vector&ys,double sigma) +:DecisionRuleImpl (g,yp,nuu,ys,sigma){} +UnfoldDecisionRule(const DecisionRuleImpl &dr,const ConstVector&fixpoint) +:DecisionRuleImpl (dr,fixpoint){} +UnfoldDecisionRule(const FoldDecisionRule&udr); +}; + + +/*:18*/ +#line 51 "./decision_rule.hweb" +; +/*19:*/ +#line 472 "./decision_rule.hweb" + +template +class DRFixPoint:public ctraits ::Tpol{ +typedef typename ctraits ::Tpol _Tparent; +static int max_iter; +static int max_newton_iter; +static int newton_pause; +static double tol; +const Vector ysteady; +const PartitionY ypart; +_Tparent*bigf; +_Tparent*bigfder; +public: +typedef typename DecisionRule::emethod emethod; +/*20:*/ +#line 511 "./decision_rule.hweb" + +DRFixPoint(const _Tg&g,const PartitionY&yp, +const Vector&ys,double sigma) +:ctraits ::Tpol(yp.ny(),yp.nys()), +ysteady(ys),ypart(yp),bigf(NULL),bigfder(NULL) +{ +fillTensors(g,sigma); +_Tparent yspol(ypart.nstat,ypart.nys(),*this); +bigf= new _Tparent((const _Tparent&)yspol); +_Ttensym*frst= bigf->get(Symmetry(1)); +for(int i= 0;iget(i,i)= frst->get(i,i)-1; +bigfder= new _Tparent(*bigf,0); +} + +/*:20*/ +#line 486 "./decision_rule.hweb" +; +/*21:*/ +#line 527 "./decision_rule.hweb" + +virtual~DRFixPoint() +{ +if(bigf) +delete bigf; +if(bigfder) +delete bigfder; +} + +/*:21*/ +#line 487 "./decision_rule.hweb" +; +/*25:*/ +#line 650 "./decision_rule.hweb" + +bool calcFixPoint(emethod em,Vector&out) +{ +KORD_RAISE_IF(out.length()!=ypart.ny(), +"Wrong length of out in DRFixPoint::calcFixPoint"); + +Vector delta(ypart.nys()); +Vector ystar(ypart.nys()); +ystar.zeros(); + +iter= 0; +newton_iter_last= 0; +newton_iter_total= 0; +bool converged= false; +do{ +if((iter/newton_pause)*newton_pause==iter) +converged= solveNewton(ystar); +if(!converged){ +bigf->evalHorner(delta,ystar); +KORD_RAISE_IF_X(!delta.isFinite(), +"NaN or Inf asserted in DRFixPoint::calcFixPoint", +KORD_FP_NOT_FINITE); +ystar.add(1.0,delta); +converged= delta.getNorm()zeros(); +int kfact= 1; +for(int k= 0;d+k<=g.getMaxDim();k++,kfact*= k){ +if(g.check(Symmetry(d,0,0,k))){ +const _Ttensor*ten= g.get(Symmetry(d,0,0,k)); +double mult= pow(sigma,k)/dfact/kfact; +g_yd->add(mult,*ten); +} +} +insert(g_yd); +} +} + +/*:22*/ +#line 496 "./decision_rule.hweb" +; +/*23:*/ +#line 575 "./decision_rule.hweb" + +bool solveNewton(Vector&y) +{ +const double urelax_threshold= 1.e-5; +Vector sol((const Vector&)y); +Vector delta(y.length()); +newton_iter_last= 0; +bool delta_finite= true; +double flastnorm= 0.0; +double fnorm= 0.0; +bool converged= false; +double urelax= 1.0; + +do{ +_Ttensym*jacob= bigfder->evalPartially(1,sol); +bigf->evalHorner(delta,sol); +if(newton_iter_last==0) +flastnorm= delta.getNorm(); +delta_finite= delta.isFinite(); +if(delta_finite){ +ConstTwoDMatrix(*jacob).multInvLeft(delta); +/*24:*/ +#line 620 "./decision_rule.hweb" + +bool urelax_found= false; +urelax= 1.0; +while(!urelax_found&&urelax> urelax_threshold){ +Vector soltmp((const Vector&)sol); +soltmp.add(-urelax,delta); +Vector f(sol.length()); +bigf->evalHorner(f,soltmp); +fnorm= f.getNorm(); +if(fnorm<=flastnorm) +urelax_found= true; +else +urelax*= std::min(0.5,flastnorm/fnorm); +} + + +/*:24*/ +#line 596 "./decision_rule.hweb" +; +sol.add(-urelax,delta); +delta_finite= delta.isFinite(); +} +delete jacob; +newton_iter_last++; +converged= delta_finite&&fnorm urelax_threshold); + +newton_iter_total+= newton_iter_last; +if(!converged) +newton_iter_last= 0; +y= (const Vector&)sol; +return converged; +} + +/*:23*/ +#line 497 "./decision_rule.hweb" +; +private: +int iter; +int newton_iter_last; +int newton_iter_total; +}; + + +/*:19*/ +#line 52 "./decision_rule.hweb" +; +/*26:*/ +#line 691 "./decision_rule.hweb" + +class ExplicitShockRealization; +class SimResults{ +protected: +int num_y; +int num_per; +vector data; +vector shocks; +public: +SimResults(int ny,int nper) +:num_y(ny),num_per(nper){} +virtual~SimResults(); +void simulate(int num_sim,const DecisionRule&dr,const Vector&start, +const TwoDMatrix&vcov,Journal&journal); +void simulate(int num_sim,const DecisionRule&dr,const Vector&start, +const TwoDMatrix&vcov); +int getNumPer()const +{return num_per;} +int getNumSets()const +{return(int)data.size();} +const TwoDMatrix&getData(int i)const +{return*(data[i]);} +const ExplicitShockRealization&getShocks(int i)const +{return*(shocks[i]);} +bool addDataSet(TwoDMatrix*d,ExplicitShockRealization*sr); +void writeMat4(const char*base,const char*lname)const; +void writeMat4(FILE*fd,const char*lname)const; +}; + +/*:26*/ +#line 53 "./decision_rule.hweb" +; +/*27:*/ +#line 723 "./decision_rule.hweb" + +class SimResultsStats:public SimResults{ +protected: +Vector mean; +TwoDMatrix vcov; +public: +SimResultsStats(int ny,int nper) +:SimResults(ny,nper),mean(ny),vcov(ny,ny){} +void simulate(int num_sim,const DecisionRule&dr,const Vector&start, +const TwoDMatrix&vcov,Journal&journal); +void writeMat4(FILE*fd,const char*lname)const; +protected: +void calcMean(); +void calcVcov(); +}; + +/*:27*/ +#line 54 "./decision_rule.hweb" +; +/*28:*/ +#line 743 "./decision_rule.hweb" + +class SimResultsDynamicStats:public SimResults{ +protected: +TwoDMatrix mean; +TwoDMatrix variance; +public: +SimResultsDynamicStats(int ny,int nper) +:SimResults(ny,nper),mean(ny,nper),variance(ny,nper){} +void simulate(int num_sim,const DecisionRule&dr,const Vector&start, +const TwoDMatrix&vcov,Journal&journal); +void writeMat4(FILE*fd,const char*lname)const; +protected: +void calcMean(); +void calcVariance(); +}; + + +/*:28*/ +#line 55 "./decision_rule.hweb" +; +/*29:*/ +#line 767 "./decision_rule.hweb" + +class SimulationIRFWorker; +class SimResultsIRF:public SimResults{ +friend class SimulationIRFWorker; +protected: +const SimResults&control; +int ishock; +double imp; +TwoDMatrix means; +TwoDMatrix variances; +public: +SimResultsIRF(const SimResults&cntl,int ny,int nper,int i,double impulse) +:SimResults(ny,nper),control(cntl), +ishock(i),imp(impulse), +means(ny,nper),variances(ny,nper){} +void simulate(const DecisionRule&dr,const Vector&start, +Journal&journal); +void simulate(const DecisionRule&dr,const Vector&start); +void writeMat4(FILE*fd,const char*lname)const; +protected: +void calcMeans(); +void calcVariances(); +}; + +/*:29*/ +#line 56 "./decision_rule.hweb" +; +/*30:*/ +#line 797 "./decision_rule.hweb" + +class RTSimulationWorker; +class RTSimResultsStats{ +friend class RTSimulationWorker; +protected: +Vector mean; +TwoDMatrix vcov; +int num_per; +NormalConj nc; +int incomplete_simulations; +int thrown_periods; +public: +RTSimResultsStats(int ny,int nper) +:mean(ny),vcov(ny,ny), +num_per(nper),nc(ny), +incomplete_simulations(0),thrown_periods(0){} +void simulate(int num_sim,const DecisionRule&dr,const Vector&start, +const TwoDMatrix&vcov,Journal&journal); +void simulate(int num_sim,const DecisionRule&dr,const Vector&start, +const TwoDMatrix&vcov); +void writeMat4(FILE*fd,const char*lname); +}; + +/*:30*/ +#line 57 "./decision_rule.hweb" +; +/*31:*/ +#line 834 "./decision_rule.hweb" + +class DynamicModel; +class IRFResults{ +vector irf_res; +const DynamicModel&model; +vector irf_list_ind; +public: +IRFResults(const DynamicModel&mod,const DecisionRule&dr, +const SimResults&control,const vector &ili, +Journal&journal); +~IRFResults(); +void writeMat4(FILE*fd,const char*prefix)const; +}; + +/*:31*/ +#line 58 "./decision_rule.hweb" +; +/*32:*/ +#line 851 "./decision_rule.hweb" + +class SimulationWorker:public THREAD{ +protected: +SimResults&res; +const DecisionRule&dr; +DecisionRule::emethod em; +int np; +const Vector&st; +ShockRealization&sr; +public: +SimulationWorker(SimResults&sim_res, +const DecisionRule&dec_rule, +DecisionRule::emethod emet,int num_per, +const Vector&start,ShockRealization&shock_r) +:res(sim_res),dr(dec_rule),em(emet),np(num_per),st(start),sr(shock_r){} +void operator()(); +}; + +/*:32*/ +#line 59 "./decision_rule.hweb" +; +/*33:*/ +#line 874 "./decision_rule.hweb" + +class SimulationIRFWorker:public THREAD{ +SimResultsIRF&res; +const DecisionRule&dr; +DecisionRule::emethod em; +int np; +const Vector&st; +int idata; +int ishock; +double imp; +public: +SimulationIRFWorker(SimResultsIRF&sim_res, +const DecisionRule&dec_rule, +DecisionRule::emethod emet,int num_per, +const Vector&start,int id, +int ishck,double impulse) +:res(sim_res),dr(dec_rule),em(emet),np(num_per),st(start), +idata(id),ishock(ishck),imp(impulse){} +void operator()(); +}; + +/*:33*/ +#line 60 "./decision_rule.hweb" +; +/*34:*/ +#line 901 "./decision_rule.hweb" + +class RTSimulationWorker:public THREAD{ +protected: +RTSimResultsStats&res; +const DecisionRule&dr; +DecisionRule::emethod em; +int np; +const Vector&ystart; +ShockRealization&sr; +public: +RTSimulationWorker(RTSimResultsStats&sim_res, +const DecisionRule&dec_rule, +DecisionRule::emethod emet,int num_per, +const Vector&start,ShockRealization&shock_r) +:res(sim_res),dr(dec_rule),em(emet),np(num_per),ystart(start),sr(shock_r){} +void operator()(); +}; + +/*:34*/ +#line 61 "./decision_rule.hweb" +; +/*35:*/ +#line 923 "./decision_rule.hweb" + +class RandomShockRealization:virtual public ShockRealization{ +protected: +MersenneTwister mtwister; +TwoDMatrix factor; +public: +RandomShockRealization(const TwoDMatrix&v,unsigned int iseed) +:mtwister(iseed),factor(v.nrows(),v.nrows()) +{schurFactor(v);} +RandomShockRealization(const RandomShockRealization&sr) +:mtwister(sr.mtwister),factor(sr.factor){} +virtual~RandomShockRealization(){} +void get(int n,Vector&out); +int numShocks()const +{return factor.nrows();} +protected: +void choleskyFactor(const TwoDMatrix&v); +void schurFactor(const TwoDMatrix&v); +}; + +/*:35*/ +#line 62 "./decision_rule.hweb" +; +/*36:*/ +#line 946 "./decision_rule.hweb" + +class ExplicitShockRealization:virtual public ShockRealization{ +TwoDMatrix shocks; +public: +ExplicitShockRealization(const TwoDMatrix&sh) +:shocks(sh){} +ExplicitShockRealization(const ExplicitShockRealization&sr) +:shocks(sr.shocks){} +ExplicitShockRealization(ShockRealization&sr,int num_per); +void get(int n,Vector&out); +int numShocks()const +{return shocks.nrows();} +void addToShock(int ishock,int iper,double val); +void print()const +{shocks.print();} +}; + +/*:36*/ +#line 63 "./decision_rule.hweb" +; +/*37:*/ +#line 972 "./decision_rule.hweb" + +class GenShockRealization:public RandomShockRealization,public ExplicitShockRealization{ +public: +GenShockRealization(const TwoDMatrix&v,const TwoDMatrix&sh,int seed) +:RandomShockRealization(v,seed),ExplicitShockRealization(sh) +{ +KORD_RAISE_IF(sh.nrows()!=v.nrows()||v.nrows()!=v.ncols(), +"Wrong dimension of input matrix in GenShockRealization constructor"); +} +void get(int n,Vector&out); +int numShocks()const +{return RandomShockRealization::numShocks();} +}; + +/*:37*/ +#line 64 "./decision_rule.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/dynamic_model.cpp b/mex/sources/korderpert/Dyn_pp/kord/dynamic_model.cpp new file mode 100644 index 000000000..a5e42c59c --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/dynamic_model.cpp @@ -0,0 +1,65 @@ +/*1:*/ +#line 6 "./dynamic_model.cweb" + +#include "dynamic_model.h" + +/*2:*/ +#line 14 "./dynamic_model.cweb" + +void NameList::print()const +{ +for(int i= 0;i &getModelDerivatives()const= 0; +virtual const Vector&getSteady()const= 0; +virtual Vector&getSteady()= 0; + +virtual void solveDeterministicSteady()= 0; +virtual void evaluateSystem(Vector&out,const Vector&yy,const Vector&xx)= 0; +virtual void evaluateSystem(Vector&out,const Vector&yym,const Vector&yy, +const Vector&yyp,const Vector&xx)= 0; +virtual void calcDerivativesAtSteady()= 0; +}; + + +/*:3*/ +#line 23 "./dynamic_model.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/faa_di_bruno.cpp b/mex/sources/korderpert/Dyn_pp/kord/faa_di_bruno.cpp new file mode 100644 index 000000000..8c1a51337 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/faa_di_bruno.cpp @@ -0,0 +1,130 @@ +/*1:*/ +#line 9 "./faa_di_bruno.cweb" + +#include "faa_di_bruno.h" +#include "fine_container.h" + +#include + +double FaaDiBruno::magic_mult= 1.5; +/*2:*/ +#line 25 "./faa_di_bruno.cweb" + +void FaaDiBruno::calculate(const StackContainer &cont, +const TensorContainer &f, +FGSTensor&out) +{ +out.zeros(); +for(int l= 1;l<=out.dimen();l++){ +int mem_mb,p_size_mb; +int max= estimRefinment(out.getDims(),out.nrows(),l,mem_mb,p_size_mb); +FoldedFineContainer fine_cont(cont,max); +fine_cont.multAndAdd(l,f,out); +JournalRecord recc(journal); +recc<<"dim="<"< &cont, +const TensorContainer &f, +UGSTensor&out) +{ +out.zeros(); +for(int l= 1;l<=out.dimen();l++){ +int mem_mb,p_size_mb; +int max= estimRefinment(out.getDims(),out.nrows(),l,mem_mb,p_size_mb); +UnfoldedFineContainer fine_cont(cont,max); +fine_cont.multAndAdd(l,f,out); +JournalRecord recc(journal); +recc<<"dim="<"< 0){ +double maxd= pow(num_cols,((double)1)/l); +max= (int)floor(maxd); +} +if(max==0){ +max= 10; +JournalRecord rec(journal); +rec<<"dim="< &cont,const TensorContainer &f, +FGSTensor&out); +void calculate(const FoldedStackContainer&cont,const FGSContainer&g, +FGSTensor&out); +void calculate(const StackContainer &cont,const TensorContainer &f, +UGSTensor&out); +void calculate(const UnfoldedStackContainer&cont,const UGSContainer&g, +UGSTensor&out); +protected: +int estimRefinment(const TensorDimens&tdims,int nr,int l,int&avmem_mb,int&tmpmem_mb); +static double magic_mult; +}; + +/*:2*/ +#line 23 "./faa_di_bruno.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/first_order.cpp b/mex/sources/korderpert/Dyn_pp/kord/first_order.cpp new file mode 100644 index 000000000..28d8fbb7e --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/first_order.cpp @@ -0,0 +1,233 @@ +/*1:*/ +#line 6 "./first_order.cweb" + + +#include "kord_exception.h" +#include "first_order.h" +#include "cpplapack.h" + +/*2:*/ +#line 20 "./first_order.cweb" + +int order_eigs(const double*alphar,const double*alphai,const double*beta) +{ +return(*alphar**alphar+*alphai**alphai<*beta**beta); +} + + +/*:2*/ +#line 12 "./first_order.cweb" +; +/*3:*/ +#line 40 "./first_order.cweb" + +void FirstOrder::solve(const TwoDMatrix&fd) +{ +JournalRecordPair pa(journal); +pa<<"Recovering first order derivatives "< class FirstOrderDerivs; +class FirstOrder{ +template friend class FirstOrderDerivs; +PartitionY ypart; +int nu; +TwoDMatrix gy; +TwoDMatrix gu; +bool bk_cond; +double b_error; +int sdim; +Vector alphar; +Vector alphai; +Vector beta; +Journal&journal; +public: +FirstOrder(int num_stat,int num_pred,int num_both,int num_forw, +int num_u,const FSSparseTensor&f,Journal&jr) +:ypart(num_stat,num_pred,num_both,num_forw), +nu(num_u), +gy(ypart.ny(),ypart.nys()), +gu(ypart.ny(),nu), +alphar(ypart.ny()+ypart.nboth), +alphai(ypart.ny()+ypart.nboth), +beta(ypart.ny()+ypart.nboth), +journal(jr) +{solve(FFSTensor(f));} +bool isStable()const +{return bk_cond;} +const TwoDMatrix&getGy()const +{return gy;} +const TwoDMatrix&getGu()const +{return gu;} +protected: +void solve(const TwoDMatrix&f); +void journalEigs(); +}; + +/*:2*/ +#line 17 "./first_order.hweb" +; +/*3:*/ +#line 64 "./first_order.hweb" + +template +class FirstOrderDerivs:public ctraits ::Tg{ +public: +FirstOrderDerivs(const FirstOrder&fo) +:ctraits ::Tg(4) +{ +IntSequence nvs(4); +nvs[0]= fo.ypart.nys();nvs[1]= fo.nu;nvs[2]= fo.nu;nvs[3]= 1; +_Ttensor*ten= new _Ttensor(fo.ypart.ny(),TensorDimens(Symmetry(1,0,0,0),nvs)); +ten->zeros();ten->add(1.0,fo.gy); +insert(ten); +ten= new _Ttensor(fo.ypart.ny(),TensorDimens(Symmetry(0,1,0,0),nvs)); +ten->zeros();ten->add(1.0,fo.gu); +insert(ten); +} +}; + + +/*:3*/ +#line 18 "./first_order.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/global_check.cpp b/mex/sources/korderpert/Dyn_pp/kord/global_check.cpp new file mode 100644 index 000000000..5dea2cd49 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/global_check.cpp @@ -0,0 +1,469 @@ +/*1:*/ +#line 6 "./global_check.cweb" + +#include "SymSchurDecomp.h" + +#include "global_check.h" + +#include "smolyak.h" +#include "product.h" +#include "quasi_mcarlo.h" + +#include "cpplapack.h" + +/*2:*/ +#line 31 "./global_check.cweb" + +ResidFunction::ResidFunction(const Approximation&app) +:VectorFunction(app.getModel().nexog(),app.getModel().numeq()),approx(app), +model(app.getModel().clone()), +yplus(NULL),ystar(NULL),u(NULL),hss(NULL) +{ +} + +/*:2*/ +#line 17 "./global_check.cweb" +; +/*3:*/ +#line 40 "./global_check.cweb" + +ResidFunction::ResidFunction(const ResidFunction&rf) +:VectorFunction(rf),approx(rf.approx),model(rf.model->clone()), +yplus(NULL),ystar(NULL),u(NULL),hss(NULL) +{ +if(rf.yplus) +yplus= new Vector(*(rf.yplus)); +if(rf.ystar) +ystar= new Vector(*(rf.ystar)); +if(rf.u) +u= new Vector(*(rf.u)); +if(rf.hss) +hss= new FTensorPolynomial(*(rf.hss)); +} + + +/*:3*/ +#line 18 "./global_check.cweb" +; +/*4:*/ +#line 57 "./global_check.cweb" + +ResidFunction::~ResidFunction() +{ +delete model; +/*5:*/ +#line 65 "./global_check.cweb" + +if(yplus) +delete yplus; +if(ystar) +delete ystar; +if(u) +delete u; +if(hss) +delete hss; + + +/*:5*/ +#line 61 "./global_check.cweb" +; +} + +/*:4*/ +#line 19 "./global_check.cweb" +; +/*6:*/ +#line 79 "./global_check.cweb" + +void ResidFunction::setYU(const Vector&ys,const Vector&xx) +{ +/*5:*/ +#line 65 "./global_check.cweb" + +if(yplus) +delete yplus; +if(ystar) +delete ystar; +if(u) +delete u; +if(hss) +delete hss; + + +/*:5*/ +#line 82 "./global_check.cweb" +; + +ystar= new Vector(ys); +u= new Vector(xx); +yplus= new Vector(model->numeq()); +approx.getFoldDecisionRule().evaluate(DecisionRule::horner, +*yplus,*ystar,*u); + +/*7:*/ +#line 103 "./global_check.cweb" + +union{const FoldDecisionRule*c;FoldDecisionRule*n;}dr; +dr.c= &(approx.getFoldDecisionRule()); +FTensorPolynomial dr_ss(model->nstat()+model->npred(),model->nboth()+model->nforw(), +*(dr.n)); + +/*:7*/ +#line 90 "./global_check.cweb" +; +/*8:*/ +#line 110 "./global_check.cweb" + +Vector ytmp_star(ConstVector(*yplus,model->nstat(),model->npred()+model->nboth())); +ConstVector ysteady_star(dr.c->getSteady(),model->nstat(), +model->npred()+model->nboth()); +ytmp_star.add(-1.0,ysteady_star); + +/*:8*/ +#line 91 "./global_check.cweb" +; +/*9:*/ +#line 117 "./global_check.cweb" + +hss= new FTensorPolynomial(dr_ss,ytmp_star); +ConstVector ysteady_ss(dr.c->getSteady(),model->nstat()+model->npred(), +model->nboth()+model->nforw()); +if(hss->check(Symmetry(0))){ +hss->get(Symmetry(0))->getData().add(1.0,ysteady_ss); +}else{ +FFSTensor*ten= new FFSTensor(hss->nrows(),hss->nvars(),0); +ten->getData()= ysteady_ss; +hss->insert(ten); +} + +/*:9*/ +#line 92 "./global_check.cweb" +; +} + +/*:6*/ +#line 20 "./global_check.cweb" +; +/*10:*/ +#line 132 "./global_check.cweb" + +void ResidFunction::eval(const Vector&point,const ParameterSignal&sig,Vector&out) +{ +KORD_RAISE_IF(point.length()!=hss->nvars(), +"Wrong dimension of input vector in ResidFunction::eval"); +KORD_RAISE_IF(out.length()!=model->numeq(), +"Wrong dimension of output vector in ResidFunction::eval"); +Vector yss(hss->nrows()); +hss->evalHorner(yss,point); +model->evaluateSystem(out,*ystar,*yplus,yss,*u); +} + +/*:10*/ +#line 21 "./global_check.cweb" +; +/*11:*/ +#line 148 "./global_check.cweb" + +void GlobalChecker::check(const Quadrature&quad,int level, +const ConstVector&ys,const ConstVector&x,Vector&out) +{ +for(int ifunc= 0;ifunc=prod_level-1); + +/*:13*/ +#line 173 "./global_check.cweb" +; +Quadrature*quad; +int lev; +/*14:*/ +#line 198 "./global_check.cweb" + +if(take_smolyak){ +quad= new SmolyakQuadrature(model.nexog(),smol_level,gh); +lev= smol_level; +JournalRecord rec(journal); +rec<<"Selected Smolyak (level,evals)=("<writeMat4(fd,tmp); +sprintf(tmp,"%s_simul_errors",prefix); +out.writeMat4(fd,tmp); + +delete y; +} + + +/*:25*/ +#line 26 "./global_check.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/global_check.h b/mex/sources/korderpert/Dyn_pp/kord/global_check.h new file mode 100644 index 000000000..338a48016 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/global_check.h @@ -0,0 +1,104 @@ +/*1:*/ +#line 49 "./global_check.hweb" + +#ifndef GLOBAL_CHECK_H +#define GLOBAL_CHECK_H + +#include "vector_function.h" +#include "quadrature.h" + +#include "dynamic_model.h" +#include "journal.h" +#include "approximation.h" + +/*2:*/ +#line 85 "./global_check.hweb" + +class ResidFunction:public VectorFunction{ +protected: +const Approximation≈ +DynamicModel*model; +Vector*yplus; +Vector*ystar; +Vector*u; +FTensorPolynomial*hss; +public: +ResidFunction(const Approximation&app); +ResidFunction(const ResidFunction&rf); +virtual~ResidFunction(); +virtual VectorFunction*clone()const +{return new ResidFunction(*this);} +virtual void eval(const Vector&point,const ParameterSignal&sig,Vector&out); +void setYU(const Vector&ys,const Vector&xx); +}; + +/*:2*/ +#line 60 "./global_check.hweb" +; +/*3:*/ +#line 106 "./global_check.hweb" + +class GResidFunction:public GaussConverterFunction{ +public: +GResidFunction(const Approximation&app) +:GaussConverterFunction(new ResidFunction(app),app.getModel().getVcov()){} +GResidFunction(const GResidFunction&rf) +:GaussConverterFunction(rf){} +virtual~GResidFunction(){} +virtual VectorFunction*clone()const +{return new GResidFunction(*this);} +void setYU(const Vector&ys,const Vector&xx) +{((ResidFunction*)func)->setYU(ys,xx);} +}; + + +/*:3*/ +#line 61 "./global_check.hweb" +; +/*4:*/ +#line 133 "./global_check.hweb" + +class GlobalChecker{ +const Approximation≈ +const DynamicModel&model; +Journal&journal; +GResidFunction rf; +VectorFunctionSet vfs; +public: +GlobalChecker(const Approximation&app,int n,Journal&jr) +:approx(app),model(approx.getModel()),journal(jr), +rf(approx),vfs(rf,n){} +void check(int max_evals,const ConstTwoDMatrix&y, +const ConstTwoDMatrix&x,TwoDMatrix&out); +void checkAlongShocksAndSave(FILE*fd,const char*prefix, +int m,double mult,int max_evals); +void checkOnEllipseAndSave(FILE*fd,const char*prefix, +int m,double mult,int max_evals); +void checkAlongSimulationAndSave(FILE*fd,const char*prefix, +int m,int max_evals); +void checkUnconditionalAndSave(FILE*fd,const char*prefix, +int m,int max_evals); +protected: +void check(const Quadrature&quad,int level, +const ConstVector&y,const ConstVector&x,Vector&out); +}; + + +/*:4*/ +#line 62 "./global_check.hweb" +; +/*5:*/ +#line 161 "./global_check.hweb" + +class ResidFunctionSig:public ResidFunction{ +public: +ResidFunctionSig(const Approximation&app,const Vector&ys,const Vector&xx); +}; + +/*:5*/ +#line 63 "./global_check.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/journal.cpp b/mex/sources/korderpert/Dyn_pp/kord/journal.cpp new file mode 100644 index 000000000..df7f5013e --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/journal.cpp @@ -0,0 +1,360 @@ +#define _W32_FT_OFFSET (116444736000000000LL) +/*1:*/ +#line 6 "./journal.cweb" + +#include "journal.h" +#include "kord_exception.h" + +#ifndef __MINGW32__ +# include +# include +#endif +#include +#include +#include + +SystemResources _sysres; +#ifdef __MINGW32__ +/*16:*/ +#line 249 "./journal.cweb" + +typedef struct _filetime{ +unsigned long dwLowDateTime; +unsigned long dwHighDateTime; +}filetime; + +extern"C"{ +void __stdcall GetSystemTimeAsFileTime(filetime*); +}; + +typedef union{ +long long ns100; +filetime ft; +}w32_ftv; + +void D_gettimeofday(struct timeval*p,struct timezone*tz) +{ +w32_ftv _now; +GetSystemTimeAsFileTime(&(_now.ft)); +p->tv_usec= (long)((_now.ns100/10LL)%1000000LL); +p->tv_sec= (long)((_now.ns100-_W32_FT_OFFSET)/10000000LL); +return; +} + +/*:16*/ +#line 20 "./journal.cweb" +; +/*17:*/ +#line 282 "./journal.cweb" + +#define _SC_PAGESIZE 1 +#define _SC_PHYS_PAGES 2 +#define _SC_AVPHYS_PAGES 3 +#define _SC_NPROCESSORS_ONLN 4 + +struct Win32MemoryStatus{ +unsigned long dwLength; +unsigned long dwMemoryLoad; +unsigned int dwTotalPhys; +unsigned int dwAvailPhys; +unsigned int dwTotalPageFile; +unsigned int dwAvailPageFile; +unsigned int dwTotalVirtual; +unsigned int dwAvailVirtual; +Win32MemoryStatus(); +}; + +extern"C"{ +void __stdcall GlobalMemoryStatus(Win32MemoryStatus*); +}; + +Win32MemoryStatus::Win32MemoryStatus() +{ +dwLength= sizeof(Win32MemoryStatus); +GlobalMemoryStatus(this); +} + +long sysconf(int name) +{ +switch(name){ +case _SC_PAGESIZE: +return 1024; +case _SC_PHYS_PAGES: +{ +Win32MemoryStatus memstat; +return memstat.dwTotalPhys/1024; +} +case _SC_AVPHYS_PAGES: +{ +Win32MemoryStatus memstat; +return memstat.dwAvailPhys/1024; +} +case _SC_NPROCESSORS_ONLN: +return-1; +default: +KORD_RAISE("Not implemented in Win32 sysconf."); +return-1; +} +} + +/*:17*/ +#line 21 "./journal.cweb" +; +#endif + +/*2:*/ +#line 40 "./journal.cweb" + +SystemResources::SystemResources() +{ +D_gettimeofday(&start,NULL); +} + + +/*:2*/ +#line 24 "./journal.cweb" +; +/*3:*/ +#line 48 "./journal.cweb" + +long int SystemResources::pageSize() +{ +return sysconf(_SC_PAGESIZE); +} + +/*:3*/ +#line 25 "./journal.cweb" +; +/*4:*/ +#line 55 "./journal.cweb" + +long int SystemResources::physicalPages() +{ +return sysconf(_SC_PHYS_PAGES); +} + +/*:4*/ +#line 26 "./journal.cweb" +; +/*5:*/ +#line 62 "./journal.cweb" + +long int SystemResources::onlineProcessors() +{ +return sysconf(_SC_NPROCESSORS_ONLN); +} + +/*:5*/ +#line 27 "./journal.cweb" +; +/*6:*/ +#line 69 "./journal.cweb" + +long int SystemResources::availableMemory() +{ +return pageSize()*sysconf(_SC_AVPHYS_PAGES); +} + +/*:6*/ +#line 28 "./journal.cweb" +; +/*7:*/ +#line 78 "./journal.cweb" + +void SystemResources::getRUS(double&load_avg,long int&pg_avail, +double&utime,double&stime,double&elapsed, +long int&idrss,long int&majflt) +{ +struct timeval now; +D_gettimeofday(&now,NULL); +elapsed= now.tv_sec-start.tv_sec+(now.tv_usec-start.tv_usec)*1.0e-6; + +#ifndef __MINGW32__ +struct rusage rus; +getrusage(RUSAGE_SELF,&rus); +utime= rus.ru_utime.tv_sec+rus.ru_utime.tv_usec*1.0e-6; +stime= rus.ru_stime.tv_sec+rus.ru_stime.tv_usec*1.0e-6; +idrss= rus.ru_idrss; +majflt= rus.ru_majflt; + +getloadavg(&load_avg,1); +#else +utime= -1.0; +stime= -1.0; +idrss= -1; +majflt= -1; +load_avg= -1.0; +#endif +pg_avail= sysconf(_SC_AVPHYS_PAGES); +} + +/*:7*/ +#line 29 "./journal.cweb" +; +/*8:*/ +#line 107 "./journal.cweb" + +SystemResourcesFlash::SystemResourcesFlash() +{ +_sysres.getRUS(load_avg,pg_avail,utime,stime, +elapsed,idrss,majflt); +} + +/*:8*/ +#line 30 "./journal.cweb" +; +/*9:*/ +#line 115 "./journal.cweb" + +void SystemResourcesFlash::diff(const SystemResourcesFlash&pre) +{ +utime-= pre.utime; +stime-= pre.stime; +elapsed-= pre.elapsed; +idrss-= pre.idrss; +majflt-= pre.majflt; +} + +/*:9*/ +#line 31 "./journal.cweb" +; +/*10:*/ +#line 126 "./journal.cweb" + +JournalRecord&JournalRecord::operator<<(const IntSequence&s) +{ +operator<<("["); +for(int i= 0;i +#include +#include +#include + +/*2:*/ +#line 34 "./journal.hweb" + +class SystemResources{ +timeval start; +public: +SystemResources(); +static long int pageSize(); +static long int physicalPages(); +static long int onlineProcessors(); +static long int availableMemory(); +void getRUS(double&load_avg,long int&pg_avail,double&utime, +double&stime,double&elapsed,long int&idrss, +long int&majflt); +}; + +/*:2*/ +#line 25 "./journal.hweb" +; +/*3:*/ +#line 49 "./journal.hweb" + +struct SystemResourcesFlash{ +double load_avg; +long int pg_avail; +double utime; +double stime; +double elapsed; +long int idrss; +long int majflt; +SystemResourcesFlash(); +void diff(const SystemResourcesFlash&pre); +}; + + +/*:3*/ +#line 26 "./journal.hweb" +; +/*6:*/ +#line 113 "./journal.hweb" + +class Journal:public ofstream{ +int ord; +int depth; +public: +Journal(const char*fname) +:ofstream(fname),ord(0),depth(0) +{printHeader();} +~Journal() +{flush();} +void printHeader(); +void incrementOrd() +{ord++;} +int getOrd()const +{return ord;} +void incrementDepth() +{depth++;} +void decrementDepth() +{depth--;} +int getDepth()const +{return depth;} +}; + + +/*:6*/ +#line 27 "./journal.hweb" +; +/*4:*/ +#line 67 "./journal.hweb" + +class JournalRecord; +JournalRecord&endrec(JournalRecord&); + +class JournalRecord{ +protected: +char recChar; +int ord; +public: +Journal&journal; +char prefix[MAXLEN]; +char mes[MAXLEN]; +SystemResourcesFlash flash; +typedef JournalRecord&(*_Tfunc)(JournalRecord&); + +JournalRecord(Journal&jr,char rc= 'M') +:recChar(rc),ord(jr.getOrd()),journal(jr) +{prefix[0]= '\0';mes[0]= '\0';writePrefix(flash);} +virtual~JournalRecord(){} +JournalRecord&operator<<(const IntSequence&s); +JournalRecord&operator<<(_Tfunc f) +{(*f)(*this);return*this;} +JournalRecord&operator<<(const char*s) +{strcat(mes,s);return*this;} +JournalRecord&operator<<(int i) +{sprintf(mes+strlen(mes),"%d",i);return*this;} +JournalRecord&operator<<(double d) +{sprintf(mes+strlen(mes),"%f",d);return*this;} +protected: +void writePrefix(const SystemResourcesFlash&f); +}; + +/*:4*/ +#line 28 "./journal.hweb" +; +/*5:*/ +#line 100 "./journal.hweb" + +class JournalRecordPair:public JournalRecord{ +char prefix_end[MAXLEN]; +public: +JournalRecordPair(Journal&jr) +:JournalRecord(jr,'S') +{prefix_end[0]= '\0';journal.incrementDepth();} +~JournalRecordPair(); +private: +void writePrefixForEnd(const SystemResourcesFlash&f); +}; + +/*:5*/ +#line 29 "./journal.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/kord_exception.h b/mex/sources/korderpert/Dyn_pp/kord/kord_exception.h new file mode 100644 index 000000000..2c7fbb481 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/kord_exception.h @@ -0,0 +1,64 @@ +/*1:*/ +#line 9 "./kord_exception.hweb" + +#ifndef KORD_EXCEPTION_H +#define KORD_EXCEPTION_H + +#include +#include + +#define KORD_RAISE(mes) \ +throw KordException(__FILE__, __LINE__, mes); + +#define KORD_RAISE_IF(expr, mes) \ +if (expr) throw KordException(__FILE__, __LINE__, mes); + +#define KORD_RAISE_X(mes, c) \ +throw KordException(__FILE__, __LINE__, mes, c); + +#define KORD_RAISE_IF_X(expr, mes, c) \ +if (expr) throw KordException(__FILE__, __LINE__, mes, c); + +/*2:*/ +#line 34 "./kord_exception.hweb" + +class KordException{ +protected: +char fname[50]; +int lnum; +char message[500]; +int cd; +public: +KordException(const char*f,int l,const char*mes,int c= 255) +{ +strncpy(fname,f,50);fname[49]= '\0'; +strncpy(message,mes,500);message[499]= '\0'; +lnum= l; +cd= c; +} +virtual~KordException(){} +virtual void print()const +{printf("At %s:%d:(%d):%s\n",fname,lnum,cd,message);} +virtual int code()const +{return cd;} +const char*get_message()const +{return message;} +}; + +/*:2*/ +#line 28 "./kord_exception.hweb" +; +/*3:*/ +#line 59 "./kord_exception.hweb" + +#define KORD_FP_NOT_CONV 254 +#define KORD_FP_NOT_FINITE 253 +#define KORD_MD_NOT_STABLE 252 + +/*:3*/ +#line 29 "./kord_exception.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/korder.cpp b/mex/sources/korderpert/Dyn_pp/kord/korder.cpp new file mode 100644 index 000000000..453fdc134 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/korder.cpp @@ -0,0 +1,326 @@ +/*1:*/ +#line 6 "./korder.cweb" + + +#include "kord_exception.h" +#include "korder.h" + +#include "cpplapack.h" + +/*2:*/ +#line 25 "./korder.cweb" + +PLUMatrix::PLUMatrix(const PLUMatrix&plu) +:TwoDMatrix(plu),inv(plu.inv),ipiv(new int[nrows()]) +{ +memcpy(ipiv,plu.ipiv,nrows()*sizeof(int)); +} + + +/*:2*/ +#line 13 "./korder.cweb" +; +/*3:*/ +#line 37 "./korder.cweb" + +void PLUMatrix::calcPLU() +{ +int info; +int rows= nrows(); +inv= (const Vector&)getData(); +LAPACK_dgetrf(&rows,&rows,inv.base(),&rows,ipiv,&info); +} + +/*:3*/ +#line 14 "./korder.cweb" +; +/*4:*/ +#line 48 "./korder.cweb" + +void PLUMatrix::multInv(TwoDMatrix&m)const +{ +KORD_RAISE_IF(m.nrows()!=ncols(), +"The matrix is not square in PLUMatrix::multInv"); +int info; +int mcols= m.ncols(); +int mrows= m.nrows(); +double*mbase= m.getData().base(); +LAPACK_dgetrs("N",&mrows,&mcols,inv.base(),&mrows,ipiv, +mbase,&mrows,&info); +KORD_RAISE_IF(info!=0, +"Info!=0 in PLUMatrix::multInv"); +} + +/*:4*/ +#line 15 "./korder.cweb" +; +/*5:*/ +#line 69 "./korder.cweb" + +MatrixA::MatrixA(const FSSparseTensor&f,const IntSequence&ss, +const TwoDMatrix&gy,const PartitionY&ypart) +:PLUMatrix(ypart.ny()) +{ +zeros(); + +IntSequence c(1);c[0]= 1; +FGSTensor f_y(f,ss,c,TensorDimens(ss,c)); +add(1.0,f_y); + +ConstTwoDMatrix gss_ys(ypart.nstat+ypart.npred,ypart.nyss(),gy); +c[0]= 0; +FGSTensor f_yss(f,ss,c,TensorDimens(ss,c)); +TwoDMatrix sub(*this,ypart.nstat,ypart.nys()); +sub.multAndAdd(ConstTwoDMatrix(f_yss),gss_ys); + +calcPLU(); +} + +/*:5*/ +#line 16 "./korder.cweb" +; +/*6:*/ +#line 97 "./korder.cweb" + +MatrixS::MatrixS(const FSSparseTensor&f,const IntSequence&ss, +const TwoDMatrix&gy,const PartitionY&ypart) +:PLUMatrix(ypart.ny()) +{ +zeros(); + +IntSequence c(1);c[0]= 1; +FGSTensor f_y(f,ss,c,TensorDimens(ss,c)); +add(1.0,f_y); + +ConstTwoDMatrix gss_ys(ypart.nstat+ypart.npred,ypart.nyss(),gy); +c[0]= 0; +FGSTensor f_yss(f,ss,c,TensorDimens(ss,c)); +TwoDMatrix sub(*this,ypart.nstat,ypart.nys()); +sub.multAndAdd(ConstTwoDMatrix(f_yss),gss_ys); + +TwoDMatrix sub2(*this,ypart.nstat+ypart.npred,ypart.nyss()); +sub2.add(1.0,f_yss); + +calcPLU(); +} + + +/*:6*/ +#line 17 "./korder.cweb" +; +/*13:*/ +#line 281 "./korder.cweb" + +template<> ctraits ::Tg&KOrder::g () +{return _ug;} +template<> const ctraits ::Tg&KOrder::g ()const +{return _ug;} +template<> ctraits ::Tg&KOrder::g () +{return _fg;} +template<> const ctraits ::Tg&KOrder::g ()const +{return _fg;} +template<> ctraits ::Tgs&KOrder::gs () +{return _ugs;} +template<> const ctraits ::Tgs&KOrder::gs ()const +{return _ugs;} +template<> ctraits ::Tgs&KOrder::gs () +{return _fgs;} +template<> const ctraits ::Tgs&KOrder::gs ()const +{return _fgs;} +template<> ctraits ::Tgss&KOrder::gss () +{return _ugss;} +template<> const ctraits ::Tgss&KOrder::gss ()const +{return _ugss;} +template<> ctraits ::Tgss&KOrder::gss () +{return _fgss;} +template<> const ctraits ::Tgss&KOrder::gss ()const +{return _fgss;} +template<> ctraits ::TG&KOrder::G () +{return _uG;} +template<> const ctraits ::TG&KOrder::G ()const +{return _uG;} +template<> ctraits ::TG&KOrder::G () +{return _fG;} +template<> const ctraits ::TG&KOrder::G ()const +{return _fG;} +template<> ctraits ::TZstack&KOrder::Zstack () +{return _uZstack;} +template<> const ctraits ::TZstack&KOrder::Zstack ()const +{return _uZstack;} +template<> ctraits ::TZstack&KOrder::Zstack () +{return _fZstack;} +template<> const ctraits ::TZstack&KOrder::Zstack ()const +{return _fZstack;} +template<> ctraits ::TGstack&KOrder::Gstack () +{return _uGstack;} +template<> const ctraits ::TGstack&KOrder::Gstack ()const +{return _uGstack;} +template<> ctraits ::TGstack&KOrder::Gstack () +{return _fGstack;} +template<> const ctraits ::TGstack&KOrder::Gstack ()const +{return _fGstack;} +template<> ctraits ::Tm&KOrder::m () +{return _um;} +template<> const ctraits ::Tm&KOrder::m ()const +{return _um;} +template<> ctraits ::Tm&KOrder::m () +{return _fm;} +template<> const ctraits ::Tm&KOrder::m ()const +{return _fm;} + + +/*:13*/ +#line 18 "./korder.cweb" +; +/*10:*/ +#line 211 "./korder.cweb" + +template<> +void KOrder::sylvesterSolve (ctraits ::Ttensor&der)const +{ +JournalRecordPair pa(journal); +pa<<"Sylvester equation for dimension = "< 0&&ypart.nyss()> 0){ +KORD_RAISE_IF(!der.isFinite(), +"RHS of Sylverster is not finite"); +TwoDMatrix gs_y(*(gs ().get(Symmetry(1,0,0,0)))); +GeneralSylvester sylv(der.getSym()[0],ny,ypart.nys(), +ypart.nstat+ypart.npred, +matA.getData().base(),matB.getData().base(), +gs_y.getData().base(),der.getData().base()); +sylv.solve(); +}else if(ypart.nys()> 0&&ypart.nyss()==0){ +matA.multInv(der); +} +} + +/*:10*/ +#line 19 "./korder.cweb" +; +/*11:*/ +#line 235 "./korder.cweb" + +template<> +void KOrder::sylvesterSolve (ctraits ::Ttensor&der)const +{ +ctraits ::Ttensor tmp(der); +sylvesterSolve (tmp); +ctraits ::Ttensor ftmp(tmp); +der.getData()= (const Vector&)(ftmp.getData()); +} + +/*:11*/ +#line 20 "./korder.cweb" +; +/*12:*/ +#line 246 "./korder.cweb" + +void KOrder::switchToFolded() +{ +JournalRecordPair pa(journal); +pa<<"Switching from unfolded to folded"< ().getMaxDim(); +for(int dim= 1;dim<=maxdim;dim++){ +SymmetrySet ss(dim,4); +for(symiterator si(ss);!si.isEnd();++si){ +if((*si)[2]==0&&g ().check(*si)){ +FGSTensor*ft= new FGSTensor(*(g ().get(*si))); +insertDerivative (ft); +if(dim> 1){ +gss ().remove(*si); +gs ().remove(*si); +g ().remove(*si); +} +} +if(G ().check(*si)){ +FGSTensor*ft= new FGSTensor(*(G ().get(*si))); +G ().insert(ft); +if(dim> 1){ +G ().remove(*si); +} +} +} +} +} + + + +/*:12*/ +#line 21 "./korder.cweb" +; +/*7:*/ +#line 133 "./korder.cweb" + +KOrder::KOrder(int num_stat,int num_pred,int num_both,int num_forw, +const TensorContainer &fcont, +const TwoDMatrix&gy,const TwoDMatrix&gu,const TwoDMatrix&v, +Journal&jr) +:ypart(num_stat,num_pred,num_both,num_forw), +ny(ypart.ny()),nu(gu.ncols()),maxk(fcont.getMaxDim()), +nvs(4), +_ug(4),_fg(4),_ugs(4),_fgs(4),_ugss(4),_fgss(4), +_uG(4),_fG(4), +_uZstack(&_uG,ypart.nyss(),&_ug,ny,ypart.nys(),nu), +_fZstack(&_fG,ypart.nyss(),&_fg,ny,ypart.nys(),nu), +_uGstack(&_ugs,ypart.nys(),nu), +_fGstack(&_fgs,ypart.nys(),nu), +_um(maxk,v),_fm(_um),f(fcont), +matA(*(f.get(Symmetry(1))),_uZstack.getStackSizes(),gy,ypart), +matS(*(f.get(Symmetry(1))),_uZstack.getStackSizes(),gy,ypart), +matB(*(f.get(Symmetry(1))),_uZstack.getStackSizes()), +journal(jr) +{ +KORD_RAISE_IF(gy.ncols()!=ypart.nys(), +"Wrong number of columns in gy in KOrder constructor"); +KORD_RAISE_IF(v.ncols()!=nu, +"Wrong number of columns of Vcov in KOrder constructor"); +KORD_RAISE_IF(nu!=v.nrows(), +"Wrong number of rows of Vcov in KOrder constructor"); +KORD_RAISE_IF(maxk<2, +"Order of approximation must be at least 2 in KOrder constructor"); +KORD_RAISE_IF(gy.nrows()!=ypart.ny(), +"Wrong number of rows in gy in KOrder constructor"); +KORD_RAISE_IF(gu.nrows()!=ypart.ny(), +"Wrong number of rows in gu in KOrder constuctor"); +KORD_RAISE_IF(gu.ncols()!=nu, +"Wrong number of columns in gu in KOrder constuctor"); + + +nvs[0]= ypart.nys();nvs[1]= nu;nvs[2]= nu;nvs[3]= 1; + +/*8:*/ +#line 178 "./korder.cweb" + +UGSTensor*tgy= new UGSTensor(ny,TensorDimens(Symmetry(1,0,0,0),nvs)); +tgy->getData()= gy.getData(); +insertDerivative (tgy); +UGSTensor*tgu= new UGSTensor(ny,TensorDimens(Symmetry(0,1,0,0),nvs)); +tgu->getData()= gu.getData(); +insertDerivative (tgu); + +/*:8*/ +#line 171 "./korder.cweb" +; +/*9:*/ +#line 187 "./korder.cweb" + +UGSTensor*tGy= faaDiBrunoG (Symmetry(1,0,0,0)); +G ().insert(tGy); +UGSTensor*tGu= faaDiBrunoG (Symmetry(0,1,0,0)); +G ().insert(tGu); +UGSTensor*tGup= faaDiBrunoG (Symmetry(0,0,1,0)); +G ().insert(tGup); + + + +/*:9*/ +#line 172 "./korder.cweb" +; +} + +/*:7*/ +#line 22 "./korder.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/korder.h b/mex/sources/korderpert/Dyn_pp/kord/korder.h new file mode 100644 index 000000000..944ae5ebd --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/korder.h @@ -0,0 +1,736 @@ +#define _Ttensor TYPENAME ctraits ::Ttensor +#define _Ttensym TYPENAME ctraits ::Ttensym +#define _Tg TYPENAME ctraits ::Tg +#define _Tgs TYPENAME ctraits ::Tgs +#define _Tgss TYPENAME ctraits ::Tgss +#define _TG TYPENAME ctraits ::TG +#define _TZstack TYPENAME ctraits ::TZstack +#define _TGstack TYPENAME ctraits ::TGstack +#define _TZXstack TYPENAME ctraits ::TZXstack +#define _TGXstack TYPENAME ctraits ::TGXstack +#define _Tm TYPENAME ctraits ::Tm +#define _Tpol TYPENAME ctraits ::Tpol \ + \ + +/*1:*/ +#line 62 "./korder.hweb" + +#ifndef KORDER_H +#define KORDER_H + +#include "int_sequence.h" +#include "fs_tensor.h" +#include "gs_tensor.h" +#include "t_container.h" +#include "stack_container.h" +#include "normal_moments.h" +#include "t_polynomial.h" +#include "faa_di_bruno.h" +#include "journal.h" + +#include "kord_exception.h" +#include "GeneralSylvester.h" + +#include + +#define TYPENAME typename + +/*2:*/ +#line 106 "./korder.hweb" + +class FoldedZXContainer; +class UnfoldedZXContainer; +class FoldedGXContainer; +class UnfoldedGXContainer; + +template +struct IF{ +typedef Then RET; +}; + +template +struct IF { +typedef Else RET; +}; + +template +class ctraits{ +public: +enum{fold,unfold}; +typedef TYPENAME IF ::RET Ttensor; +typedef TYPENAME IF ::RET Ttensym; +typedef TYPENAME IF ::RET Tg; +typedef TYPENAME IF ::RET Tgs; +typedef TYPENAME IF ::RET Tgss; +typedef TYPENAME IF ::RET TG; +typedef TYPENAME IF ::RET TZstack; +typedef TYPENAME IF ::RET TGstack; +typedef TYPENAME IF ::RET Tm; +typedef TYPENAME IF ::RET Tpol; +typedef TYPENAME IF ::RET TZXstack; +typedef TYPENAME IF ::RET TGXstack; +}; + + +/*:2*/ +#line 83 "./korder.hweb" +; +/*3:*/ +#line 156 "./korder.hweb" + +struct PartitionY{ +const int nstat; +const int npred; +const int nboth; +const int nforw; +PartitionY(int num_stat,int num_pred, +int num_both,int num_forw) +:nstat(num_stat),npred(num_pred), +nboth(num_both),nforw(num_forw) +{} +int ny()const +{return nstat+npred+nboth+nforw;} +int nys()const +{return npred+nboth;} +int nyss()const +{return nboth+nforw;} +}; + + +/*:3*/ +#line 84 "./korder.hweb" +; +/*4:*/ +#line 183 "./korder.hweb" + +class PLUMatrix:public TwoDMatrix{ +public: +PLUMatrix(int n) +:TwoDMatrix(n,n), +inv(nrows()*ncols()), +ipiv(new int[nrows()]){} +PLUMatrix(const PLUMatrix&plu); +virtual~PLUMatrix() +{delete[]ipiv;} +void multInv(TwoDMatrix&m)const; +private: +Vector inv; +int*ipiv; +protected: +void calcPLU(); +}; + +/*:4*/ +#line 85 "./korder.hweb" +; +/*5:*/ +#line 205 "./korder.hweb" + +class MatrixA:public PLUMatrix{ +public: +MatrixA(const FSSparseTensor&f,const IntSequence&ss, +const TwoDMatrix&gy,const PartitionY&ypart); +}; + +/*:5*/ +#line 86 "./korder.hweb" +; +/*6:*/ +#line 218 "./korder.hweb" + +class MatrixS:public PLUMatrix{ +public: +MatrixS(const FSSparseTensor&f,const IntSequence&ss, +const TwoDMatrix&gy,const PartitionY&ypart); +}; + + +/*:6*/ +#line 87 "./korder.hweb" +; +/*7:*/ +#line 229 "./korder.hweb" + +class MatrixB:public TwoDMatrix{ +public: +MatrixB(const FSSparseTensor&f,const IntSequence&ss) +:TwoDMatrix(FGSTensor(f,ss,IntSequence(1,0), +TensorDimens(ss,IntSequence(1,0)))) +{} +}; + +/*:7*/ +#line 88 "./korder.hweb" +; +/*8:*/ +#line 325 "./korder.hweb" + +class KOrder{ +protected: +const PartitionY ypart; +const int ny; +const int nu; +const int maxk; +IntSequence nvs; +/*30:*/ +#line 919 "./korder.hweb" + +UGSContainer _ug; +FGSContainer _fg; +UGSContainer _ugs; +FGSContainer _fgs; +UGSContainer _ugss; +FGSContainer _fgss; +UGSContainer _uG; +FGSContainer _fG; +UnfoldedZContainer _uZstack; +FoldedZContainer _fZstack; +UnfoldedGContainer _uGstack; +FoldedGContainer _fGstack; +UNormalMoments _um; +FNormalMoments _fm; +const TensorContainer &f; + +/*:30*/ +#line 333 "./korder.hweb" +; +const MatrixA matA; +const MatrixS matS; +const MatrixB matB; +/*31:*/ +#line 939 "./korder.hweb" + +template _Tg&g(); +template const _Tg&g()const; +template _Tgs&gs(); +template const _Tgs&gs()const; +template _Tgss&gss(); +template const _Tgss&gss()const; +template _TG&G(); +template const _TG&G()const; +template _TZstack&Zstack(); +template const _TZstack&Zstack()const; +template _TGstack&Gstack(); +template const _TGstack&Gstack()const; +template _Tm&m(); +template const _Tm&m()const; + + +/*:31*/ +#line 337 "./korder.hweb" +; +Journal&journal; +public: +KOrder(int num_stat,int num_pred,int num_both,int num_forw, +const TensorContainer &fcont, +const TwoDMatrix&gy,const TwoDMatrix&gu,const TwoDMatrix&v, +Journal&jr); +enum{fold,unfold}; +/*24:*/ +#line 796 "./korder.hweb" + +template +void performStep(int order) +{ +KORD_RAISE_IF(order-1!=g ().getMaxDim(), +"Wrong order for KOrder::performStep"); +JournalRecordPair pa(journal); +pa<<"Performing step for order = "< (order); + +for(int i= 0;i (i,order-i); +} + +for(int j= 1;j=1;i--){ +recover_yus (order-j,i,j-i); +} +recover_ys (order-j,j); +} + +for(int i= order-1;i>=1;i--){ +recover_yus (0,i,order-i); +} +recover_s (order); +} + +/*:24*/ +#line 345 "./korder.hweb" +; +/*25:*/ +#line 828 "./korder.hweb" + +template +double check(int dim)const +{ +KORD_RAISE_IF(dim> g ().getMaxDim(), +"Wrong dimension for KOrder::check"); +JournalRecordPair pa(journal); +pa<<"Checking residuals for order = "< (sym); +double err= r->getData().getMax(); +JournalRecord(journal)<<"\terror for symmetry "< maxerror) +maxerror= err; +delete r; +} + +/*:26*/ +#line 839 "./korder.hweb" +; +/*27:*/ +#line 860 "./korder.hweb" + +SymmetrySet ss(dim,3); +for(symiterator si(ss);!si.isEnd();++si){ +int i= (*si)[0]; +int j= (*si)[1]; +int k= (*si)[2]; +if(i+j> 0&&k> 0){ +Symmetry sym(i,j,0,k); +_Ttensor*r= faaDiBrunoZ (sym); +_Ttensor*D_ijk= calcD_ijk (i,j,k); +r->add(1.0,*D_ijk); +delete D_ijk; +_Ttensor*E_ijk= calcE_ijk (i,j,k); +r->add(1.0,*E_ijk); +delete E_ijk; +double err= r->getData().getMax(); +JournalRecord(journal)<<"\terror for symmetry "< (Symmetry(0,0,0,dim)); +_Ttensor*D_k= calcD_k (dim); +r->add(1.0,*D_k); +delete D_k; +_Ttensor*E_k= calcE_k (dim); +r->add(1.0,*E_k); +delete E_k; +double err= r->getData().getMax(); +Symmetry sym(0,0,0,dim); +JournalRecord(journal)<<"\terror for symmetry "< maxerror) +maxerror= err; +delete r; + +/*:28*/ +#line 841 "./korder.hweb" +; + +return maxerror; +} + + +/*:25*/ +#line 346 "./korder.hweb" +; +/*29:*/ +#line 899 "./korder.hweb" + +template +Vector*calcStochShift(int order,double sigma)const +{ +Vector*res= new Vector(ny); +res->zeros(); +int jfac= 1; +for(int j= 1;j<=order;j++,jfac*= j) +if(is_even(j)){ +_Ttensor*ten= calcD_k (j); +res->add(std::pow(sigma,j)/jfac,ten->getData()); +delete ten; +} +return res; +} + + +/*:29*/ +#line 347 "./korder.hweb" +; +void switchToFolded(); +const PartitionY&getPartY()const +{return ypart;} +const FGSContainer&getFoldDers()const +{return _fg;} +const UGSContainer&getUnfoldDers()const +{return _ug;} +static bool is_even(int i) +{return(i/2)*2==i;} +protected: +/*9:*/ +#line 386 "./korder.hweb" + +template +void insertDerivative(_Ttensor*der) +{ +g ().insert(der); +gs ().insert(new _Ttensor(ypart.nstat,ypart.nys(),*der)); +gss ().insert(new _Ttensor(ypart.nstat+ypart.npred, +ypart.nyss(),*der)); +} + + +/*:9*/ +#line 358 "./korder.hweb" +; +template +void sylvesterSolve(_Ttensor&der)const; + +/*10:*/ +#line 404 "./korder.hweb" + +template +_Ttensor*faaDiBrunoZ(const Symmetry&sym)const +{ +JournalRecordPair pa(journal); +pa<<"Faa Di Bruno Z container for "< (),f,*res); +return res; +} + +/*:10*/ +#line 362 "./korder.hweb" +; +/*11:*/ +#line 419 "./korder.hweb" + +template +_Ttensor*faaDiBrunoG(const Symmetry&sym)const +{ +JournalRecordPair pa(journal); +pa<<"Faa Di Bruno G container for "< (),gss (),*res); +return res; +} + +/*:11*/ +#line 363 "./korder.hweb" +; + +/*12:*/ +#line 444 "./korder.hweb" + +template +void recover_y(int i) +{ +Symmetry sym(i,0,0,0); +JournalRecordPair pa(journal); +pa<<"Recovering symmetry "< (sym); +G ().insert(G_yi); + +_Ttensor*g_yi= faaDiBrunoZ (sym); +g_yi->mult(-1.0); + +sylvesterSolve (*g_yi); + +insertDerivative (g_yi); + +_Ttensor*gss_y= gss ().get(Symmetry(1,0,0,0)); +gs ().multAndAdd(*gss_y,*G_yi); +_Ttensor*gss_yi= gss ().get(sym); +gs ().multAndAdd(*gss_yi,*G_yi); +} + + +/*:12*/ +#line 365 "./korder.hweb" +; +/*13:*/ +#line 480 "./korder.hweb" + +template +void recover_yu(int i,int j) +{ +Symmetry sym(i,j,0,0); +JournalRecordPair pa(journal); +pa<<"Recovering symmetry "< (sym); +G ().insert(G_yiuj); + +_Ttensor*g_yiuj= faaDiBrunoZ (sym); +g_yiuj->mult(-1.0); +matA.multInv(*g_yiuj); +insertDerivative (g_yiuj); + +gs ().multAndAdd(*(gss ().get(Symmetry(1,0,0,0))),*G_yiuj); +} + +/*:13*/ +#line 366 "./korder.hweb" +; +/*14:*/ +#line 519 "./korder.hweb" + +template +void recover_ys(int i,int j) +{ +Symmetry sym(i,0,0,j); +JournalRecordPair pa(journal); +pa<<"Recovering symmetry "< (i,0,j); + +if(is_even(j)){ +_Ttensor*G_yisj= faaDiBrunoG (sym); +G ().insert(G_yisj); + +_Ttensor*g_yisj= faaDiBrunoZ (sym); + +{ +_Ttensor*D_ij= calcD_ik (i,j); +g_yisj->add(1.0,*D_ij); +delete D_ij; +} + +if(j>=3){ +_Ttensor*E_ij= calcE_ik (i,j); +g_yisj->add(1.0,*E_ij); +delete E_ij; +} + +g_yisj->mult(-1.0); + +sylvesterSolve (*g_yisj); + +insertDerivative (g_yisj); + +Gstack ().multAndAdd(1,gss (),*G_yisj); +Gstack ().multAndAdd(i+j,gss (),*G_yisj); +} +} + +/*:14*/ +#line 367 "./korder.hweb" +; +/*15:*/ +#line 577 "./korder.hweb" + +template +void recover_yus(int i,int j,int k) +{ +Symmetry sym(i,j,0,k); +JournalRecordPair pa(journal); +pa<<"Recovering symmetry "< (i,j,k); + +if(is_even(k)){ +_Ttensor*G_yiujsk= faaDiBrunoG (sym); +G ().insert(G_yiujsk); + +_Ttensor*g_yiujsk= faaDiBrunoZ (sym); + +{ +_Ttensor*D_ijk= calcD_ijk (i,j,k); +g_yiujsk->add(1.0,*D_ijk); +delete D_ijk; +} + +if(k>=3){ +_Ttensor*E_ijk= calcE_ijk (i,j,k); +g_yiujsk->add(1.0,*E_ijk); +delete E_ijk; +} + +g_yiujsk->mult(-1.0); + +matA.multInv(*g_yiujsk); +insertDerivative (g_yiujsk); + +Gstack ().multAndAdd(1,gss (),*G_yiujsk); +} +} + +/*:15*/ +#line 368 "./korder.hweb" +; +/*16:*/ +#line 642 "./korder.hweb" + +template +void recover_s(int i) +{ +Symmetry sym(0,0,0,i); +JournalRecordPair pa(journal); +pa<<"Recovering symmetry "< (0,0,i); + +if(is_even(i)){ +_Ttensor*G_si= faaDiBrunoG (sym); +G ().insert(G_si); + +_Ttensor*g_si= faaDiBrunoZ (sym); + +{ +_Ttensor*D_i= calcD_k (i); +g_si->add(1.0,*D_i); +delete D_i; +} + +if(i>=3){ +_Ttensor*E_i= calcE_k (i); +g_si->add(1.0,*E_i); +delete E_i; +} + +g_si->mult(-1.0); + + +matS.multInv(*g_si); +insertDerivative (g_si); + +Gstack ().multAndAdd(1,gss (),*G_si); +Gstack ().multAndAdd(i,gss (),*G_si); +} +} + +/*:16*/ +#line 369 "./korder.hweb" +; +/*17:*/ +#line 685 "./korder.hweb" + +template +void fillG(int i,int j,int k) +{ +for(int m= 1;m<=k;m++){ +if(is_even(k-m)){ +_Ttensor*G_yiujupms= faaDiBrunoG (Symmetry(i,j,m,k-m)); +G ().insert(G_yiujupms); +} +} +} + + +/*:17*/ +#line 370 "./korder.hweb" +; + +/*18:*/ +#line 705 "./korder.hweb" + +template +_Ttensor*calcD_ijk(int i,int j,int k)const +{ +_Ttensor*res= new _Ttensor(ny,TensorDimens(Symmetry(i,j,0,0),nvs)); +res->zeros(); +if(is_even(k)){ +_Ttensor*tmp= faaDiBrunoZ (Symmetry(i,j,k,0)); +tmp->contractAndAdd(2,*res,*(m ().get(Symmetry(k)))); +delete tmp; +} +return res; +} + + +/*:18*/ +#line 372 "./korder.hweb" +; +/*20:*/ +#line 743 "./korder.hweb" + +template +_Ttensor*calcD_ik(int i,int k)const +{ +return calcD_ijk (i,0,k); +} + +/*:20*/ +#line 373 "./korder.hweb" +; +/*21:*/ +#line 751 "./korder.hweb" + +template +_Ttensor*calcD_k(int k)const +{ +return calcD_ijk (0,0,k); +} + +/*:21*/ +#line 374 "./korder.hweb" +; + +/*19:*/ +#line 727 "./korder.hweb" + +template +_Ttensor*calcE_ijk(int i,int j,int k)const +{ +_Ttensor*res= new _Ttensor(ny,TensorDimens(Symmetry(i,j,0,0),nvs)); +res->zeros(); +for(int n= 2;n<=k-1;n+= 2){ +_Ttensor*tmp= faaDiBrunoZ (Symmetry(i,j,n,k-n)); +tmp->mult((double)(Tensor::noverk(k,n))); +tmp->contractAndAdd(2,*res,*(m ().get(Symmetry(n)))); +delete tmp; +} +return res; +} + +/*:19*/ +#line 376 "./korder.hweb" +; +/*22:*/ +#line 759 "./korder.hweb" + +template +_Ttensor*calcE_ik(int i,int k)const +{ +return calcE_ijk (i,0,k); +} + +/*:22*/ +#line 377 "./korder.hweb" +; +/*23:*/ +#line 767 "./korder.hweb" + +template +_Ttensor*calcE_k(int k)const +{ +return calcE_ijk (0,0,k); +} + +/*:23*/ +#line 378 "./korder.hweb" +; +}; + + + +/*:8*/ +#line 89 "./korder.hweb" +; + + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/korder_stoch.cpp b/mex/sources/korderpert/Dyn_pp/kord/korder_stoch.cpp new file mode 100644 index 000000000..e3bf297e0 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/korder_stoch.cpp @@ -0,0 +1,137 @@ +/*1:*/ +#line 5 "./korder_stoch.cweb" + +#include "korder_stoch.h" + +/*2:*/ +#line 14 "./korder_stoch.cweb" + +MatrixAA::MatrixAA(const FSSparseTensor&f,const IntSequence&ss, +const TwoDMatrix&gss_ys,const PartitionY&ypart) +:PLUMatrix(ypart.ny()) +{ +zeros(); + +IntSequence c(1);c[0]= 1; +FGSTensor f_y(f,ss,c,TensorDimens(ss,c)); +add(1.0,f_y); + +c[0]= 0; +FGSTensor f_yss(f,ss,c,TensorDimens(ss,c)); +TwoDMatrix sub(*this,ypart.nstat,ypart.nys()); +sub.multAndAdd(f_yss,gss_ys); + +calcPLU(); +} + + +/*:2*/ +#line 8 "./korder_stoch.cweb" +; +/*3:*/ +#line 35 "./korder_stoch.cweb" + +KOrderStoch::KOrderStoch(const PartitionY&yp,int nu, +const TensorContainer &fcont, +const FGSContainer&hh,Journal&jr) +:nvs(4),ypart(yp),journal(jr), +_ug(4),_fg(4),_ugs(4),_fgs(4),_uG(4),_fG(4), +_uh(NULL),_fh(&hh), +_uZstack(&_uG,ypart.nyss(),&_ug,ypart.ny(),ypart.nys(),nu), +_fZstack(&_fG,ypart.nyss(),&_fg,ypart.ny(),ypart.nys(),nu), +_uGstack(&_ugs,ypart.nys(),nu), +_fGstack(&_fgs,ypart.nys(),nu), +f(fcont), +matA(*(fcont.get(Symmetry(1))),_uZstack.getStackSizes(),*(hh.get(Symmetry(1,0,0,0))), +ypart) +{ +nvs[0]= ypart.nys(); +nvs[1]= nu; +nvs[2]= nu; +nvs[3]= 1; +} + +/*:3*/ +#line 9 "./korder_stoch.cweb" +; +/*4:*/ +#line 57 "./korder_stoch.cweb" + +KOrderStoch::KOrderStoch(const PartitionY&yp,int nu, +const TensorContainer &fcont, +const UGSContainer&hh,Journal&jr) +:nvs(4),ypart(yp),journal(jr), +_ug(4),_fg(4),_ugs(4),_fgs(4),_uG(4),_fG(4), +_uh(&hh),_fh(NULL), +_uZstack(&_uG,ypart.nyss(),&_ug,ypart.ny(),ypart.nys(),nu), +_fZstack(&_fG,ypart.nyss(),&_fg,ypart.ny(),ypart.nys(),nu), +_uGstack(&_ugs,ypart.nys(),nu), +_fGstack(&_fgs,ypart.nys(),nu), +f(fcont), +matA(*(fcont.get(Symmetry(1))),_uZstack.getStackSizes(),*(hh.get(Symmetry(1,0,0,0))), +ypart) +{ +nvs[0]= ypart.nys(); +nvs[1]= nu; +nvs[2]= nu; +nvs[3]= 1; +} + + +/*:4*/ +#line 10 "./korder_stoch.cweb" +; +/*5:*/ +#line 80 "./korder_stoch.cweb" + +template<> ctraits ::Tg&KOrderStoch::g () +{return _ug;} +template<> const ctraits ::Tg&KOrderStoch::g ()const +{return _ug;} +template<> ctraits ::Tg&KOrderStoch::g () +{return _fg;} +template<> const ctraits ::Tg&KOrderStoch::g ()const +{return _fg;} +template<> ctraits ::Tgs&KOrderStoch::gs () +{return _ugs;} +template<> const ctraits ::Tgs&KOrderStoch::gs ()const +{return _ugs;} +template<> ctraits ::Tgs&KOrderStoch::gs () +{return _fgs;} +template<> const ctraits ::Tgs&KOrderStoch::gs ()const +{return _fgs;} +template<> const ctraits ::Tgss&KOrderStoch::h ()const +{return*_uh;} +template<> const ctraits ::Tgss&KOrderStoch::h ()const +{return*_fh;} +template<> ctraits ::TG&KOrderStoch::G () +{return _uG;} +template<> const ctraits ::TG&KOrderStoch::G ()const +{return _uG;} +template<> ctraits ::TG&KOrderStoch::G () +{return _fG;} +template<> const ctraits ::TG&KOrderStoch::G ()const +{return _fG;} +template<> ctraits ::TZXstack&KOrderStoch::Zstack () +{return _uZstack;} +template<> const ctraits ::TZXstack&KOrderStoch::Zstack ()const +{return _uZstack;} +template<> ctraits ::TZXstack&KOrderStoch::Zstack () +{return _fZstack;} +template<> const ctraits ::TZXstack&KOrderStoch::Zstack ()const +{return _fZstack;} +template<> ctraits ::TGXstack&KOrderStoch::Gstack () +{return _uGstack;} +template<> const ctraits ::TGXstack&KOrderStoch::Gstack ()const +{return _uGstack;} +template<> ctraits ::TGXstack&KOrderStoch::Gstack () +{return _fGstack;} +template<> const ctraits ::TGXstack&KOrderStoch::Gstack ()const +{return _fGstack;} + + +/*:5*/ +#line 11 "./korder_stoch.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/korder_stoch.h b/mex/sources/korderpert/Dyn_pp/kord/korder_stoch.h new file mode 100644 index 000000000..3a866e0c7 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/korder_stoch.h @@ -0,0 +1,444 @@ +/*1:*/ +#line 40 "./korder_stoch.hweb" + +#include "korder.h" +#include "faa_di_bruno.h" +#include "journal.h" + + +/*2:*/ +#line 60 "./korder_stoch.hweb" + +template +class IntegDerivs:public ctraits ::Tgss{ +public: +/*3:*/ +#line 106 "./korder_stoch.hweb" + +IntegDerivs(int r,const IntSequence&nvs,const _Tgss&g,const _Tm&mom, +double at_sigma) +:ctraits ::Tgss(4) +{ +int maxd= g.getMaxDim(); +for(int d= 1;d<=maxd;d++){ +for(int i= 0;i<=d;i++){ +int p= d-i; +Symmetry sym(i,0,0,p); +_Ttensor*ten= new _Ttensor(r,TensorDimens(sym,nvs)); +/*4:*/ +#line 129 "./korder_stoch.hweb" + +ten->zeros(); +for(int n= 0;n<=p;n++){ +int k= p-n; +int povern= Tensor::noverk(p,n); +int mfac= 1; +for(int m= 0;i+m+n+k<=maxd;m++,mfac*= m){ +double mult= (pow(at_sigma,m)*povern)/mfac; +Symmetry sym_mn(i,m+n,0,k); +if(m+n==0&&g.check(sym_mn)) +ten->add(mult,*(g.get(sym_mn))); +if(m+n> 0&&KOrder::is_even(m+n)&&g.check(sym_mn)){ +_Ttensor gtmp(*(g.get(sym_mn))); +gtmp.mult(mult); +gtmp.contractAndAdd(1,*ten,*(mom.get(Symmetry(m+n)))); +} +} +} + +/*:4*/ +#line 117 "./korder_stoch.hweb" +; +insert(ten); +} +} +} + +/*:3*/ +#line 64 "./korder_stoch.hweb" +; +}; + +/*:2*/ +#line 46 "./korder_stoch.hweb" +; +/*5:*/ +#line 156 "./korder_stoch.hweb" + +template +class StochForwardDerivs:public ctraits ::Tgss{ +public: +/*6:*/ +#line 180 "./korder_stoch.hweb" + +StochForwardDerivs(const PartitionY&ypart,int nu, +const _Tgss&g,const _Tm&m, +const Vector&ydelta,double sdelta, +double at_sigma) +:ctraits ::Tgss(4) +{ +int maxd= g.getMaxDim(); +int r= ypart.nyss(); + +/*7:*/ +#line 201 "./korder_stoch.hweb" + +IntSequence nvs(4); +nvs[0]= ypart.nys();nvs[1]= 0;nvs[2]= 0;nvs[3]= 1; +IntegDerivs g_int(r,nvs,g,m,at_sigma); + +/*:7*/ +#line 190 "./korder_stoch.hweb" +; +/*8:*/ +#line 209 "./korder_stoch.hweb" + +_Tpol g_int_sym(r,ypart.nys()+1); +for(int d= 1;d<=maxd;d++){ +_Ttensym*ten= new _Ttensym(r,ypart.nys()+1,d); +ten->zeros(); +for(int i= 0;i<=d;i++){ +int k= d-i; +if(g_int.check(Symmetry(i,0,0,k))) +ten->addSubTensor(*(g_int.get(Symmetry(i,0,0,k)))); +} +g_int_sym.insert(ten); +} + +/*:8*/ +#line 191 "./korder_stoch.hweb" +; +/*9:*/ +#line 229 "./korder_stoch.hweb" + +Vector delta(ypart.nys()+1); +Vector dy(delta,0,ypart.nys()); +ConstVector dy_in(ydelta,ypart.nstat,ypart.nys()); +dy= dy_in; +delta[ypart.nys()]= sdelta; +_Tpol g_int_cent(r,ypart.nys()+1); +for(int d= 1;d<=maxd;d++){ +g_int_sym.derivative(d-1); +_Ttensym*der= g_int_sym.evalPartially(d,delta); +g_int_cent.insert(der); +} + +/*:9*/ +#line 192 "./korder_stoch.hweb" +; +/*10:*/ +#line 245 "./korder_stoch.hweb" + +IntSequence ss(4); +ss[0]= ypart.nys();ss[1]= 0;ss[2]= 0;ss[3]= 1; +IntSequence pp(4); +pp[0]= 0;pp[1]= 1;pp[2]= 2;pp[3]= 3; +IntSequence true_nvs(nvs); +true_nvs[1]= nu;true_nvs[2]= nu; +for(int d= 1;d<=maxd;d++){ +if(g_int_cent.check(Symmetry(d))){ +for(int i= 0;i<=d;i++){ +Symmetry sym(i,0,0,d-i); +IntSequence coor(sym,pp); +_Ttensor*ten= new _Ttensor(*(g_int_cent.get(Symmetry(d))),ss,coor, +TensorDimens(sym,true_nvs)); +insert(ten); +} +} +} + + +/*:10*/ +#line 193 "./korder_stoch.hweb" +; +} + +/*:6*/ +#line 160 "./korder_stoch.hweb" +; +}; + +/*:5*/ +#line 47 "./korder_stoch.hweb" +; +/*11:*/ +#line 270 "./korder_stoch.hweb" + +template +class GXContainer:public GContainer<_Ttype> { +public: +typedef StackContainerInterface<_Ttype> _Stype; +typedef typename StackContainer<_Ttype> ::_Ctype _Ctype; +typedef typename StackContainer<_Ttype> ::itype itype; +GXContainer(const _Ctype*gs,int ngs,int nu) +:GContainer<_Ttype> (gs,ngs,nu){} +/*12:*/ +#line 285 "./korder_stoch.hweb" + +itype getType(int i,const Symmetry&s)const +{ +if(i==0) +if(s[2]> 0) +return _Stype::zero; +else +return _Stype::matrix; +if(i==1) +return _Stype::zero; +if(i==2) +return _Stype::zero; +if(i==3) +if(s==Symmetry(0,0,0,1)) +return _Stype::unit; +else +return _Stype::zero; + +KORD_RAISE("Wrong stack index in GXContainer::getType"); +} + + +/*:12*/ +#line 279 "./korder_stoch.hweb" +; +}; + +/*:11*/ +#line 48 "./korder_stoch.hweb" +; +/*13:*/ +#line 312 "./korder_stoch.hweb" + +template +class ZXContainer:public ZContainer<_Ttype> { +public: +typedef StackContainerInterface<_Ttype> _Stype; +typedef typename StackContainer<_Ttype> ::_Ctype _Ctype; +typedef typename StackContainer<_Ttype> ::itype itype; +ZXContainer(const _Ctype*gss,int ngss,const _Ctype*g,int ng,int ny,int nu) +:ZContainer<_Ttype> (gss,ngss,g,ng,ny,nu){} +/*14:*/ +#line 327 "./korder_stoch.hweb" + +itype getType(int i,const Symmetry&s)const +{ +if(i==0) +if(s[2]> 0) +return _Stype::zero; +else +return _Stype::matrix; +if(i==1) +if(s[2]> 0) +return _Stype::zero; +else +return _Stype::matrix; +if(i==2) +if(s==Symmetry(1,0,0,0)) +return _Stype::unit; +else +return _Stype::zero; +if(i==3) +if(s==Symmetry(0,1,0,0)) +return _Stype::unit; +else +return _Stype::zero; + +KORD_RAISE("Wrong stack index in ZXContainer::getType"); +} + +/*:14*/ +#line 321 "./korder_stoch.hweb" +; +}; + +/*:13*/ +#line 49 "./korder_stoch.hweb" +; +/*15:*/ +#line 355 "./korder_stoch.hweb" + +class UnfoldedGXContainer:public GXContainer ,public UnfoldedStackContainer{ +public: +typedef TensorContainer _Ctype; +UnfoldedGXContainer(const _Ctype*gs,int ngs,int nu) +:GXContainer (gs,ngs,nu){} +}; + +/*:15*/ +#line 50 "./korder_stoch.hweb" +; +/*16:*/ +#line 364 "./korder_stoch.hweb" + +class FoldedGXContainer:public GXContainer ,public FoldedStackContainer{ +public: +typedef TensorContainer _Ctype; +FoldedGXContainer(const _Ctype*gs,int ngs,int nu) +:GXContainer (gs,ngs,nu){} +}; + +/*:16*/ +#line 51 "./korder_stoch.hweb" +; +/*17:*/ +#line 373 "./korder_stoch.hweb" + +class UnfoldedZXContainer:public ZXContainer ,public UnfoldedStackContainer{ +public: +typedef TensorContainer _Ctype; +UnfoldedZXContainer(const _Ctype*gss,int ngss,const _Ctype*g,int ng,int ny,int nu) +:ZXContainer (gss,ngss,g,ng,ny,nu){} +}; + +/*:17*/ +#line 52 "./korder_stoch.hweb" +; +/*18:*/ +#line 382 "./korder_stoch.hweb" + +class FoldedZXContainer:public ZXContainer ,public FoldedStackContainer{ +public: +typedef TensorContainer _Ctype; +FoldedZXContainer(const _Ctype*gss,int ngss,const _Ctype*g,int ng,int ny,int nu) +:ZXContainer (gss,ngss,g,ng,ny,nu){} +}; + +/*:18*/ +#line 53 "./korder_stoch.hweb" +; +/*19:*/ +#line 397 "./korder_stoch.hweb" + +class MatrixAA:public PLUMatrix{ +public: +MatrixAA(const FSSparseTensor&f,const IntSequence&ss, +const TwoDMatrix&gyss,const PartitionY&ypart); +}; + + +/*:19*/ +#line 54 "./korder_stoch.hweb" +; +/*20:*/ +#line 418 "./korder_stoch.hweb" + +class KOrderStoch{ +protected: +IntSequence nvs; +PartitionY ypart; +Journal&journal; +UGSContainer _ug; +FGSContainer _fg; +UGSContainer _ugs; +FGSContainer _fgs; +UGSContainer _uG; +FGSContainer _fG; +const UGSContainer*_uh; +const FGSContainer*_fh; +UnfoldedZXContainer _uZstack; +FoldedZXContainer _fZstack; +UnfoldedGXContainer _uGstack; +FoldedGXContainer _fGstack; +const TensorContainer &f; +MatrixAA matA; +public: +KOrderStoch(const PartitionY&ypart,int nu,const TensorContainer &fcont, +const FGSContainer&hh,Journal&jr); +KOrderStoch(const PartitionY&ypart,int nu,const TensorContainer &fcont, +const UGSContainer&hh,Journal&jr); +/*23:*/ +#line 496 "./korder_stoch.hweb" + +template +void performStep(int order) +{ +int maxd= g ().getMaxDim(); +KORD_RAISE_IF(order-1!=maxd&&(order!=1||maxd!=-1), +"Wrong order for KOrderStoch::performStep"); +SymmetrySet ss(order,4); +for(symiterator si(ss);!si.isEnd();++si){ +if((*si)[2]==0){ +JournalRecordPair pa(journal); +pa<<"Recovering symmetry "<<*si< (*si); +G ().insert(G_sym); + +_Ttensor*g_sym= faaDiBrunoZ (*si); +g_sym->mult(-1.0); +matA.multInv(*g_sym); +g ().insert(g_sym); +gs ().insert(new _Ttensor(ypart.nstat,ypart.nys(),*g_sym)); + +Gstack ().multAndAdd(1,h (),*G_sym); +} +} +} + +/*:23*/ +#line 443 "./korder_stoch.hweb" +; +const FGSContainer&getFoldDers()const +{return _fg;} +const UGSContainer&getUnfoldDers()const +{return _ug;} +protected: +/*21:*/ +#line 457 "./korder_stoch.hweb" + +template +_Ttensor*faaDiBrunoZ(const Symmetry&sym)const +{ +JournalRecordPair pa(journal); +pa<<"Faa Di Bruno ZX container for "< (),f,*res); +return res; +} + +/*:21*/ +#line 449 "./korder_stoch.hweb" +; +/*22:*/ +#line 472 "./korder_stoch.hweb" + +template +_Ttensor*faaDiBrunoG(const Symmetry&sym)const +{ +JournalRecordPair pa(journal); +pa<<"Faa Di Bruno GX container for "< (),h (),*res); +return res; +} + +/*:22*/ +#line 450 "./korder_stoch.hweb" +; +/*24:*/ +#line 524 "./korder_stoch.hweb" + +template _Tg&g(); +template const _Tg&g()const; +template _Tgs&gs(); +template const _Tgs&gs()const; +template const _Tgss&h()const; +template _TG&G(); +template const _TG&G()const; +template _TZXstack&Zstack(); +template const _TZXstack&Zstack()const; +template _TGXstack&Gstack(); +template const _TGXstack&Gstack()const; + + +/*:24*/ +#line 451 "./korder_stoch.hweb" +; +}; + +/*:20*/ +#line 55 "./korder_stoch.hweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/mersenne_twister.h b/mex/sources/korderpert/Dyn_pp/kord/mersenne_twister.h new file mode 100644 index 000000000..dcc25ee1d --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/mersenne_twister.h @@ -0,0 +1,157 @@ +/*1:*/ +#line 14 "./mersenne_twister.hweb" + +#ifndef MERSENNE_TWISTER_H +#define MERSENNE_TWISTER_H + +#include "random.h" +#include + +/*2:*/ +#line 27 "./mersenne_twister.hweb" + +class MersenneTwister:public RandomGenerator{ +protected: +typedef unsigned int uint32; +enum{STATE_SIZE= 624}; +enum{RECUR_OFFSET= 397}; +uint32 statevec[STATE_SIZE]; +int stateptr; +public: +MersenneTwister(uint32 iseed); +MersenneTwister(const MersenneTwister&mt); +virtual~MersenneTwister(){} +uint32 lrand(); +double drand(); +double uniform() +{return drand();} +protected: +void seed(uint32 iseed); +void refresh(); +private: +/*3:*/ +#line 51 "./mersenne_twister.hweb" + +static uint32 hibit(uint32 u) +{return u&0x80000000UL;} +static uint32 lobit(uint32 u) +{return u&0x00000001UL;} +static uint32 lobits(uint32 u) +{return u&0x7fffffffUL;} +static uint32 mixbits(uint32 u,uint32 v) +{return hibit(u)|lobits(v);} +static uint32 twist(uint32 m,uint32 s0,uint32 s1) +{return m^(mixbits(s0,s1)>>1)^(-lobit(s1)&0x9908b0dfUL);} + + +/*:3*/ +#line 47 "./mersenne_twister.hweb" +; +}; + +/*:2*/ +#line 21 "./mersenne_twister.hweb" +; +/*4:*/ +#line 65 "./mersenne_twister.hweb" + +/*5:*/ +#line 74 "./mersenne_twister.hweb" + +inline MersenneTwister::MersenneTwister(uint32 iseed) +{ +seed(iseed); +} + +/*:5*/ +#line 66 "./mersenne_twister.hweb" +; +/*6:*/ +#line 81 "./mersenne_twister.hweb" + +inline MersenneTwister::MersenneTwister(const MersenneTwister&mt) +:stateptr(mt.stateptr) +{ +memcpy(statevec,mt.statevec,sizeof(uint32)*STATE_SIZE); +} + +/*:6*/ +#line 67 "./mersenne_twister.hweb" +; +/*7:*/ +#line 89 "./mersenne_twister.hweb" + +inline MersenneTwister::uint32 MersenneTwister::lrand() +{ +if(stateptr>=STATE_SIZE) +refresh(); + +register uint32 v= statevec[stateptr++]; +v^= v>>11; +v^= (v<<7)&0x9d2c5680; +v^= (v<<15)&0xefc60000; +return(v^(v>>18)); +} + +/*:7*/ +#line 68 "./mersenne_twister.hweb" +; +/*8:*/ +#line 103 "./mersenne_twister.hweb" + +inline double MersenneTwister::drand() +{ +uint32 a= lrand()>>5; +uint32 b= lrand()>>6; +return(a*67108864.0+b)*(1.0/9007199254740992.0); +} + +/*:8*/ +#line 69 "./mersenne_twister.hweb" +; +/*9:*/ +#line 112 "./mersenne_twister.hweb" + +inline void MersenneTwister::seed(uint32 iseed) +{ +statevec[0]= iseed&0xffffffffUL; +for(int i= 1;i>30; +val^= statevec[i-1]; +val*= 1812433253ul; +val+= i; +statevec[i]= val&0xffffffffUL; +} + +refresh(); +} + +/*:9*/ +#line 70 "./mersenne_twister.hweb" +; +/*10:*/ +#line 128 "./mersenne_twister.hweb" + +inline void MersenneTwister::refresh() +{ +register uint32*p= statevec; +for(int i= STATE_SIZE-RECUR_OFFSET;i--;++p) +*p= twist(p[RECUR_OFFSET],p[0],p[1]); +for(int i= RECUR_OFFSET;--i;++p) +*p= twist(p[RECUR_OFFSET-STATE_SIZE],p[0],p[1]); +*p= twist(p[RECUR_OFFSET-STATE_SIZE],p[0],statevec[0]); + +stateptr= 0; +} + +/*:10*/ +#line 71 "./mersenne_twister.hweb" +; + +/*:4*/ +#line 22 "./mersenne_twister.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/normal_conjugate.cpp b/mex/sources/korderpert/Dyn_pp/kord/normal_conjugate.cpp new file mode 100644 index 000000000..1ebe89bbb --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/normal_conjugate.cpp @@ -0,0 +1,130 @@ +/*1:*/ +#line 6 "./normal_conjugate.cweb" + + +#include "normal_conjugate.h" +#include "kord_exception.h" + +/*2:*/ +#line 20 "./normal_conjugate.cweb" + +NormalConj::NormalConj(int d) +:mu(d),kappa(0),nu(-1),lambda(d,d) +{ +mu.zeros(); +lambda.zeros(); +} + +/*:2*/ +#line 11 "./normal_conjugate.cweb" +; +/*3:*/ +#line 29 "./normal_conjugate.cweb" + +NormalConj::NormalConj(const ConstTwoDMatrix&ydata) +:mu(ydata.numRows()),kappa(ydata.numCols()),nu(ydata.numCols()-1), +lambda(ydata.numRows(),ydata.numRows()) +{ +mu.zeros(); +for(int i= 0;i getDim()+1){ +v= (const TwoDMatrix&)lambda; +v.mult(1.0/(nu-getDim()-1)); +}else +v.nans(); +} + + +/*:8*/ +#line 17 "./normal_conjugate.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/normal_conjugate.h b/mex/sources/korderpert/Dyn_pp/kord/normal_conjugate.h new file mode 100644 index 000000000..c05016513 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/normal_conjugate.h @@ -0,0 +1,47 @@ +/*1:*/ +#line 37 "./normal_conjugate.hweb" + +#ifndef NORMAL_CONJUGATE_H +#define NORMAL_CONJUGATE_H + +#include "twod_matrix.h" + +/*2:*/ +#line 49 "./normal_conjugate.hweb" + +class NormalConj{ +protected: +Vector mu; +int kappa; +int nu; +TwoDMatrix lambda; +public: +/*3:*/ +#line 76 "./normal_conjugate.hweb" + +NormalConj(int d); +NormalConj(const ConstTwoDMatrix&ydata); +NormalConj(const NormalConj&nc); + + +/*:3*/ +#line 57 "./normal_conjugate.hweb" +; +virtual~NormalConj(){} +void update(const ConstVector&y); +void update(const ConstTwoDMatrix&ydata); +void update(const NormalConj&nc); +int getDim()const +{return mu.length();} +const Vector&getMean()const +{return mu;} +void getVariance(TwoDMatrix&v)const; +}; + +/*:2*/ +#line 43 "./normal_conjugate.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/random.cpp b/mex/sources/korderpert/Dyn_pp/kord/random.cpp new file mode 100644 index 000000000..ca9ca624c --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/random.cpp @@ -0,0 +1,73 @@ +/*1:*/ +#line 5 "./random.cweb" + + +#include "random.h" + +#include +#include +#include + +/*2:*/ +#line 20 "./random.cweb" + +int RandomGenerator::int_uniform() +{ +double s= std::numeric_limits ::max()*uniform(); +return(int)s; +} + +/*:2*/ +#line 13 "./random.cweb" +; +/*3:*/ +#line 28 "./random.cweb" + +double RandomGenerator::normal() +{ +double x1,x2; +double w; +do{ +x1= 2*uniform()-1; +x2= 2*uniform()-1; +w= x1*x1+x2*x2; +}while(w>=1.0||w<1.0e-30); +return x1*std::sqrt((-2.0*std::log(w))/w); +} + +/*:3*/ +#line 14 "./random.cweb" +; +SystemRandomGenerator system_random_generator; +/*4:*/ +#line 42 "./random.cweb" + +double SystemRandomGenerator::uniform() +{ +#ifndef __MINGW32__ +return drand48(); +#else +return((double)rand())/RAND_MAX; +#endif +} + +/*:4*/ +#line 16 "./random.cweb" +; +/*5:*/ +#line 53 "./random.cweb" + +void SystemRandomGenerator::initSeed(int seed) +{ +#ifndef __MINGW32__ +srand48(seed); +#else +srand(seed); +#endif +} + +/*:5*/ +#line 17 "./random.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/random.h b/mex/sources/korderpert/Dyn_pp/kord/random.h new file mode 100644 index 000000000..eb4116dff --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/random.h @@ -0,0 +1,36 @@ +/*1:*/ +#line 9 "./random.hweb" + +#ifndef RANDOM_H +#define RANDOM_H + +/*2:*/ +#line 22 "./random.hweb" + +class RandomGenerator{ +public: +virtual double uniform()= 0; +int int_uniform(); +double normal(); +}; + +/*:2*/ +#line 13 "./random.hweb" +; +/*3:*/ +#line 32 "./random.hweb" + +class SystemRandomGenerator:public RandomGenerator{ +public: +double uniform(); +void initSeed(int seed); +}; + +/*:3*/ +#line 14 "./random.hweb" +; +extern SystemRandomGenerator system_random_generator; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/kord/tests.cpp b/mex/sources/korderpert/Dyn_pp/kord/tests.cpp new file mode 100644 index 000000000..75f18a6b9 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/kord/tests.cpp @@ -0,0 +1,413 @@ +/* $Id: tests.cpp 148 2005-04-19 15:12:26Z kamenik $ */ +/* Copyright 2004, Ondra Kamenik */ + +#include "korder.h" +#include "SylvException.h" + +struct Rand { + static void init(int n1, int n2, int n3, int n4, int n5); + static double get(double m); + static int get(int m); + static bool discrete(double prob); // answers true with given probability +}; + +void Rand::init(int n1, int n2, int n3, int n4, int n5) +{ + long int seed = n1; + seed = 256*seed+n2; + seed = 256*seed+n3; + seed = 256*seed+n4; + seed = 256*seed+n5; + srand48(seed); +} + +double Rand::get(double m) +{ + return 2*m*(drand48()-0.5); +} + +int Rand::get(int m) +{ + return (int)(Rand::get(0.9999*m)); +} + +bool Rand::discrete(double prob) +{ + return drand48() < prob; +} + +struct SparseGenerator { + static FSSparseTensor* makeTensor(int dim, int nv, int r, + double fill, double m); + static void fillContainer(TensorContainer& c, + int maxdim, int nv, int r, double m); +}; + +FSSparseTensor* SparseGenerator::makeTensor(int dim, int nv, int r, + double fill, double m) +{ + FSSparseTensor* res = new FSSparseTensor(dim, nv, r); + FFSTensor dummy(0, nv, dim); + for (Tensor::index fi = dummy.begin(); fi != dummy.end(); ++fi) { + for (int i = 0; i < r; i++) { + if (Rand::discrete(fill)) { + double x = Rand::get(m); + res->insert(fi.getCoor(), i, x); + } + } + } + return res; +} + +void SparseGenerator::fillContainer(TensorContainer& c, + int maxdim, int nv, int r, + double m) +{ + Rand::init(maxdim, nv, r, (int)(5*m), 0); + double fill = 0.5; + for (int d = 1; d <= maxdim; d++) { + c.insert(makeTensor(d,nv,r,fill,m)); + fill *= 0.3; + } +} + +const double vdata [] = { // 3x3 + 0.1307870268, 0.1241940078, 0.1356703123, + 0.1241940078, 0.1986920419, 0.2010160581, + 0.1356703123, 0.2010160581, 0.2160336975 +}; + + +const double gy_data [] = { // 8x4 + 0.3985178619, -0.5688233582, 0.9572900437, -0.6606847776, 0.1453004017, + 0.3025310675, -0.8627437750, -0.6903410191, 0.4751910580, -0.7270018589, + -0.0939612498, -0.1463831989, 0.6742110220, 0.6046671043, 0.5215893126, + -1.0412969986, -0.3524898417, -1.0986703430, 0.8006531522, 0.8879776376, + -0.1037608317, -0.5587378073, -0.1010366945, 0.9462411248, -0.2439199881, + 1.3420621236, -0.7820285935, 0.3205293447, 0.3606124791, 0.2975422208, + -0.5452861965, 1.6320340279 +}; + +const double gu_data [] = { // just some numbers, no structure + 1.8415286914, -0.2638743845, 1.7690713274, 0.9668585956, 0.2303143646, + -0.2229624279, -0.4381991822, 1.0082401405, -0.3186555860, -0.0624691529, + -0.5189085756, 1.4269672156, 0.1163282969, 1.4020183445, -0.0952660426, + 0.2099097124, 0.6912400502, -0.5180935114, 0.5288316624, 0.2188053448, + 0.5715516767, 0.7813893410, -0.6385073106, 0.8335131513, 0.3605202168, + -1.1167944865, -1.2263750934, 0.6113636081, 0.6964915482, -0.6451217688, + 0.4062810500, -2.0552251116, -1.6383406284, 0.0198915095, 0.0111014458, + -1.2421792262, -1.0724161722, -0.4276904972, 0.1801494950, -2.0716473264 +}; + +const double vdata2 [] = { // 10x10 positive definite + 0.79666, -0.15536, 0.05667, -0.21026, 0.20262, 0.28505, 0.60341, -0.09703, 0.32363, 0.13299, + -0.15536, 0.64380, -0.01131, 0.00980, 0.03755, 0.43791, 0.21784, -0.31755, -0.55911, -0.29655, + 0.05667, -0.01131, 0.56165, -0.34357, -0.40584, 0.20990, 0.28348, 0.20398, -0.19856, 0.35820, + -0.21026, 0.00980, -0.34357, 0.56147, 0.10972, -0.34146, -0.49906, -0.19685, 0.21088, -0.31560, + 0.20262, 0.03755, -0.40584, 0.10972, 0.72278, 0.02155, 0.04089, -0.19696, 0.03446, -0.12919, + 0.28505, 0.43791, 0.20990, -0.34146, 0.02155, 0.75867, 0.77699, -0.31125, -0.55141, -0.02155, + 0.60341, 0.21784, 0.28348, -0.49906, 0.04089, 0.77699, 1.34553, -0.18613, -0.25811, -0.19016, + -0.09703, -0.31755, 0.20398, -0.19685, -0.19696, -0.31125, -0.18613, 0.59470, 0.08386, 0.41750, + 0.32363, -0.55911, -0.19856, 0.21088, 0.03446, -0.55141, -0.25811, 0.08386, 0.98917, -0.12992, + 0.13299, -0.29655, 0.35820, -0.31560, -0.12919, -0.02155, -0.19016, 0.41750, -0.12992, 0.89608 +}; + +const double gy_data2 [] = { // 600 items make gy 30x20, whose gy(6:25,:) has spectrum within unit + 0.39414, -0.29766, 0.08948, -0.19204, -0.00750, 0.21159, 0.05494, 0.06225, 0.01771, 0.21913, + -0.01373, 0.20086, -0.06086, -0.10955, 0.14424, -0.08390, 0.03948, -0.14713, 0.11674, 0.05091, + 0.24039, 0.28307, -0.11835, 0.13030, 0.11682, -0.27444, -0.19311, -0.16654, 0.12867, 0.25116, + -0.19781, 0.45242, -0.15862, 0.24428, -0.11966, 0.11483, -0.32279, 0.29727, 0.20934, -0.18190, + -0.15080, -0.09477, -0.30551, -0.02672, -0.26919, 0.11165, -0.06390, 0.03449, -0.26622, 0.22197, + 0.45141, -0.41683, 0.09760, 0.31094, -0.01652, 0.05809, -0.04514, -0.05645, 0.00554, 0.47980, + 0.11726, 0.42459, -0.13136, -0.30902, -0.14648, 0.11455, 0.02947, -0.03835, -0.04044, 0.03559, + -0.26575, -0.01783, 0.31243, -0.14412, -0.13218, -0.05080, 0.18576, 0.13840, -0.05560, 0.35530, + -0.25573, -0.11560, 0.15187, -0.18431, 0.08193, -0.32278, 0.17560, -0.05529, -0.10020, -0.23088, + -0.20979, -0.49245, 0.09915, -0.16909, -0.03443, 0.19497, 0.18473, 0.25662, 0.29605, -0.20531, + -0.39244, -0.43369, 0.05588, 0.24823, -0.14236, -0.08311, 0.16371, -0.19975, 0.30605, -0.17087, + -0.01270, 0.00123, -0.22426, -0.13810, 0.05079, 0.06971, 0.01922, -0.09952, -0.23177, -0.41962, + -0.41991, 0.41430, -0.04247, -0.13706, -0.12048, -0.28906, -0.22813, -0.25057, -0.18579, -0.20642, + -0.47976, 0.25490, -0.05138, -0.30794, 0.31651, 0.02034, 0.12954, -0.20110, 0.13336, -0.40775, + -0.30195, -0.13704, 0.12396, 0.28152, 0.02986, 0.27669, 0.24623, 0.08635, -0.11956, -0.02949, + 0.37401, 0.20838, 0.24801, -0.26872, 0.11195, 0.00315, -0.19069, 0.12839, -0.23036, -0.48228, + 0.08434, -0.39872, -0.28896, -0.28754, 0.24668, 0.23285, 0.25437, 0.10456, -0.14124, 0.20483, + -0.19117, -0.33836, -0.24875, 0.08207, -0.03930, 0.20364, 0.15384, -0.15270, 0.24372, -0.11199, + -0.46591, 0.30319, 0.05745, 0.09084, 0.06058, 0.31884, 0.05071, -0.28899, -0.30793, -0.03566, + 0.02286, 0.28178, 0.00736, -0.31378, -0.18144, -0.22346, -0.27239, 0.31043, -0.26228, 0.22181, + -0.15096, -0.36953, -0.06032, 0.21496, 0.29545, -0.13112, 0.16420, -0.07573, -0.43111, -0.43057, + 0.26716, -0.31209, -0.05866, -0.29101, -0.27437, -0.18727, 0.28732, -0.19014, 0.08837, 0.30405, + 0.06103, -0.35612, 0.00173, 0.25134, -0.08987, -0.22766, -0.03254, -0.18662, -0.08491, 0.49401, + -0.12145, -0.02961, -0.03668, -0.30043, -0.08555, 0.01701, -0.12544, 0.10969, -0.48202, 0.07245, + 0.20673, 0.11408, 0.04343, -0.01815, -0.31594, -0.23632, -0.06258, -0.27474, 0.12180, 0.16613, + -0.37931, 0.30219, 0.15765, 0.25489, 0.17529, -0.17020, -0.30060, 0.22058, -0.02450, -0.42143, + 0.49642, 0.46899, -0.28552, -0.22549, -0.01333, 0.21567, 0.22251, 0.21639, -0.19194, -0.19140, + -0.24106, 0.10952, -0.11019, 0.29763, -0.02039, -0.25748, 0.23169, 0.01357, 0.09802, -0.19022, + 0.37604, -0.40777, 0.18131, -0.10258, 0.29573, -0.31773, 0.09069, -0.02198, -0.26594, 0.48302, + -0.10041, 0.20210, -0.05609, -0.01169, -0.17339, 0.17862, -0.22502, 0.29009, -0.45160, 0.19771, + 0.27634, 0.31695, -0.09993, 0.17167, 0.12394, 0.28088, -0.12502, -0.16967, -0.06296, -0.17036, + 0.27320, 0.01595, 0.16955, 0.30146, -0.15173, -0.29807, 0.08178, -0.06811, 0.21655, 0.26348, + 0.06316, 0.45661, -0.29756, -0.05742, -0.14715, -0.03037, -0.16656, -0.08768, 0.38078, 0.40679, + -0.32779, -0.09106, 0.16107, -0.07301, 0.07700, -0.22694, -0.15692, -0.02548, 0.38749, -0.12203, + -0.02980, -0.22067, 0.00680, -0.23058, -0.29112, 0.23032, -0.16026, 0.23392, -0.09990, 0.03628, + -0.42592, -0.33474, -0.09499, -0.17442, -0.20110, 0.24618, -0.06418, -0.06715, 0.40754, 0.29377, + 0.29543, -0.16832, -0.08468, 0.06491, -0.01410, 0.19988, 0.24950, 0.14626, -0.27851, 0.06079, + 0.48134, -0.13475, 0.25398, 0.11738, 0.23369, -0.00661, -0.16811, -0.04557, -0.12030, -0.39527, + -0.35760, 0.01840, -0.15941, 0.03290, 0.09988, -0.08307, 0.06644, -0.24637, 0.34112, -0.08026, + 0.00951, 0.27656, 0.16247, 0.28217, 0.17198, -0.16389, -0.03835, -0.02675, -0.08032, -0.21045, + -0.38946, 0.23207, 0.10987, -0.31674, -0.28653, -0.27430, -0.29109, -0.00648, 0.38431, -0.38478, + -0.41195, -0.19364, -0.20977, -0.05524, 0.05558, -0.20109, 0.11803, -0.19884, 0.43318, -0.39255, + 0.26612, -0.21771, 0.12471, 0.12856, -0.15104, -0.11676, 0.17582, -0.25330, 0.00298, -0.31712, + 0.21532, -0.20319, 0.14507, -0.04588, -0.22995, -0.06470, 0.18849, -0.13444, 0.37107, 0.07387, + -0.14008, 0.09896, 0.13727, -0.28417, -0.09461, -0.18703, 0.04080, 0.02343, -0.49988, 0.17993, + 0.23189, -0.30581, -0.18334, -0.09667, -0.27699, -0.05998, 0.09118, -0.32453, 0.46251, 0.41500, + -0.45314, -0.00544, 0.08529, 0.29099, -0.00937, -0.31650, 0.26163, 0.14506, 0.37498, -0.16454, + 0.35215, 0.31642, -0.09161, -0.31452, -0.04792, -0.04677, -0.19523, 0.27998, 0.05491, 0.44461, + -0.01258, -0.27887, 0.18361, -0.04539, -0.02977, 0.30821, 0.29454, -0.17932, 0.16193, 0.23934, + 0.47923, 0.25373, 0.23258, 0.31484, -0.17958, -0.01136, 0.17681, 0.12869, 0.03235, 0.43762, + 0.13734, -0.09433, -0.03735, 0.17949, 0.14122, -0.17814, 0.06359, 0.16044, 0.12249, -0.22314, + 0.40775, 0.05147, 0.12389, 0.04290, -0.01642, 0.00082, -0.18056, 0.02875, 0.32690, 0.17712, + 0.34001, -0.21581, -0.01086, -0.18180, 0.17480, -0.17774, -0.07503, 0.28438, -0.19747, 0.29595, + -0.28002, -0.02073, -0.16522, -0.18234, -0.20565, 0.29620, 0.07502, 0.01429, -0.31418, 0.43693, + -0.12212, 0.11178, -0.28503, 0.04683, 0.00072, 0.05566, 0.18857, 0.26101, -0.38891, -0.21216, + -0.21850, -0.15147, -0.30749, -0.23762, 0.14984, 0.03535, -0.02862, -0.00105, -0.39907, -0.06909, + -0.36094, 0.21717, 0.15930, -0.18924, 0.13741, 0.01039, 0.13613, 0.00659, 0.07676, -0.13711, + 0.24285, -0.07564, -0.28349, -0.15658, 0.03135, -0.30909, -0.22534, 0.17363, -0.19376, 0.26038, + 0.05546, -0.22607, 0.32420, -0.02552, -0.05400, 0.13388, 0.04643, -0.31535, -0.06181, 0.30237, + -0.04680, -0.29441, 0.12231, 0.03960, -0.01188, 0.01406, 0.25402, 0.03315, 0.25026, -0.10922 +}; + +const double gu_data2 [] = { // raw data 300 items + 0.26599, 0.41329, 0.31846, 0.92590, 0.43050, 0.17466, 0.02322, 0.72621, 0.37921, 0.70597, + 0.97098, 0.14023, 0.57619, 0.09938, 0.02281, 0.92341, 0.72654, 0.71000, 0.76687, 0.70182, + 0.88752, 0.49524, 0.42549, 0.42806, 0.57615, 0.76051, 0.15341, 0.47457, 0.60066, 0.40880, + 0.20668, 0.41949, 0.97620, 0.94318, 0.71491, 0.56402, 0.23553, 0.94387, 0.78567, 0.06362, + 0.85252, 0.86262, 0.25190, 0.03274, 0.93216, 0.37971, 0.08797, 0.14596, 0.73871, 0.06574, + 0.67447, 0.28575, 0.43911, 0.92133, 0.12327, 0.87762, 0.71060, 0.07141, 0.55443, 0.53310, + 0.91529, 0.25121, 0.07593, 0.94490, 0.28656, 0.82174, 0.68887, 0.67337, 0.99291, 0.03316, + 0.02849, 0.33891, 0.25594, 0.90071, 0.01248, 0.67871, 0.65953, 0.65369, 0.97574, 0.31578, + 0.23678, 0.39220, 0.06706, 0.80943, 0.57694, 0.08220, 0.18151, 0.19969, 0.37096, 0.37858, + 0.70153, 0.46816, 0.76511, 0.02520, 0.39387, 0.25527, 0.39050, 0.60141, 0.30322, 0.46195, + 0.12025, 0.33616, 0.04174, 0.00196, 0.68886, 0.74445, 0.15869, 0.18994, 0.95195, 0.62874, + 0.82874, 0.53369, 0.34383, 0.50752, 0.97023, 0.22695, 0.62407, 0.25840, 0.71279, 0.28785, + 0.31611, 0.20391, 0.19702, 0.40760, 0.85158, 0.68369, 0.63760, 0.09879, 0.11924, 0.32920, + 0.53052, 0.15900, 0.21229, 0.84080, 0.33933, 0.93651, 0.42705, 0.06199, 0.50092, 0.47192, + 0.57152, 0.01818, 0.31404, 0.50173, 0.87725, 0.50530, 0.10717, 0.04035, 0.32901, 0.33538, + 0.04780, 0.40984, 0.78216, 0.91288, 0.11314, 0.25248, 0.23823, 0.74001, 0.48089, 0.55531, + 0.82486, 0.01058, 0.05409, 0.44357, 0.52641, 0.68188, 0.94629, 0.61627, 0.33037, 0.11961, + 0.57988, 0.19653, 0.91902, 0.59838, 0.52974, 0.28364, 0.45767, 0.65836, 0.63045, 0.76140, + 0.27918, 0.27256, 0.46035, 0.77418, 0.92918, 0.14095, 0.89645, 0.25146, 0.21172, 0.47910, + 0.95451, 0.34377, 0.29927, 0.79220, 0.97654, 0.67591, 0.44385, 0.38434, 0.44860, 0.28170, + 0.90712, 0.20337, 0.00292, 0.55046, 0.62255, 0.45127, 0.80896, 0.43965, 0.59145, 0.23801, + 0.33601, 0.30119, 0.89935, 0.40850, 0.98226, 0.75430, 0.68318, 0.65407, 0.68067, 0.32942, + 0.11756, 0.27626, 0.83879, 0.72174, 0.75430, 0.13702, 0.03402, 0.58781, 0.07393, 0.23067, + 0.92537, 0.29445, 0.43437, 0.47685, 0.54548, 0.66082, 0.23805, 0.60208, 0.94337, 0.21363, + 0.72637, 0.57181, 0.77679, 0.63931, 0.72860, 0.38901, 0.94920, 0.04535, 0.12863, 0.40550, + 0.90095, 0.21418, 0.13953, 0.99639, 0.02526, 0.70018, 0.21828, 0.20294, 0.20191, 0.30954, + 0.39490, 0.68955, 0.11506, 0.15748, 0.40252, 0.91680, 0.61547, 0.78443, 0.19693, 0.67630, + 0.56552, 0.58556, 0.53554, 0.53507, 0.09831, 0.21229, 0.83135, 0.26375, 0.89287, 0.97069, + 0.70615, 0.42041, 0.43117, 0.21291, 0.26086, 0.26978, 0.77340, 0.43833, 0.46179, 0.54418, + 0.67878, 0.42776, 0.61454, 0.55915, 0.36363, 0.31999, 0.42442, 0.86649, 0.62513, 0.02047 +}; + +class TestRunnable { + char name[100]; +public: + int dim; // dimension of the solved problem + int nvar; // number of variable of the solved problem + TestRunnable(const char* n, int d, int nv) + : dim(d), nvar(nv) + {strncpy(name, n, 100);} + bool test() const; + virtual bool run() const =0; + const char* getName() const + {return name;} +protected: + static double korder_unfold_fold(int maxdim, int unfold_dim, + int nstat, int npred, int nboth, int forw, + const TwoDMatrix& gy, const TwoDMatrix& gu, + const TwoDMatrix& v); +}; + + +bool TestRunnable::test() const +{ + printf("Running test <%s>\n",name); + clock_t start = clock(); + bool passed = run(); + clock_t end = clock(); + printf("CPU time %8.4g (CPU seconds)..................", + ((double)(end-start))/CLOCKS_PER_SEC); + if (passed) { + printf("passed\n\n"); + return passed; + } else { + printf("FAILED\n\n"); + return passed; + } +} + +double TestRunnable::korder_unfold_fold(int maxdim, int unfold_dim, + int nstat, int npred, int nboth, int nforw, + const TwoDMatrix& gy, const TwoDMatrix& gu, + const TwoDMatrix& v) +{ + TensorContainer c(1); + int ny = nstat+npred+nboth+nforw; + int nu = v.nrows(); + int nz = nboth+nforw+ny+nboth+npred+nu; + SparseGenerator::fillContainer(c, maxdim, nz, ny, 5.0); + for (int d = 1; d <= maxdim; d++) { + printf("\ttensor fill for dim=%d is: %3.2f %%\n", + d, c.get(Symmetry(d))->getFillFactor()*100.0); + } + Journal jr("out.txt"); + KOrder kord(nstat, npred, nboth, nforw, c, gy, gu, v, jr); + // perform unfolded steps until unfold_dim + double maxerror = 0.0; + for (int d = 2; d <= unfold_dim; d++) { + clock_t pertime = clock(); + kord.performStep(d); + pertime = clock()-pertime; + printf("\ttime for unfolded step dim=%d: %8.4g\n", + d, ((double)(pertime))/CLOCKS_PER_SEC); + clock_t checktime = clock(); + double err = kord.check(d); + checktime = clock()-checktime; + printf("\ttime for step check dim=%d: %8.4g\n", + d, ((double)(checktime))/CLOCKS_PER_SEC); + printf("\tmax error in step dim=%d: %10.6g\n", + d, err); + if (maxerror < err) + maxerror = err; + } + // perform folded steps until maxdim + if (unfold_dim < maxdim) { + clock_t swtime = clock(); + kord.switchToFolded(); + swtime = clock()-swtime; + printf("\ttime for switching dim=%d: %8.4g\n", + unfold_dim, ((double)(swtime))/CLOCKS_PER_SEC); + + for (int d = unfold_dim+1; d <= maxdim; d++) { + clock_t pertime = clock(); + kord.performStep(d); + pertime = clock()-pertime; + printf("\ttime for folded step dim=%d: %8.4g\n", + d, ((double)(pertime))/CLOCKS_PER_SEC); + clock_t checktime = clock(); + double err = kord.check(d); + checktime = clock()-checktime; + printf("\ttime for step check dim=%d: %8.4g\n", + d, ((double)(checktime))/CLOCKS_PER_SEC); + printf("\tmax error in step dim=%d: %10.6g\n", + d, err); + if (maxerror < err) + maxerror = err; + } + } + return maxerror; +} + +class UnfoldKOrderSmall : public TestRunnable { +public: + UnfoldKOrderSmall() + : TestRunnable("unfold-3 fold-4 korder (stat=2,pred=3,both=1,forw=2,u=3,dim=4)", + 4, 18) {} + + bool run() const + { + TwoDMatrix gy(8, 4, gy_data); + TwoDMatrix gu(8, 3, gu_data); + TwoDMatrix v(3, 3, vdata); + double err = korder_unfold_fold(4, 3, 2, 3, 1, 2, + gy, gu, v); + + return err < 0.08; + } +}; + +// same dimension as Smets & Wouters +class UnfoldKOrderSW : public TestRunnable { +public: + UnfoldKOrderSW() + : TestRunnable("unfold S&W korder (stat=5,pred=12,both=8,forw=5,u=10,dim=4)", + 4, 73) {} + + bool run() const + { + TwoDMatrix gy(30, 20, gy_data2); + TwoDMatrix gu(30, 10, gu_data2); + TwoDMatrix v(10, 10, vdata2); + v.mult(0.001); + gu.mult(.01); + double err = korder_unfold_fold(4, 4, 5, 12, 8, 5, + gy, gu, v); + + return err < 0.08; + } +}; + +class UnfoldFoldKOrderSW : public TestRunnable { +public: + UnfoldFoldKOrderSW() + : TestRunnable("unfold-2 fold-3 S&W korder (stat=5,pred=12,both=8,forw=5,u=10,dim=3)", + 4, 73) {} + + bool run() const + { + TwoDMatrix gy(30, 20, gy_data2); + TwoDMatrix gu(30, 10, gu_data2); + TwoDMatrix v(10, 10, vdata2); + v.mult(0.001); + gu.mult(.01); + double err = korder_unfold_fold(4, 3, 5, 12, 8, 5, + gy, gu, v); + + return err < 0.08; + } +}; + +int main() +{ + TestRunnable* all_tests[50]; + // fill in vector of all tests + int num_tests = 0; + all_tests[num_tests++] = new UnfoldKOrderSmall(); + all_tests[num_tests++] = new UnfoldKOrderSW(); + all_tests[num_tests++] = new UnfoldFoldKOrderSW(); + + // find maximum dimension and maximum nvar + int dmax=0; + int nvmax = 0; + for (int i = 0; i < num_tests; i++) { + if (dmax < all_tests[i]->dim) + dmax = all_tests[i]->dim; + if (nvmax < all_tests[i]->nvar) + nvmax = all_tests[i]->nvar; + } + tls.init(dmax, nvmax); // initialize library + + // launch the tests + int success = 0; + for (int i = 0; i < num_tests; i++) { + try { + if (all_tests[i]->test()) + success++; + } catch (const TLException& e) { + printf("Caugth TL exception in <%s>:\n", all_tests[i]->getName()); + e.print(); + } catch (SylvException& e) { + printf("Caught Sylv exception in <%s>:\n", all_tests[i]->getName()); + e.printMessage(); + } + } + + printf("There were %d tests that failed out of %d tests run.\n", + num_tests - success, num_tests); + + // destroy + for (int i = 0; i < num_tests; i++) { + delete all_tests[i]; + } + + return 0; +} diff --git a/mex/sources/korderpert/Dyn_pp/src/Makefile b/mex/sources/korderpert/Dyn_pp/src/Makefile new file mode 100644 index 000000000..3659a3312 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/src/Makefile @@ -0,0 +1,216 @@ +CC_FLAGS = -Wall -I../sylv/cc -I../tl/cc -I../kord -I../integ/cc -I.. \ + $(CC_INCLUDE_PATH) + +LDFLAGS = -llapack -lcblas -lf77blas -latlas -lg2c -lstdc++ -lcygwin +DYNVERSION = 1.3.7 +tmpdir = /tmp/aaabbb123321 +pthreadGC2 = `which pthreadGC2.dll` +mingwm10 = `which mingwm10.dll` + +ifeq ($(CC),) + CC := gcc +endif + +ifneq ($(LD_LIBRARY_PATH),) # use LD_LIBRARY_PATH from environment +# LDFLAGS := -Wl,--library-path $(LD_LIBRARY_PATH) $(LDFLAGS) + LDFLAGS := -Wl,--library-path $(LD_LIBRARY_LIST) $(LDFLAGS) +# LDFLAGS := $(LD_LIBRARY_LIST) $(LDFLAGS) +endif + +ifeq ($(DEBUG),yes) + CC_FLAGS := $(CC_FLAGS) -g -DTL_DEBUG=2 +else + CC_FLAGS := $(CC_FLAGS) -O3 -DPOSIX_THREADS +endif + +ifeq ($(OS),Windows_NT) + CC_FLAGS := -mno-cygwin -mthreads $(CC_FLAGS) + LDFLAGS := -mno-cygwin -mthreads $(LDFLAGS) -lpthreadGC2 + ARCH := w32 + MEX_SUFFIX = dll +else + LDFLAGS := $(LDFLAGS) -lpthread + ARCH := linux + MEX_SUFFIX = mexglx +endif + +sylvcppsource := $(wildcard ../sylv/cc/*.cpp) +sylvhsource := $(wildcard ../sylv/cc/*.h) +sylvobjects := $(patsubst %.cpp, %.o, $(sylvcppsource)) + +tlcwebsource := $(wildcard ../tl/cc/*.cweb) +tlcppsource := $(patsubst %.cweb,%.cpp,$(tlcwebsource)) +tlhwebsource := $(wildcard ../tl/cc/*.hweb) +tlhsource := $(patsubst %.hweb,%.h,$(tlhwebsource)) +tlobjects := $(patsubst %.cweb,%.o,$(tlcwebsource)) + +kordcwebsource := $(wildcard ../kord/*.cweb) +kordcppsource := $(patsubst %.cweb,%.cpp,$(kordcwebsource)) +kordhwebsource := $(wildcard ../kord/*.hweb) +kordhsource := $(patsubst %.hweb,%.h,$(kordhwebsource)) +kordobjects := $(patsubst %.cweb,%.o,$(kordcwebsource)) + +integcwebsource := $(wildcard ../integ/cc/*.cweb) +integcppsource := $(patsubst %.cweb,%.cpp,$(integcwebsource)) +integhwebsource := $(wildcard ../integ/cc/*.hweb) +integhsource := $(patsubst %.hweb,%.h,$(integhwebsource)) +integobjects := $(patsubst %.cweb,%.o,$(integcwebsource)) + +parserhsource := $(wildcard ../parser/cc/*.h) +parsercppsource := $(wildcard ../parser/cc/*.cpp) + +utilshsource := $(wildcard ../utils/cc/*.h) +utilscppsource := $(wildcard ../utils/cc/*.cpp) + +cppsource := $(wildcard *.cpp) $(patsubst %.y,%_ll.cc,$(wildcard *.y)) $(patsubst %.lex,%_tab.cc,$(wildcard *.lex)) +hsource := $(wildcard *.h) $(patsubst %.lex,%_tab.hh,$(wildcard *.lex)) +objects := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) $(patsubst %.y,%_ll.o,$(wildcard *.y)) $(patsubst %.lex,%_tab.o,$(wildcard *.lex)) + +all: dynare++ + +../tl/cc/dummy.ch: + make -C ../tl/cc dummy.ch + +../tl/cc/%.cpp: ../tl/cc/%.cweb ../tl/cc/dummy.ch + make -C ../tl/cc $*.cpp + +../tl/cc/%.h: ../tl/cc/%.hweb ../tl/cc/dummy.ch + make -C ../tl/cc $*.h + +../tl/cc/%.o: ../tl/cc/%.cpp $(tlhsource) + make -C ../tl/cc $*.o + +../integ/cc/dummy.ch: + make -C ../integ/cc dummy.ch + +../integ/cc/%.cpp: ../integ/cc/%.cweb ../integ/cc/dummy.ch + make -C ../integ/cc $*.cpp + +../integ/cc/%.h: ../integ/cc/%.hweb ../integ/cc/dummy.ch + make -C ../integ/cc $*.h + +../integ/cc/%.o: ../integ/cc/%.cpp $(integhsource) $(tlhsource) + make -C ../integ/cc $*.o + + +../sylv/cc/%.o: ../sylv/cc/%.cpp $(sylvhsource) + make -C ../sylv/cc $*.o + +../kord/dummy.ch: + make -C ../kord dummy.ch + +../kord/%.cpp: ../kord/%.cweb ../kord/dummy.ch + make -C ../kord $*.cpp + +../kord/%.h: ../kord/%.hweb ../kord/dummy.ch + make -C ../kord $*.h + +../kord/%.o: ../kord/%.cpp $(tlhsource) $(kordhsource) $(integhsource) + make -C ../kord $*.o + +# for some reason, the pattern rules didn't work here, so the rules +# are expanded: +dynglob_tab.cc: dynglob.y dynare_atoms.h dynare_model.h + bison -d -t --verbose -odynglob_tab.cc dynglob.y + +dynglob_tab.hh: dynglob.y dynare_atoms.h dynare_model.h + bison -d -t --verbose -odynglob_tab.cc dynglob.y + +dynglob_ll.cc: dynglob.lex dynglob_tab.hh + flex -i -odynglob_ll.cc dynglob.lex + +dynglob_ll.o: dynglob_ll.cc $(hsource) + $(CC) -I.. -I../sylv/cc -I../tl/cc -O3 -c dynglob_ll.cc + +dynglob_tab.o: dynglob_tab.cc $(hsource) + $(CC) -I.. -I../sylv/cc -I../tl/cc -O3 -c dynglob_tab.cc + +%.o: %.cpp $(hsource) $(kordhsource) $(tlhsource) $(sylvhsource) $(parserhsource) + $(CC) $(CC_FLAGS) -DDYNVERSION=\"$(DYNVERSION)\" -o $*.o -c $*.cpp + +../parser/cc/parser.a: $(parserhsource) $(parsercppsource) + make -C ../parser/cc parser.a + +../utils/cc/utils.a: $(utilshsource) $(utilscppsource) + make -C ../utils/cc utils.a + +dynare++: $(tlhwebsource) $(tlcwebsoure) $(tlhsource) $(tlcppsource) \ + $(integhwebsource) $(integcwebsoure) $(integhsource) $(integcppsource) \ + $(kordhwebsource) $(kordcwebsoure) $(kordhsource) $(kordcppsource) \ + $(sylvhsource) $(sylvcppsource) \ + $(kordobjects) $(tlobjects) $(integobjects) $(sylvobjects) $(objects) \ + ../parser/cc/parser.a ../utils/cc/utils.a + $(CC) -g -o dynare++ $(objects) $(kordobjects) $(integobjects) $(tlobjects) ../parser/cc/parser.a ../utils/cc/utils.a $(sylvobjects) $(LDFLAGS) + +../extern/matlab/dynare_simul_.$(MEX_SUFFIX): + make -C ../extern/matlab all + +srcball: + rm -rf $(tmpdir) + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/tests + cp ../tests/*.mod ../tests/*.dyn $(tmpdir)/dynare++-$(DYNVERSION)/tests + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/src + cp *.h *.cpp *.y *.lex Makefile $(tmpdir)/dynare++-$(DYNVERSION)/src + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/tl/cc + cp ../tl/cc/*web ../tl/cc/Makefile $(tmpdir)/dynare++-$(DYNVERSION)/tl/cc + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/tl/testing + cp ../tl/testing/*.cpp ../tl/testing/*.h ../tl/testing/Makefile $(tmpdir)/dynare++-$(DYNVERSION)/tl/testing + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/integ/cc + cp ../integ/cc/*web ../integ/cc/Makefile ../integ/cc/*.dat $(tmpdir)/dynare++-$(DYNVERSION)/integ/cc + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/integ/testing + cp ../integ/testing/*.cpp ../integ/testing/Makefile $(tmpdir)/dynare++-$(DYNVERSION)/integ/testing + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/sylv/cc + cp ../sylv/cc/*.cpp ../sylv/cc/*.h ../sylv/cc/Makefile $(tmpdir)/dynare++-$(DYNVERSION)/sylv/cc + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/sylv/testing + cp ../sylv/testing/*.cpp ../sylv/testing/*.h ../sylv/testing/Makefile $(tmpdir)/dynare++-$(DYNVERSION)/sylv/testing + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/kord + cp ../kord/*web ../kord/Makefile ../kord/tests.cpp $(tmpdir)/dynare++-$(DYNVERSION)/kord + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/parser/cc + cp ../parser/cc/*.cpp ../parser/cc/*.h ../parser/cc/*.lex ../parser/cc/*.y ../parser/cc/Makefile $(tmpdir)/dynare++-$(DYNVERSION)/parser/cc + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/utils/cc + cp ../utils/cc/*.cpp ../utils/cc/*.h ../utils/cc/Makefile $(tmpdir)/dynare++-$(DYNVERSION)/utils/cc + + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/extern/matlab + cp ../extern/matlab/*.cpp ../extern/matlab/*.m ../extern/matlab/Makefile ../extern/matlab/*.bat $(tmpdir)/dynare++-$(DYNVERSION)/extern/matlab + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/doc + cp ../doc/*.tex $(tmpdir)/dynare++-$(DYNVERSION)/doc + cp ../change_log.html $(tmpdir)/dynare++-$(DYNVERSION)/ + cd $(tmpdir); tar czf dynare++-$(DYNVERSION).src.tgz dynare++-$(DYNVERSION)/* + mv $(tmpdir)/dynare++-$(DYNVERSION).src.tgz .. + rm -rf $(tmpdir) + +binball: dynare++ ../extern/matlab/dynare_simul_.$(MEX_SUFFIX) + rm -rf $(tmpdir) + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/tests + cp ../tests/*.mod ../tests/*.dyn $(tmpdir)/dynare++-$(DYNVERSION)/tests + mkdir -p $(tmpdir)/dynare++-$(DYNVERSION)/doc + cp ../doc/*.pdf $(tmpdir)/dynare++-$(DYNVERSION)/doc + cp dynare++* $(tmpdir)/dynare++-$(DYNVERSION) + cp ../extern/matlab/*.m $(tmpdir)/dynare++-$(DYNVERSION) + cp ../extern/matlab/dynare_simul_.$(MEX_SUFFIX) $(tmpdir)/dynare++-$(DYNVERSION) + cp ../change_log.html $(tmpdir)/dynare++-$(DYNVERSION) +ifeq ($(OS),Windows_NT) + cp $(pthreadGC2) $(tmpdir)/dynare++-$(DYNVERSION) + cp $(mingwm10) $(tmpdir)/dynare++-$(DYNVERSION) + cd $(tmpdir); zip -r dynare++-$(DYNVERSION)-$(ARCH).ix86.zip dynare++-$(DYNVERSION)/* + mv $(tmpdir)/dynare++-$(DYNVERSION)-$(ARCH).ix86.zip .. +else + cd $(tmpdir); tar czf dynare++-$(DYNVERSION)-$(ARCH).ix86.tgz dynare++-$(DYNVERSION)/* + mv $(tmpdir)/dynare++-$(DYNVERSION)-$(ARCH).ix86.tgz .. +endif + rm -rf $(tmpdir) + + +clear: + rm -f *.o + rm -f dynare++* + rm -f *_ll.cc *_tab.hh *_tab.cc *.output + make -C ../tl/testing clear + make -C ../tl/cc clear + make -C ../integ/testing clear + make -C ../integ/cc clear + make -C ../sylv/testing clear + make -C ../sylv/cc clear + make -C ../kord clear + make -C ../parser/cc clear + make -C ../utils/cc clear diff --git a/mex/sources/korderpert/Dyn_pp/src/dynare_exception.h b/mex/sources/korderpert/Dyn_pp/src/dynare_exception.h new file mode 100644 index 000000000..c91048a3a --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/src/dynare_exception.h @@ -0,0 +1,41 @@ +// Copyright (C) 2006, Ondra Kamenik + +// $Id: dynare_exception.h 853 2006-08-01 08:42:42Z kamenik $ + +#ifndef DYNARE_EXCEPTION_H +#define DYNARE_EXCEPTION_H + +#include + +class DynareException { + char* mes; +public: + DynareException(const char* m, const char* fname, int line, int col) + { + mes = new char[strlen(m) + strlen(fname) + 100]; + sprintf(mes, "Parse error at %s, line %d, column %d: %s", fname, line, col, m); + } + DynareException(const char* fname, int line, const std::string& m) + { + mes = new char[m.size() + strlen(fname) + 50]; + sprintf(mes, "%s:%d: %s", fname, line, m.c_str()); + } + DynareException(const char* m, int offset) + { + mes = new char[strlen(m) + 100]; + sprintf(mes, "Parse error in provided string at offset %d: %s", offset, m); + } + DynareException(const DynareException& e) + : mes(new char[strlen(e.mes)+1]) + {strcpy(mes, e.mes);} + virtual ~DynareException() + {delete [] mes;} + const char* message() const + {return mes;} +}; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/src/dynare_params.cpp b/mex/sources/korderpert/Dyn_pp/src/dynare_params.cpp new file mode 100644 index 000000000..407e1c4a2 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/src/dynare_params.cpp @@ -0,0 +1,245 @@ +// $Id: dynare_params.cpp 1520 2008-01-02 14:46:44Z kamenik $ +//Copyright 2004, Ondra Kamenik + +#include "dynare_params.h" + +#include +#include +#include + +const char* help_str = +"usage: dynare++ [--help] [--version] [options] \n" +"\n" +" --help print this message and return\n" +" --version print version and return\n" +"\n" +"options:\n" +" --per number of periods simulated [100]\n" +" --sim number of simulations [80]\n" +" --rtper number of RT periods simulated [0]\n" +" --rtsim number of RT simulations [0]\n" +" --condper number of periods in cond. simulations [0]\n" +" --condsim number of conditional simulations [0]\n" +" --steps steps towards stoch. SS [0=deter.]\n" +" --prefix prefix of variables in Mat-4 file [\"dyn\"]\n" +" --seed random number generator seed [934098]\n" +" --order order of approximation [no default]\n" +" --threads number of max parallel threads [2]\n" +" --ss-tol steady state calcs tolerance [1.e-13]\n" +" --check pesPES check model residuals [no checks]\n" +" lower/upper case switches off/on\n" +" pP checking along simulation path\n" +" eE checking on ellipse\n" +" sS checking along shocks\n" +" --check-evals max number of evals per residual [1000]\n" +" --check-num number of checked points [10]\n" +" --check-scale scaling of checked points [2.0]\n" +" --no-irfs shuts down IRF simulations [do IRFs]\n" +" --irfs performs IRF simulations [do IRFs]\n" +"\n\n"; + +// returns the pointer to the first character after the last slash or +// backslash in the string +const char* dyn_basename(const char* str); + +DynareParams::DynareParams(int argc, char** argv) + : modname(NULL), num_per(100), num_sim(80), + num_rtper(0), num_rtsim(0), + num_condper(0), num_condsim(0), + num_threads(2), num_steps(0), + prefix("dyn"), seed(934098), order(-1), ss_tol(1.e-13), + check_along_path(false), check_along_shocks(false), + check_on_ellipse(false), check_evals(1000), check_num(10), check_scale(2.0), + do_irfs_all(true), help(false), version(false) +{ + if (argc == 1 || !strcmp(argv[1],"--help")) { + help = true; + return; + } + if (argc == 1 || !strcmp(argv[1],"--version")) { + version = true; + return; + } + + modname = argv[argc-1]; + argc--; + + struct option const opts [] = { + {"periods", required_argument, NULL, opt_per}, + {"per", required_argument, NULL, opt_per}, + {"simulations", required_argument, NULL, opt_sim}, + {"sim", required_argument, NULL, opt_sim}, + {"rtperiods", required_argument, NULL, opt_rtper}, + {"rtper", required_argument, NULL, opt_rtper}, + {"rtsimulations", required_argument, NULL, opt_rtsim}, + {"rtsim", required_argument, NULL, opt_rtsim}, + {"condperiods", required_argument, NULL, opt_condper}, + {"condper", required_argument, NULL, opt_condper}, + {"condsimulations", required_argument, NULL, opt_condsim}, + {"condsim", required_argument, NULL, opt_condsim}, + {"prefix", required_argument, NULL, opt_prefix}, + {"threads", required_argument, NULL, opt_threads}, + {"steps", required_argument, NULL, opt_steps}, + {"seed", required_argument, NULL, opt_seed}, + {"order", required_argument, NULL, opt_order}, + {"ss-tol", required_argument, NULL, opt_ss_tol}, + {"check", required_argument, NULL, opt_check}, + {"check-scale", required_argument, NULL, opt_check_scale}, + {"check-evals", required_argument, NULL, opt_check_evals}, + {"check-num", required_argument, NULL, opt_check_num}, + {"no-irfs", no_argument, NULL, opt_noirfs}, + {"irfs", no_argument, NULL, opt_irfs}, + {"help", no_argument, NULL, opt_help}, + {"version", no_argument, NULL, opt_version}, + {NULL, 0, NULL, 0} + }; + + int ret; + int index; + while (-1 != (ret = getopt_long(argc, argv, "", opts, &index))) { + switch (ret) { + case opt_per: + if (1 != sscanf(optarg, "%d", &num_per)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_sim: + if (1 != sscanf(optarg, "%d", &num_sim)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_rtper: + if (1 != sscanf(optarg, "%d", &num_rtper)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_rtsim: + if (1 != sscanf(optarg, "%d", &num_rtsim)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_condper: + if (1 != sscanf(optarg, "%d", &num_condper)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_condsim: + if (1 != sscanf(optarg, "%d", &num_condsim)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_prefix: + prefix = optarg; + break; + case opt_threads: + if (1 != sscanf(optarg, "%d", &num_threads)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_steps: + if (1 != sscanf(optarg, "%d", &num_steps)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_seed: + if (1 != sscanf(optarg, "%d", &seed)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_order: + if (1 != sscanf(optarg, "%d", &order)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_ss_tol: + if (1 != sscanf(optarg, "%lf", &ss_tol)) + fprintf(stderr, "Couldn't parse float %s, ignored\n", optarg); + break; + case opt_check: + processCheckFlags(optarg); + break; + case opt_check_scale: + if (1 != sscanf(optarg, "%lf", &check_scale)) + fprintf(stderr, "Couldn't parse float %s, ignored\n", optarg); + break; + case opt_check_evals: + if (1 != sscanf(optarg, "%d", &check_evals)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_check_num: + if (1 != sscanf(optarg, "%d", &check_num)) + fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg); + break; + case opt_noirfs: + irf_list.clear(); + do_irfs_all = false; + break; + case opt_irfs: + processIRFList(argc, argv); + if (irf_list.empty()) + do_irfs_all = true; + else + do_irfs_all = false; + break; + case opt_help: + help = true; + break; + case opt_version: + version = true; + break; + case '?': + fprintf(stderr, "Unknown option, ignored\n"); + break; + } + } + + // make basename (get rid of the extension) + basename = dyn_basename(modname); + std::string::size_type i = basename.rfind('.'); + if (i != std::string::npos) + basename.erase(i); +} + +void DynareParams::printHelp() const +{ + printf("%s", help_str); +} + +void DynareParams::processCheckFlags(const char* flags) +{ + for (unsigned int i = 0; i < strlen(flags); i++) { + switch (flags[i]) { + case 'p': + check_along_path = false; + break; + case 'P': + check_along_path = true; + break; + case 'e': + check_on_ellipse = false; + break; + case 'E': + check_on_ellipse = true; + break; + case 's': + check_along_shocks = false; + break; + case 'S': + check_along_shocks = true; + break; + default: + fprintf(stderr, "Unknown check type selection character <%c>, ignored.\n", flags[i]); + } + } +} + +void DynareParams::processIRFList(int argc, char** argv) +{ + irf_list.clear(); + while (optind < argc && *(argv[optind]) != '-') { + irf_list.push_back(argv[optind]); + optind++; + } +} + +const char* dyn_basename(const char* str) +{ + int i = strlen(str); + while (i > 0 && str[i-1] != '/' && str[i-1] != '\\') + i--; + return str+i; +} + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/src/dynare_params.h b/mex/sources/korderpert/Dyn_pp/src/dynare_params.h new file mode 100644 index 000000000..9bbecc3b8 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/src/dynare_params.h @@ -0,0 +1,71 @@ +// $Id: dynare_params.h 1520 2008-01-02 14:46:44Z kamenik $ + +// Copyright 2004, Ondra Kamenik + +/* +along shocks: m mult max_evals +ellipse: m mult max_evals (10*m) (0.5*mult) +simul: m max_evals (10*m) + +--check-scale 2.0 --check-evals 1000 --check-num 10 --check PES + */ + +#include +#include + +struct DynareParams { + const char* modname; + std::string basename; + int num_per; + int num_sim; + int num_rtper; + int num_rtsim; + int num_condper; + int num_condsim; + int num_threads; + int num_steps; + const char* prefix; + int seed; + int order; + /** Tolerance used for steady state calcs. */ + double ss_tol; + bool check_along_path; + bool check_along_shocks; + bool check_on_ellipse; + int check_evals; + int check_num; + double check_scale; + /** Flag for doing IRFs even if the irf_list is empty. */ + bool do_irfs_all; + /** List of shocks for which IRF will be calculated. */ + std::vector irf_list; + bool help; + bool version; + DynareParams(int argc, char** argv); + void printHelp() const; + int getCheckShockPoints() const + {return check_num;} + double getCheckShockScale() const + {return check_scale;} + int getCheckEllipsePoints() const + {return 10*check_num;} + double getCheckEllipseScale() const + {return 0.5*check_scale;} + int getCheckPathPoints() const + {return 10*check_num;} +private: + enum {opt_per, opt_sim, opt_rtper, opt_rtsim, opt_condper, opt_condsim, opt_prefix, opt_threads, + opt_steps, opt_seed, opt_order, opt_ss_tol, opt_check, + opt_check_along_path, opt_check_along_shocks, opt_check_on_ellipse, + opt_check_evals, opt_check_scale, opt_check_num, opt_noirfs, opt_irfs, + opt_help, opt_version}; + void processCheckFlags(const char* flags); + /** This gathers strings from argv[optind] and on not starting + * with '-' to the irf_list. It stops one item before the end, + * since this is the model file. */ + void processIRFList(int argc, char** argv); +}; + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/src/forw_subst_builder.cpp b/mex/sources/korderpert/Dyn_pp/src/forw_subst_builder.cpp new file mode 100644 index 000000000..430245e1c --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/src/forw_subst_builder.cpp @@ -0,0 +1,122 @@ +// Copyright (C) 2006, Ondra Kamenik + +// $Id$ + +#include "forw_subst_builder.h" + +using namespace ogdyn; + +ForwSubstBuilder::ForwSubstBuilder(DynareModel& m) + : model(m) +{ + info.num_new_terms -= model.getParser().getTree().get_num_op(); + + // go through all equations + int neq = model.eqs.nformulas(); + for (int i = 0; i < neq; i++) { + int ft = model.eqs.formula(i); + int mlead, mlag; + model.termspan(ft, mlead, mlag); + // if equation is too forward looking + if (mlead > 1) { + info.num_affected_equations++; + // break it to non-linear terms + hash_set nlt = model.get_nonlinear_subterms(ft); + int j = 0; // indexes subterms + // and make substitutions for all these non-linear subterms + for (hash_set::const_iterator it = nlt.begin(); + it != nlt.end(); ++it, ++j) + substitute_for_term(*it, i, j); + } + } + // unassign all variables with lead greater than 1 + unassign_gt_1_leads(); + + // forget the derivatives in the tree because some variables could + // have been unassigned + model.eqs.getTree().forget_derivative_maps(); + + info.num_new_terms += model.getParser().getTree().get_num_op(); +} + +void ForwSubstBuilder::substitute_for_term(int t, int i, int j) +{ + int mlead, mlag; + model.termspan(t, mlead, mlag); + if (mlead > 1) { + info.num_subst_terms++; + // Example for comments: let t = f(x(+4)) + // first make lagsubst be substitution setting f(x(+4)) to f(x(+1)) + // this is lag = -3 (1-mlead) + map lagsubst; + model.variable_shift_map(model.eqs.nulary_of_term(t), 1-mlead, lagsubst); + int lagt = model.eqs.add_substitution(t, lagsubst); + // now maxlead of lagt is +1 + // add AUXLD_*_*_1 = f(x(+1)) to the model + char name[100]; + sprintf(name, "AUXLD_%d_%d_%d", i, j, 1); + model.atoms.register_uniq_endo(name); + info.num_aux_variables++; + const char* ss = model.atoms.get_name_storage().query(name); + int auxt = model.eqs.add_nulary(name); + model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lagt)); + aux_map.insert(Tsubstmap::value_type(ss, lagt)); + // now add variables and equations + // AUXLD_*_*_2 = AUXLD_*_*_1(+1) through + // AUXLD_*_*_{mlead-1} = AUXLD_*_*_{mlead-2}(+1) + for (int ll = 1; ll <= mlead-2; ll++) { + // create AUXLD_*_*_{ll}(+1) + sprintf(name, "AUXLD_%d_%d_%d(+1)", i, j, ll); + int lastauxt_lead = model.eqs.add_nulary(name); + // create AUXLD_*_*{ll+1} + sprintf(name, "AUXLD_%d_%d_%d", i, j, ll+1); + model.atoms.register_uniq_endo(name); + info.num_aux_variables++; + ss = model.atoms.get_name_storage().query(name); + auxt = model.eqs.add_nulary(name); + // add AUXLD_*_*_{ll+1} = AUXLD_*_*_{ll}(+1) + model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lastauxt_lead)); + // add substitution to the map; todo: this + // works well because in the context where + // aux_map is used the timing doesn't matter, + // however, it is misleading, needs to be + // changed + aux_map.insert(Tsubstmap::value_type(ss, lagt)); + } + + // now we have to substitute AUXLEAD_*_*{mlead-1}(+1) for t + model.substitute_atom_for_term(ss, +1, t); + } +} + +void ForwSubstBuilder::unassign_gt_1_leads(const char* name) +{ + const char* ss = model.atoms.get_name_storage().query(name); + int mlead, mlag; + model.atoms.varspan(name, mlead, mlag); + for (int ll = 2; ll <= mlead; ll++) { + int t = model.atoms.index(ss, ll); + if (t != -1) + model.atoms.unassign_variable(ss, ll, t); + } +} + +void ForwSubstBuilder::unassign_gt_1_leads() +{ + const vector& endovars = model.atoms.get_endovars(); + for (unsigned int i = 0; i < endovars.size(); i++) + unassign_gt_1_leads(endovars[i]); + const vector& exovars = model.atoms.get_exovars(); + for (unsigned int i = 0; i < exovars.size(); i++) + unassign_gt_1_leads(exovars[i]); +} + +ForwSubstBuilder::ForwSubstBuilder(const ForwSubstBuilder& b, DynareModel& m) + : model(m) +{ + for (Tsubstmap::const_iterator it = b.aux_map.begin(); + it != b.aux_map.end(); ++it) { + const char* ss = m.atoms.get_name_storage().query((*it).first); + aux_map.insert(Tsubstmap::value_type(ss, (*it).second)); + } +} diff --git a/mex/sources/korderpert/Dyn_pp/src/forw_subst_builder.h b/mex/sources/korderpert/Dyn_pp/src/forw_subst_builder.h new file mode 100644 index 000000000..7f703092d --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/src/forw_subst_builder.h @@ -0,0 +1,83 @@ +// Copyright (C) 2006, Ondra Kamenik + +// $Id$ + +#ifndef FORW_SUBST_BUILDER_H +#define FORW_SUBST_BUILDER_H + + +#include "dynare_model.h" + +namespace ogdyn { + + /** This struct encapsulates information about the process of + * forward substitutions. */ + struct ForwSubstInfo { + int num_affected_equations; + int num_subst_terms; + int num_aux_variables; + int num_new_terms; + ForwSubstInfo() + : num_affected_equations(0), + num_subst_terms(0), + num_aux_variables(0), + num_new_terms(0) {} + }; + + class ForwSubstBuilder { + typedef map Ttermauxmap; + protected: + /** Reference to the model, to which we will add equations and + * change some equations. */ + DynareModel& model; + /** A map mapping new auxiliary variables to the terms in the + * tree in the DynareModel. */ + Tsubstmap aux_map; + /** Information about the substitutions. */ + ForwSubstInfo info; + public: + /** Do all the jobs needed. This scans all equations in the + * model, and for equations containing forward looking + * variables greater than 1 lead, it makes corresponding + * substitutions. Basically, it breaks each equation to its + * non-linear components and creates substitutions for these + * components, not for whole equation. This is because the + * expectation operator can go through the linear part of the + * function. This will save us many occurrences of other + * variables involved in the equation. */ + ForwSubstBuilder(DynareModel& m); + /** Copy constructor with a new instance of the model. */ + ForwSubstBuilder(const ForwSubstBuilder& b, DynareModel& m); + /** Return the auxiliary variable mapping. */ + const Tsubstmap& get_aux_map() const + {return aux_map;} + /** Return the information. */ + const ForwSubstInfo& get_info() const + {return info;} + private: + ForwSubstBuilder(const ForwSubstBuilder& b); + /** This method takes a nonlinear term t, and if it has leads + * of greater than 1, then it substitutes the term for the new + * variable (or string of variables). Note that the + * substitution is done by DynamicAtoms::assign_variable. This + * means that the substitution is made for all other + * ocurrences of t in the model. So there is no need of + * tracking already substituted terms. The other two + * parameters are just for identification of the new auxiliary + * variables. When called from the constructor, i is an + * equation number, j is an order of the non-linear term in + * the equation. */ + void substitute_for_term(int t, int i, int j); + /** This is called just at the end of the job. It unassigns + * all nulary terms with a lead greater than 1. */ + void unassign_gt_1_leads(); + /** This unassigns all leads greater than 1 of the given name. */ + void unassign_gt_1_leads(const char* name); + }; +}; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/src/nlsolve.cpp b/mex/sources/korderpert/Dyn_pp/src/nlsolve.cpp new file mode 100644 index 000000000..c335d8fde --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/src/nlsolve.cpp @@ -0,0 +1,230 @@ +// Copyright (C) 2006, Ondra Kamenik + +// $Id: nlsolve.cpp 762 2006-05-22 13:00:07Z kamenik $ + +#include "nlsolve.h" +#include "dynare_exception.h" + +#include + +using namespace ogu; + +/** This should not be greater than DBL_EPSILON^(1/2). */ +double GoldenSectionSearch::tol = 1.e-4; + +/** This is equal to the golden section ratio. */ +double GoldenSectionSearch::golden = (3.-std::sqrt(5.))/2; + +double GoldenSectionSearch::search(OneDFunction& f, double x1, double x2) +{ + double b; + if (init_bracket(f, x1, x2, b)) { + double fb = f.eval(b); + double f1 = f.eval(x1); + double f2 = f.eval(x2); + double dx; + do { + double w = (b-x1)/(x2-x1); + dx = std::abs((1-2*w)*(x2-x1)); + double x; + if (b-x1 > x2-b) + x = b - dx; + else + x = b + dx; + double fx = f.eval(x); + if (! std::isfinite(fx)) + return x1; + if (b-x1 > x2-b) { + // x is on the left from b + if (f1 > fx && fx < fb) { + // pickup bracket [f1,fx,fb] + f2 = fb; + x2 = b; + fb = fx; + b = x; + } else { + // pickup bracket [fx,fb,fx2] + f1 = fx; + x1 = x; + } + } else { + // x is on the right from b + if (f1 > fb && fb < fx) { + // pickup bracket [f1,fb,fx] + f2 = fx; + x2 = x; + } else { + // pickup bracket [fb,fx,f2] + f1 = fb; + x1 = b; + fb = fx; + b = x; + } + } + } while(dx > tol); + } + return b; +} + +bool GoldenSectionSearch::init_bracket(OneDFunction& f, double x1, double& x2, double& b) +{ + double f1 = f.eval(x1); + if (! std::isfinite(f1)) + throw DynareException(__FILE__, __LINE__, + "Safer point not finite in GoldenSectionSearch::init_bracket"); + + int cnt = 0; + bool bracket_found = false; + do { + bool finite_found = search_for_finite(f, x1, x2, b); + if (! finite_found) { + b = x1; + return false; + } + double f2 = f.eval(x2); + double fb = f.eval(b); + double bsym = 2*x2 - b; + double fbsym = f.eval(bsym); + // now we know that f1, f2, and fb are finite + if (std::isfinite(fbsym)) { + // we have four numbers f1, fb, f2, fbsym, we test for the + // following combinations to find the bracket: + // [f1,f2,fbsym], [f1,fb,fbsym] and [f1,fb,fbsym] + if (f1 > f2 && f2 < fbsym) { + bracket_found = true; + b = x2; + x2 = bsym; + } else if (f1 > fb && fb < fbsym) { + bracket_found = true; + x2 = bsym; + } else if (f1 > fb && fb < f2) { + bracket_found = true; + } else { + double newx2 = b; + // choose the smallest value in case we end + if (f1 > fbsym) { + // the smallest value is on the other end, we do + // not want to continue + b = bsym; + return false; + } else + b = x1; + // move x2 to b in case we continue + x2 = newx2; + } + } else { + // we have only three numbers, we test for the bracket, + // and if not found, we set b as potential result and + // shorten x2 as potential init value for next cycle + if (f1 > fb && fb < f2) + bracket_found = true; + else { + double newx2 = b; + // choose the smaller value in case we end + if (f1 > f2) + b = x2; + else + b = x1; + // move x2 to b in case we continue + x2 = newx2; + } + } + cnt++; + } while (! bracket_found && cnt < 5); + + return bracket_found; +} + +/** This moves x2 toward to x1 until the function at x2 is finite and + * b as a golden section between x1 and x2 yields also finite f. */ +bool GoldenSectionSearch::search_for_finite(OneDFunction& f, double x1, double& x2, double&b) +{ + int cnt = 0; + bool found = false; + do { + double f2 = f.eval(x2); + b = (1-golden)*x1 + golden*x2; + double fb = f.eval(b); + found = std::isfinite(f2) && std::isfinite(fb); + if (! found) + x2 = b; + cnt++; + } while (! found && cnt < 5); + + return found; +} + +void VectorFunction::check_for_eval(const ConstVector& in, Vector& out) const +{ + if (inDim() != in.length() || outDim() != out.length()) + throw DynareException(__FILE__, __LINE__, + "Wrong dimensions in VectorFunction::check_for_eval"); +} + +double NLSolver::eval(double lambda) +{ + Vector xx((const Vector&)x); + xx.add(1-lambda, xcauchy); + xx.add(lambda, xnewton); + Vector ff(func.outDim()); + func.eval(xx, ff); + return ff.dot(ff); +} + +bool NLSolver::solve(Vector& xx, int& iter) +{ + JournalRecord rec(journal); + rec << "Iter lambda residual" << endrec; + JournalRecord rec1(journal); + rec1 << "---------------------------" << endrec; + char tmpbuf[14]; + + x = (const Vector&)xx; + iter = 0; + // setup fx + Vector fx(func.outDim()); + func.eval(x, fx); + if (!fx.isFinite()) + throw DynareException(__FILE__,__LINE__, + "Initial guess does not yield finite residual in NLSolver::solve"); + bool converged = fx.getMax() < tol; + JournalRecord rec2(journal); + sprintf(tmpbuf, "%10.6g", fx.getMax()); + rec2 << iter << " N/A " << tmpbuf << endrec; + while (! converged && iter < max_iter) { + // setup Jacobian + jacob.eval(x); + // calculate cauchy step + Vector g(func.inDim()); + g.zeros(); + ConstTwoDMatrix(jacob).multaVecTrans(g, fx); + Vector Jg(func.inDim()); + Jg.zeros(); + ConstTwoDMatrix(jacob).multaVec(Jg, g); + double m = -g.dot(g)/Jg.dot(Jg); + xcauchy = (const Vector&) g; + xcauchy.mult(m); + // calculate newton step + xnewton = (const Vector&) fx; + ConstTwoDMatrix(jacob).multInvLeft(xnewton); + xnewton.mult(-1); + + // line search + double lambda = GoldenSectionSearch::search(*this, 0, 1); + x.add(1-lambda, xcauchy); + x.add(lambda, xnewton); + // evaluate func + func.eval(x, fx); + converged = fx.getMax() < tol; + + // iter + iter++; + + JournalRecord rec3(journal); + sprintf(tmpbuf, "%10.6g", fx.getMax()); + rec3 << iter << " " << lambda << " " << tmpbuf << endrec; + } + xx = (const Vector&)x; + + return converged; +} diff --git a/mex/sources/korderpert/Dyn_pp/src/nlsolve.h b/mex/sources/korderpert/Dyn_pp/src/nlsolve.h new file mode 100644 index 000000000..0cd19b1f3 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/src/nlsolve.h @@ -0,0 +1,94 @@ +// Copyright (C) 2006, Ondra Kamenik + +// $Id: nlsolve.h 762 2006-05-22 13:00:07Z kamenik $ + +#ifndef OGU_NLSOLVE_H +#define OGU_NLSOLVE_H + +#include "twod_matrix.h" +#include "journal.h" + +namespace ogu { + + class OneDFunction { + public: + virtual ~OneDFunction() {} + virtual double eval(double) = 0; + }; + + class GoldenSectionSearch { + protected: + static double tol; + static double golden; + public: + static double search(OneDFunction& f, double x1, double x2); + protected: + /** This initializes a bracket by moving x2 and b (as a golden + * section of x1,x2) so that f(x1)>f(b) && f(b) +#include + +BlockDiagonal::BlockDiagonal(const double* d, int d_size) + : QuasiTriangular(d, d_size), + row_len(new int[d_size]), col_len(new int[d_size]) +{ + for (int i = 0; i < d_size; i++) { + row_len[i] = d_size; + col_len[i] = 0; + } +} + +BlockDiagonal::BlockDiagonal(const QuasiTriangular& t) + : QuasiTriangular(t), + row_len(new int[t.numRows()]), col_len(new int[t.numRows()]) +{ + for (int i = 0; i < t.numRows(); i++) { + row_len[i] = t.numRows(); + col_len[i] = 0; + } +} + +BlockDiagonal::BlockDiagonal(int p, const BlockDiagonal& b) + : QuasiTriangular(p, b), + row_len(new int[b.numRows()]), col_len(new int[b.numRows()]) +{ + memcpy(row_len, b.row_len, b.numRows()*sizeof(int)); + memcpy(col_len, b.col_len, b.numRows()*sizeof(int)); +} + +BlockDiagonal::BlockDiagonal(const BlockDiagonal& b) + : QuasiTriangular(b), + row_len(new int[b.numRows()]), col_len(new int[b.numRows()]) +{ + memcpy(row_len, b.row_len, b.numRows()*sizeof(int)); + memcpy(col_len, b.col_len, b.numRows()*sizeof(int)); +} + +/* put zeroes to right upper submatrix whose first column is defined + * by 'edge' */ +void BlockDiagonal::setZerosToRU(diag_iter edge) +{ + int iedge = (*edge).getIndex(); + for (int i = 0; i < iedge; i++) + for (int j = iedge; j < numCols(); j++) + get(i,j) = 0.0; +} + +/* Updates row_len and col_len so that there are zeroes in upper right part, this + * |T1 0 | + * |0 T2|. The first column of T2 is given by diagonal iterator 'edge'. + + * Note the semantics of row_len and col_len. row_len[i] is distance + * of the right-most non-zero element of i-th row from the left, and + * col_len[j] is distance of top-most non-zero element of j-th column + * to the top. (First element has distance 1). + */ +void BlockDiagonal::setZeroBlockEdge(diag_iter edge) +{ + setZerosToRU(edge); + + int iedge = (*edge).getIndex(); + for (diag_iter run = diag_begin(); run != edge; ++run) { + int ind = (*run).getIndex(); + if (row_len[ind] > iedge) { + row_len[ind] = iedge; + if (!(*run).isReal()) + row_len[ind+1] = iedge; + } + } + for (diag_iter run = edge; run != diag_end(); ++run) { + int ind = (*run).getIndex(); + if (col_len[ind] < iedge) { + col_len[ind] = iedge; + if (!(*run).isReal()) + col_len[ind+1] = iedge; + } + } +} + +BlockDiagonal::const_col_iter +BlockDiagonal::col_begin(const DiagonalBlock& b) const +{ + int jbar = b.getIndex(); + int d_size = diagonal.getSize(); + return const_col_iter(&getData()[jbar*d_size + col_len[jbar]], d_size, + b.isReal(), col_len[jbar]); +} + +BlockDiagonal::col_iter +BlockDiagonal::col_begin(const DiagonalBlock& b) +{ + int jbar = b.getIndex(); + int d_size = diagonal.getSize(); + return col_iter(&getData()[jbar*d_size + col_len[jbar]], d_size, + b.isReal(), col_len[jbar]); +} + + +BlockDiagonal::const_row_iter +BlockDiagonal::row_end(const DiagonalBlock& b) const +{ + int jbar = b.getIndex(); + int d_size = diagonal.getSize(); + return const_row_iter(&getData()[d_size*row_len[jbar]+jbar], d_size, + b.isReal(), row_len[jbar]); +} + +BlockDiagonal::row_iter +BlockDiagonal::row_end(const DiagonalBlock& b) +{ + int jbar = b.getIndex(); + int d_size = diagonal.getSize(); + return row_iter(&getData()[d_size*row_len[jbar]+jbar], d_size, + b.isReal(), row_len[jbar]); +} + +int BlockDiagonal::getNumZeros() const +{ + int sum = 0; + for (int i = 0; i < diagonal.getSize(); i++) { + sum += diagonal.getSize() - row_len[i]; + } + return sum; +} + +QuasiTriangular::const_diag_iter +BlockDiagonal::findBlockStart(const_diag_iter from) const +{ + if (from != diag_end()) { + ++from; + while (from != diag_end() && + col_len[(*from).getIndex()] != (*from).getIndex()) + ++from; + } + return from; +} + +int BlockDiagonal::getLargestBlock() const +{ + int largest = 0; + const_diag_iter start = diag_begin(); + const_diag_iter end = findBlockStart(start); + while (start != diag_end()) { + int si = (*start).getIndex(); + int ei = diagonal.getSize(); + if (end != diag_end()) + ei = (*end).getIndex(); + if (largest < ei-si) + largest = ei-si; + start = end; + end = findBlockStart(start); + } + return largest; +} + + +void BlockDiagonal::savePartOfX(int si, int ei, const KronVector& x, Vector& work) +{ + for (int i = si; i < ei; i++) { + ConstKronVector xi(x, i); + Vector target(work, (i-si)*xi.length(), xi.length()); + target = xi; + } +} + +void BlockDiagonal::multKronBlock(const_diag_iter start, const_diag_iter end, + KronVector& x, Vector& work) const +{ + int si = (*start).getIndex(); + int ei = diagonal.getSize(); + if (end != diag_end()) + ei = (*end).getIndex(); + savePartOfX(si, ei, x, work); + + for (const_diag_iter di = start; di != end; ++di) { + int jbar = (*di).getIndex(); + if ((*di).isReal()) { + KronVector xi(x, jbar); + xi.zeros(); + Vector wi(work, (jbar-si)*xi.length(), xi.length()); + xi.add(*((*di).getAlpha()), wi); + for (const_row_iter ri = row_begin(*di); ri != row_end(*di); ++ri) { + int col = ri.getCol(); + Vector wj(work, (col-si)*xi.length(), xi.length()); + xi.add(*ri, wj); + } + } else { + KronVector xi(x, jbar); + KronVector xii(x, jbar+1); + xi.zeros(); + xii.zeros(); + Vector wi(work, (jbar-si)*xi.length(), xi.length()); + Vector wii(work, (jbar+1-si)*xi.length(), xi.length()); + xi.add(*((*di).getAlpha()), wi); + xi.add((*di).getBeta1(), wii); + xii.add((*di).getBeta2(), wi); + xii.add(*((*di).getAlpha()), wii); + for (const_row_iter ri = row_begin(*di); ri != row_end(*di); ++ri) { + int col = ri.getCol(); + Vector wj(work, (col-si)*xi.length(), xi.length()); + xi.add(ri.a(), wj); + xii.add(ri.b(), wj); + } + } + } +} + +void BlockDiagonal::multKronBlockTrans(const_diag_iter start, const_diag_iter end, + KronVector& x, Vector& work) const +{ + int si = (*start).getIndex(); + int ei = diagonal.getSize(); + if (end != diag_end()) + ei = (*end).getIndex(); + savePartOfX(si, ei, x, work); + + for (const_diag_iter di = start; di != end; ++di) { + int jbar = (*di).getIndex(); + if ((*di).isReal()) { + KronVector xi(x, jbar); + xi.zeros(); + Vector wi(work, (jbar-si)*xi.length(), xi.length()); + xi.add(*((*di).getAlpha()), wi); + for (const_col_iter ci = col_begin(*di); ci != col_end(*di); ++ci) { + int row = ci.getRow(); + Vector wj(work, (row-si)*xi.length(), xi.length()); + xi.add(*ci, wj); + } + } else { + KronVector xi(x, jbar); + KronVector xii(x, jbar+1); + xi.zeros(); + xii.zeros(); + Vector wi(work, (jbar-si)*xi.length(), xi.length()); + Vector wii(work, (jbar+1-si)*xi.length(), xi.length()); + xi.add(*((*di).getAlpha()), wi); + xi.add((*di).getBeta2(), wii); + xii.add((*di).getBeta1(), wi); + xii.add(*((*di).getAlpha()), wii); + for (const_col_iter ci = col_begin(*di); ci != col_end(*di); ++ci) { + int row = ci.getRow(); + Vector wj(work, (row-si)*xi.length(), xi.length()); + xi.add(ci.a(), wj); + xii.add(ci.b(), wj); + } + } + } +} + +void BlockDiagonal::multKron(KronVector& x) const +{ + int largest = getLargestBlock(); + Vector work(largest*x.getN()*power(x.getM(),x.getDepth()-1)); + const_diag_iter start = diag_begin(); + const_diag_iter end = findBlockStart(start); + while (start != diag_end()) { + multKronBlock(start, end, x, work); + start = end; + end = findBlockStart(start); + } +} + + +void BlockDiagonal::multKronTrans(KronVector& x) const +{ + int largest = getLargestBlock(); + Vector work(largest*x.getN()*power(x.getM(),x.getDepth()-1)); + const_diag_iter start = diag_begin(); + const_diag_iter end = findBlockStart(start); + while (start != diag_end()) { + multKronBlockTrans(start, end, x, work); + start = end; + end = findBlockStart(start); + } +} + +void BlockDiagonal::printInfo() const +{ + printf("Block sizes:"); + int num_blocks = 0; + const_diag_iter start = diag_begin(); + const_diag_iter end = findBlockStart(start); + while (start != diag_end()) { + int si = (*start).getIndex(); + int ei = diagonal.getSize(); + if (end != diag_end()) + ei = (*end).getIndex(); + printf(" %d", ei-si); + num_blocks++; + start = end; + end = findBlockStart(start); + } + printf("\nNum blocks: %d\n", num_blocks); + printf("There are %d zeros out of %d\n", + getNumZeros(), getNumOffdiagonal()); +} + +int BlockDiagonal::getNumBlocks() const +{ + int num_blocks = 0; + const_diag_iter start = diag_begin(); + const_diag_iter end = findBlockStart(start); + while (start != diag_end()) { + num_blocks++; + start = end; + end = findBlockStart(start); + } + return num_blocks; +} + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/BlockDiagonal.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/BlockDiagonal.h new file mode 100644 index 000000000..c2b94313a --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/BlockDiagonal.h @@ -0,0 +1,53 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/BlockDiagonal.h,v 1.1.1.1 2004/06/04 13:00:20 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef BLOCK_DIAGONAL_H +#define BLOCK_DIAGONAL_H + +#include "QuasiTriangular.h" + + +class BlockDiagonal : public QuasiTriangular { + int* const row_len; + int* const col_len; +public: + BlockDiagonal(const double* d, int d_size); + BlockDiagonal(int p, const BlockDiagonal& b); + BlockDiagonal(const BlockDiagonal& b); + BlockDiagonal(const QuasiTriangular& t); + const BlockDiagonal& operator=(const QuasiTriangular& t) + {GeneralMatrix::operator=(t); return *this;} + const BlockDiagonal& operator=(const BlockDiagonal& b); + ~BlockDiagonal() {delete [] row_len; delete [] col_len;} + void setZeroBlockEdge(diag_iter edge); + int getNumZeros() const; + int getNumBlocks() const; + int getLargestBlock() const; + void printInfo() const; + + void multKron(KronVector& x) const; + void multKronTrans(KronVector& x) const; + + const_col_iter col_begin(const DiagonalBlock& b) const; + col_iter col_begin(const DiagonalBlock& b); + const_row_iter row_end(const DiagonalBlock& b) const; + row_iter row_end(const DiagonalBlock& b); + QuasiTriangular* clone() const + {return new BlockDiagonal(*this);} +private: + void setZerosToRU(diag_iter edge); + const_diag_iter findBlockStart(const_diag_iter from) const; + static void savePartOfX(int si, int ei, const KronVector& x, Vector& work); + void multKronBlock(const_diag_iter start, const_diag_iter end, + KronVector& x, Vector& work) const; + void multKronBlockTrans(const_diag_iter start, const_diag_iter end, + KronVector& x, Vector& work) const; +}; + +#endif /* BLOCK_DIAGONAL_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralMatrix.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralMatrix.cpp new file mode 100644 index 000000000..b9db8d0f8 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralMatrix.cpp @@ -0,0 +1,482 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/GeneralMatrix.cpp,v 1.4 2004/11/24 20:41:59 kamenik Exp $ */ + +/* Tag $Name: $ */ + + +#include "SylvException.h" +#include "GeneralMatrix.h" + +#include "cppblas.h" +#include "cpplapack.h" + +#include +#include +#include +#include +#include + +int GeneralMatrix::md_length = 32; + +GeneralMatrix::GeneralMatrix(const GeneralMatrix& m) + : data(m.rows*m.cols), rows(m.rows), cols(m.cols), ld(m.rows) +{ + copy(m); +} + +GeneralMatrix::GeneralMatrix(const ConstGeneralMatrix& m) + : data(m.rows*m.cols), rows(m.rows), cols(m.cols), ld(m.rows) +{ + copy(m); +} + +GeneralMatrix::GeneralMatrix(const GeneralMatrix& m, const char* dummy) + : data(m.rows*m.cols), rows(m.cols), cols(m.rows), ld(m.cols) +{ + for (int i = 0; i < m.rows; i++) + for (int j = 0; j < m.cols; j++) + get(j,i) = m.get(i,j); +} + +GeneralMatrix::GeneralMatrix(const ConstGeneralMatrix& m, const char* dummy) + : data(m.rows*m.cols), rows(m.cols), cols(m.rows), ld(m.cols) +{ + for (int i = 0; i < m.rows; i++) + for (int j = 0; j < m.cols; j++) + get(j,i) = m.get(i,j); +} + + +GeneralMatrix::GeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols) + : data(nrows*ncols), rows(nrows), cols(ncols), ld(nrows) +{ + copy(m, i, j); +} + +GeneralMatrix::GeneralMatrix(GeneralMatrix& m, int i, int j, int nrows, int ncols) + : data(m.base()+m.ld*j+i, m.ld*(ncols-1)+nrows), rows(nrows), cols(ncols), ld(m.ld) +{} + +GeneralMatrix::GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b) + : data(a.rows*b.cols), rows(a.rows), cols(b.cols), ld(a.rows) +{ + gemm("N", a, "N", b, 1.0, 0.0); +} + +GeneralMatrix::GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b, const char* dum) + : data(a.rows*b.rows), rows(a.rows), cols(b.rows), ld(a.rows) +{ + gemm("N", a, "T", b, 1.0, 0.0); +} + +GeneralMatrix::GeneralMatrix(const GeneralMatrix& a, const char* dum, const GeneralMatrix& b) + : data(a.cols*b.cols), rows(a.cols), cols(b.cols), ld(a.cols) +{ + gemm("T", a, "N", b, 1.0, 0.0); +} + +GeneralMatrix::GeneralMatrix(const GeneralMatrix& a, const char* dum1, + const GeneralMatrix& b, const char* dum2) + : data(a.cols*b.rows), rows(a.cols), cols(b.rows), ld(a.cols) +{ + gemm("T", a, "T", b, 1.0, 0.0); +} + + + +GeneralMatrix::~GeneralMatrix() +{ +} + + + +void GeneralMatrix::place(const ConstGeneralMatrix& m, int i, int j) +{ + if (i + m.numRows() > numRows() || + j + m.numCols() > numCols()) + throw SYLV_MES_EXCEPTION("Bad submatrix placement, matrix dimensions exceeded."); + + GeneralMatrix tmpsub(*this, i, j, m.numRows(), m.numCols()); + tmpsub.copy(m); +} + +void GeneralMatrix::mult(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b) +{ + gemm("N", a, "N", b, 1.0, 0.0); +} + +void GeneralMatrix::multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b, + double mult) +{ + gemm("N", a, "N", b, mult, 1.0); +} + +void GeneralMatrix::multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b, + const char* dum, double mult) +{ + gemm("N", a, "T", b, mult, 1.0); +} + +void GeneralMatrix::multAndAdd(const ConstGeneralMatrix& a, const char* dum, + const ConstGeneralMatrix& b, double mult) +{ + gemm("T", a, "N", b, mult, 1.0); +} + +void GeneralMatrix::multAndAdd(const ConstGeneralMatrix& a, const char* dum1, + const ConstGeneralMatrix& b, const char* dum2, double mult) +{ + gemm("T", a, "T", b, mult, 1.0); +} + +void GeneralMatrix::addOuter(const ConstVector& a, double mult) +{ + if (numRows() != numCols()) + throw SYLV_MES_EXCEPTION("Matrix is not square in GeneralMatrix::addOuter."); + if (numRows() != a.length()) + throw SYLV_MES_EXCEPTION("Wrong length of a vector in GeneralMatrix::addOuter."); + + // since BLAS dsyr (symmetric rank 1 update) assumes symmetricity, we do this manually + for (int i = 0; i < numRows(); i++) + for (int j = i; j < numRows(); j++) { + double s = mult*a[i]*a[j]; + get(i,j) = get(i,j) + s; + if (i != j) + get(j,i) = get(j,i) + s; + } +} + + +void GeneralMatrix::multRight(const ConstGeneralMatrix& m) +{ + gemm_partial_right("N", m, 1.0, 0.0); +} + +void GeneralMatrix::multLeft(const ConstGeneralMatrix& m) +{ + gemm_partial_left("N", m, 1.0, 0.0); +} + +void GeneralMatrix::multRightTrans(const ConstGeneralMatrix& m) +{ + gemm_partial_right("T", m, 1.0, 0.0); +} + +void GeneralMatrix::multLeftTrans(const ConstGeneralMatrix& m) +{ + gemm_partial_left("T", m, 1.0, 0.0); +} + +// here we must be careful for ld +void GeneralMatrix::zeros() +{ + if (ld == rows) + data.zeros(); + else { + for (int i = 0; i < rows; i++) + for (int j = 0; j < cols; j++) + get(i,j) = 0; + } +} + +void GeneralMatrix::unit() +{ + for (int i = 0; i < rows; i++) + for (int j = 0; j < cols; j++) + if (i == j) + get(i,j) = 1.0; + else + get(i,j) = 0.0; +} + +void GeneralMatrix::nans() +{ + for (int i = 0; i < rows; i++) + for (int j = 0; j < cols; j++) + get(i,j) = std::numeric_limits::quiet_NaN(); +} + +void GeneralMatrix::infs() +{ + for (int i = 0; i < rows; i++) + for (int j = 0; j < cols; j++) + get(i,j) = std::numeric_limits::infinity(); +} + + +// here we must be careful for ld +void GeneralMatrix::mult(double a) +{ + if (ld == rows) + data.mult(a); + else { + for (int i = 0; i < rows; i++) + for (int j = 0; j < cols; j++) + get(i,j) *= a; + } +} + +// here we must be careful for ld +void GeneralMatrix::add(double a, const ConstGeneralMatrix& m) +{ + if (m.numRows() != rows || m.numCols() != cols) + throw SYLV_MES_EXCEPTION("Matrix has different size in GeneralMatrix::add."); + + if (ld == rows && m.ld == m.rows) + data.add(a, m.data); + else { + for (int i = 0; i < rows; i++) + for (int j = 0; j < cols; j++) + get(i,j) += a*m.get(i,j); + } +} + +void GeneralMatrix::add(double a, const ConstGeneralMatrix& m, const char* dum) +{ + if (m.numRows() != cols || m.numCols() != rows) + throw SYLV_MES_EXCEPTION("Matrix has different size in GeneralMatrix::add."); + + for (int i = 0; i < rows; i++) + for (int j = 0; j < cols; j++) + get(i,j) += a*m.get(j,i); +} + +void GeneralMatrix::copy(const ConstGeneralMatrix& m, int ioff, int joff) +{ + for (int i = 0; i < rows; i++) + for (int j = 0; j < cols; j++) + get(i,j) = m.get(i+ioff,j+joff); +} + +void GeneralMatrix::gemm(const char* transa, const ConstGeneralMatrix& a, + const char* transb, const ConstGeneralMatrix& b, + double alpha, double beta) +{ + int opa_rows = a.numRows(); + int opa_cols = a.numCols(); + if (!strcmp(transa, "T")) { + opa_rows = a.numCols(); + opa_cols = a.numRows(); + } + int opb_rows = b.numRows(); + int opb_cols = b.numCols(); + if (!strcmp(transb, "T")) { + opb_rows = b.numCols(); + opb_cols = b.numRows(); + } + + if (opa_rows != numRows() || + opb_cols != numCols() || + opa_cols != opb_rows) { + throw SYLV_MES_EXCEPTION("Wrong dimensions for matrix multiplication."); + } + + int m = opa_rows; + int n = opb_cols; + int k = opa_cols; + int lda = a.ld; + int ldb = b.ld; + int ldc = ld; + if (lda > 0 && ldb > 0 && ldc > 0) { + BLAS_dgemm(transa, transb, &m, &n, &k, &alpha, a.data.base(), &lda, + b.data.base(), &ldb, &beta, data.base(), &ldc); + } else if (numRows()*numCols() > 0) { + if (beta == 0.0) + zeros(); + else + mult(beta); + } +} + +void GeneralMatrix::gemm_partial_left(const char* trans, const ConstGeneralMatrix& m, + double alpha, double beta) +{ + int icol; + for (icol = 0; icol + md_length < cols; icol += md_length) { + GeneralMatrix incopy((const GeneralMatrix&)*this, 0, icol, rows, md_length); + GeneralMatrix inplace((GeneralMatrix&)*this, 0, icol, rows, md_length); + inplace.gemm(trans, m, "N", ConstGeneralMatrix(incopy), alpha, beta); + } + if (cols > icol) { + GeneralMatrix incopy((const GeneralMatrix&)*this, 0, icol, rows, cols - icol); + GeneralMatrix inplace((GeneralMatrix&)*this, 0, icol, rows, cols - icol); + inplace.gemm(trans, m, "N", ConstGeneralMatrix(incopy), alpha, beta); + } +} + +void GeneralMatrix::gemm_partial_right(const char* trans, const ConstGeneralMatrix& m, + double alpha, double beta) +{ + int irow; + for (irow = 0; irow + md_length < rows; irow += md_length) { + GeneralMatrix incopy((const GeneralMatrix&)*this, irow, 0, md_length, cols); + GeneralMatrix inplace((GeneralMatrix&)*this, irow, 0, md_length, cols); + inplace.gemm("N", ConstGeneralMatrix(incopy), trans, m, alpha, beta); + } + if (rows > irow) { + GeneralMatrix incopy((const GeneralMatrix&)*this, irow, 0, rows - irow, cols); + GeneralMatrix inplace((GeneralMatrix&)*this, irow, 0, rows - irow, cols); + inplace.gemm("N", ConstGeneralMatrix(incopy), trans, m, alpha, beta); + } +} + +ConstGeneralMatrix::ConstGeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols) + : data(m.getData(), j*m.getLD()+i, (ncols-1)*m.getLD()+nrows), rows(nrows), cols(ncols), ld(m.getLD()) +{ + // can check that the submatirx is fully in the matrix +} + +ConstGeneralMatrix::ConstGeneralMatrix(const ConstGeneralMatrix& m, int i, int j, int nrows, int ncols) + : data(m.getData(), j*m.getLD()+i, (ncols-1)*m.getLD()+nrows), rows(nrows), cols(ncols), ld(m.getLD()) +{ + // can check that the submatirx is fully in the matrix +} + + +ConstGeneralMatrix::ConstGeneralMatrix(const GeneralMatrix& m) + : data(m.data), rows(m.rows), cols(m.cols), ld(m.ld) {} + +double ConstGeneralMatrix::getNormInf() const +{ + double norm = 0.0; + for (int i = 0; i < numRows(); i++) { + ConstVector rowi(data.base()+i, ld, cols); + double normi = rowi.getNorm1(); + if (norm < normi) + norm = normi; + } + return norm; +} + +double ConstGeneralMatrix::getNorm1() const +{ + double norm = 0.0; + for (int j = 0; j < numCols(); j++) { + ConstVector colj(data.base()+ld*j, 1, rows); + double normj = colj.getNorm1(); + if (norm < normj) + norm = normj; + } + return norm; +} + +void ConstGeneralMatrix::multVec(double a, Vector& x, double b, const ConstVector& d) const +{ + if (x.length() != rows || cols != d.length()) { + throw SYLV_MES_EXCEPTION("Wrong dimensions for vector multiply."); + } + if (rows > 0) { + int mm = rows; + int nn = cols; + double alpha = b; + int lda = ld; + int incx = d.skip(); + double beta = a; + int incy = x.skip(); + BLAS_dgemv("N", &mm, &nn, &alpha, data.base(), &lda, d.base(), &incx, + &beta, x.base(), &incy); + } + +} + +void ConstGeneralMatrix::multVecTrans(double a, Vector& x, double b, + const ConstVector& d) const +{ + if (x.length() != cols || rows != d.length()) { + throw SYLV_MES_EXCEPTION("Wrong dimensions for vector multiply."); + } + if (rows > 0) { + int mm = rows; + int nn = cols; + double alpha = b; + int lda = rows; + int incx = d.skip(); + double beta = a; + int incy = x.skip(); + BLAS_dgemv("T", &mm, &nn, &alpha, data.base(), &lda, d.base(), &incx, + &beta, x.base(), &incy); + } +} + +/* m = inv(this)*m */ +void ConstGeneralMatrix::multInvLeft(const char* trans, int mrows, int mcols, int mld, double* d) const +{ + if (rows != cols) { + throw SYLV_MES_EXCEPTION("The matrix is not square for inversion."); + } + if (cols != mrows) { + throw SYLV_MES_EXCEPTION("Wrong dimensions for matrix inverse mutliply."); + } + + if (rows > 0) { + GeneralMatrix inv(*this); + int* ipiv = new int[rows]; + int info; + LAPACK_dgetrf(&rows, &rows, inv.getData().base(), &rows, ipiv, &info); + LAPACK_dgetrs(trans, &rows, &mcols, inv.base(), &rows, ipiv, d, + &mld, &info); + delete [] ipiv; + } +} + +/* m = inv(this)*m */ +void ConstGeneralMatrix::multInvLeft(GeneralMatrix& m) const +{ + multInvLeft("N", m.numRows(), m.numCols(), m.getLD(), m.getData().base()); +} + +/* m = inv(this')*m */ +void ConstGeneralMatrix::multInvLeftTrans(GeneralMatrix& m) const +{ + multInvLeft("T", m.numRows(), m.numCols(), m.getLD(), m.getData().base()); +} + +/* d = inv(this)*d */ +void ConstGeneralMatrix::multInvLeft(Vector& d) const +{ + if (d.skip() != 1) { + throw SYLV_MES_EXCEPTION("Skip!=1 not implemented in ConstGeneralMatrix::multInvLeft(Vector&)"); + } + + multInvLeft("N", d.length(), 1, d.length(), d.base()); +} + +/* d = inv(this')*d */ +void ConstGeneralMatrix::multInvLeftTrans(Vector& d) const +{ + if (d.skip() != 1) { + throw SYLV_MES_EXCEPTION("Skip!=1 not implemented in ConstGeneralMatrix::multInvLeft(Vector&)"); + } + + multInvLeft("T", d.length(), 1, d.length(), d.base()); +} + + +bool ConstGeneralMatrix::isFinite() const +{ + for (int i = 0; i < numRows(); i++) + for (int j = 0; j < numCols(); j++) + if (! std::isfinite(get(i,j))) + return false; + return true; +} + +bool ConstGeneralMatrix::isZero() const +{ + for (int i = 0; i < numRows(); i++) + for (int j = 0; j < numCols(); j++) + if (get(i,j) != 0.0) + return false; + return true; +} + +void ConstGeneralMatrix::print() const +{ + printf("rows=%d, cols=%d\n",rows, cols); + for (int i = 0; i < rows; i++) { + printf("row %d:\n",i); + for (int j = 0; j < cols; j++) { + printf("%6.3g ",get(i,j)); + } + printf("\n"); + } +} diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralMatrix.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralMatrix.h new file mode 100644 index 000000000..18413b762 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralMatrix.h @@ -0,0 +1,284 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/GeneralMatrix.h,v 1.3 2004/11/24 20:41:59 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef GENERAL_MATRIX_H +#define GENERAL_MATRIX_H + +#include "Vector.h" + +class GeneralMatrix; + +class ConstGeneralMatrix { + friend class GeneralMatrix; +protected: + ConstVector data; + int rows; + int cols; + int ld; +public: + ConstGeneralMatrix(const double* d, int m, int n) + : data(d, m*n), rows(m), cols(n), ld(m) {} + ConstGeneralMatrix(const GeneralMatrix& m); + ConstGeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols); + ConstGeneralMatrix(const ConstGeneralMatrix& m, int i, int j, int nrows, int ncols); + virtual ~ConstGeneralMatrix() {} + + const double& get(int i, int j) const + {return data[j*ld+i];} + int numRows() const {return rows;} + int numCols() const {return cols;} + int getLD() const {return ld;} + const double* base() const {return data.base();} + const ConstVector& getData() const {return data;} + + double getNormInf() const; + double getNorm1() const; + /* x = scalar(a)*x + scalar(b)*this*d */ + void multVec(double a, Vector& x, double b, const ConstVector& d) const; + /* x = scalar(a)*x + scalar(b)*this'*d */ + void multVecTrans(double a, Vector& x, double b, const ConstVector& d) const; + /* x = x + this*d */ + void multaVec(Vector& x, const ConstVector& d) const + {multVec(1.0, x, 1.0, d);} + /* x = x + this'*d */ + void multaVecTrans(Vector& x, const ConstVector& d) const + {multVecTrans(1.0, x, 1.0, d);} + /* x = x - this*d */ + void multsVec(Vector& x, const ConstVector& d) const + {multVec(1.0, x, -1.0, d);} + /* x = x - this'*d */ + void multsVecTrans(Vector& x, const ConstVector& d) const + {multVecTrans(1.0, x, -1.0, d);} + /* m = inv(this)*m */ + void multInvLeft(GeneralMatrix& m) const; + /* m = inv(this')*m */ + void multInvLeftTrans(GeneralMatrix& m) const; + /* d = inv(this)*d */ + void multInvLeft(Vector& d) const; + /* d = inv(this')*d */ + void multInvLeftTrans(Vector& d) const; + + bool isFinite() const; + /** Returns true of the matrix is exactly zero. */ + bool isZero() const; + + virtual void print() const; +protected: + void multInvLeft(const char* trans, int mrows, int mcols, int mld, double* d) const; +}; + + +class GeneralMatrix { + friend class ConstGeneralMatrix; +protected: + Vector data; + int rows; + int cols; + int ld; +public: + GeneralMatrix(int m, int n) + : data(m*n), rows(m), cols(n), ld(m) {} + GeneralMatrix(const double* d, int m, int n) + : data(d, m*n), rows(m), cols(n), ld(m) {} + GeneralMatrix(double* d, int m, int n) + : data(d, m*n), rows(m), cols(n), ld(m) {} + GeneralMatrix(const GeneralMatrix& m); + GeneralMatrix(const ConstGeneralMatrix& m); + GeneralMatrix(const GeneralMatrix&m, const char* dummy); // transpose + GeneralMatrix(const ConstGeneralMatrix&m, const char* dummy); // transpose + GeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols); + GeneralMatrix(GeneralMatrix& m, int i, int j, int nrows, int ncols); + /* this = a*b */ + GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b); + /* this = a*b' */ + GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b, const char* dum); + /* this = a'*b */ + GeneralMatrix(const GeneralMatrix& a, const char* dum, const GeneralMatrix& b); + /* this = a'*b */ + GeneralMatrix(const GeneralMatrix& a, const char* dum1, + const GeneralMatrix& b, const char* dum2); + + virtual ~GeneralMatrix(); + const GeneralMatrix& operator=(const GeneralMatrix& m) + {data=m.data; rows=m.rows; cols=m.cols; ld=m.ld; return *this;} + + const double& get(int i, int j) const + {return data[j*ld+i];} + double& get(int i, int j) + {return data[j*ld+i];} + int numRows() const {return rows;} + int numCols() const {return cols;} + int getLD() const {return ld;} + double* base() {return data.base();} + const double* base() const {return data.base();} + Vector& getData() {return data;} + const Vector& getData() const {return data;} + + double getNormInf() const + {return ConstGeneralMatrix(*this).getNormInf();} + double getNorm1() const + {return ConstGeneralMatrix(*this).getNorm1();} + + /* place matrix m to the position (i,j) */ + void place(const ConstGeneralMatrix& m, int i, int j); + void place(const GeneralMatrix& m, int i, int j) + {place(ConstGeneralMatrix(m), i, j);} + + /* this = a*b */ + void mult(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b); + void mult(const GeneralMatrix& a, const GeneralMatrix& b) + {mult(ConstGeneralMatrix(a), ConstGeneralMatrix(b));} + + /* this = this + scalar*a*b */ + void multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b, + double mult=1.0); + void multAndAdd(const GeneralMatrix& a, const GeneralMatrix& b, + double mult=1.0) + {multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), mult);} + + /* this = this + scalar*a*b' */ + void multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b, + const char* dum, double mult=1.0); + void multAndAdd(const GeneralMatrix& a, const GeneralMatrix& b, + const char* dum, double mult=1.0) + {multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), dum, mult);} + + /* this = this + scalar*a'*b */ + void multAndAdd(const ConstGeneralMatrix& a, const char* dum, const ConstGeneralMatrix& b, + double mult=1.0); + void multAndAdd(const GeneralMatrix& a, const char* dum, const GeneralMatrix& b, + double mult=1.0) + {multAndAdd(ConstGeneralMatrix(a), dum, ConstGeneralMatrix(b), mult);} + + /* this = this + scalar*a'*b' */ + void multAndAdd(const ConstGeneralMatrix& a, const char* dum1, + const ConstGeneralMatrix& b, const char* dum2, double mult=1.0); + void multAndAdd(const GeneralMatrix& a, const char* dum1, + const GeneralMatrix& b, const char* dum2, double mult=1.0) + {multAndAdd(ConstGeneralMatrix(a), dum1, ConstGeneralMatrix(b),dum2, mult);} + + /* this = this + scalar*a*a' */ + void addOuter(const ConstVector& a, double mult=1.0); + void addOuter(const Vector& a, double mult=1.0) + {addOuter(ConstVector(a), mult);} + + /* this = this * m */ + void multRight(const ConstGeneralMatrix& m); + void multRight(const GeneralMatrix& m) + {multRight(ConstGeneralMatrix(m));} + + /* this = m * this */ + void multLeft(const ConstGeneralMatrix& m); + void multLeft(const GeneralMatrix& m) + {multLeft(ConstGeneralMatrix(m));} + + /* this = this * m' */ + void multRightTrans(const ConstGeneralMatrix& m); + void multRightTrans(const GeneralMatrix& m) + {multRightTrans(ConstGeneralMatrix(m));} + + /* this = m' * this */ + void multLeftTrans(const ConstGeneralMatrix& m); + void multLeftTrans(const GeneralMatrix& m) + {multLeftTrans(ConstGeneralMatrix(m));} + + /* x = scalar(a)*x + scalar(b)*this*d */ + void multVec(double a, Vector& x, double b, const ConstVector& d) const + {ConstGeneralMatrix(*this).multVec(a, x, b, d);} + + /* x = scalar(a)*x + scalar(b)*this'*d */ + void multVecTrans(double a, Vector& x, double b, const ConstVector& d) const + {ConstGeneralMatrix(*this).multVecTrans(a, x, b, d);} + + /* x = x + this*d */ + void multaVec(Vector& x, const ConstVector& d) const + {ConstGeneralMatrix(*this).multaVec(x, d);} + + /* x = x + this'*d */ + void multaVecTrans(Vector& x, const ConstVector& d) const + {ConstGeneralMatrix(*this).multaVecTrans(x, d);} + + /* x = x - this*d */ + void multsVec(Vector& x, const ConstVector& d) const + {ConstGeneralMatrix(*this).multsVec(x, d);} + + /* x = x - this'*d */ + void multsVecTrans(Vector& x, const ConstVector& d) const + {ConstGeneralMatrix(*this).multsVecTrans(x, d);} + + /* this = zero */ + void zeros(); + + /** this = unit (on main diagonal) */ + void unit(); + + /* this = NaN */ + void nans(); + + /* this = Inf */ + void infs(); + + /* this = scalar*this */ + void mult(double a); + + /* this = this + scalar*m */ + void add(double a, const ConstGeneralMatrix& m); + void add(double a, const GeneralMatrix& m) + {add(a, ConstGeneralMatrix(m));} + + /* this = this + scalar*m' */ + void add(double a, const ConstGeneralMatrix& m, const char* dum); + void add(double a, const GeneralMatrix& m, const char* dum) + {add(a, ConstGeneralMatrix(m), dum);} + + bool isFinite() const + {return (ConstGeneralMatrix(*this)).isFinite();} + + bool isZero() const + {return (ConstGeneralMatrix(*this)).isZero();} + + virtual void print() const + {ConstGeneralMatrix(*this).print();} +private: + void copy(const ConstGeneralMatrix& m, int ioff = 0, int joff = 0); + void copy(const GeneralMatrix& m, int ioff = 0, int joff = 0) + {copy(ConstGeneralMatrix(m), ioff, joff);} + + void gemm(const char* transa, const ConstGeneralMatrix& a, + const char* transb, const ConstGeneralMatrix& b, + double alpha, double beta); + void gemm(const char* transa, const GeneralMatrix& a, + const char* transb, const GeneralMatrix& b, + double alpha, double beta) + {gemm(transa, ConstGeneralMatrix(a), transb, ConstGeneralMatrix(b), + alpha, beta);} + + /* this = this * op(m) (without whole copy of this) */ + void gemm_partial_right(const char* trans, const ConstGeneralMatrix& m, + double alpha, double beta); + void gemm_partial_right(const char* trans, const GeneralMatrix& m, + double alpha, double beta) + {gemm_partial_right(trans, ConstGeneralMatrix(m), alpha, beta);} + + /* this = op(m) *this (without whole copy of this) */ + void gemm_partial_left(const char* trans, const ConstGeneralMatrix& m, + double alpha, double beta); + void gemm_partial_left(const char* trans, const GeneralMatrix& m, + double alpha, double beta) + {gemm_partial_left(trans, ConstGeneralMatrix(m), alpha, beta);} + + /* number of rows/columns for copy used in gemm_partial_* */ + static int md_length; +}; + + + + + +#endif /* GENERAL_MATRIX_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralSylvester.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralSylvester.cpp new file mode 100644 index 000000000..4cfc33131 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralSylvester.cpp @@ -0,0 +1,138 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/GeneralSylvester.cpp,v 1.1.1.1 2004/06/04 13:00:20 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "GeneralSylvester.h" +#include "SchurDecomp.h" +#include "SylvException.h" +#include "TriangularSylvester.h" +#include "IterativeSylvester.h" + +#include + +GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols, + const double* da, const double* db, + const double* dc, const double* dd, + const SylvParams& ps) + : pars(ps), + mem_driver(pars, 1, m, n, ord), order(ord), a(da, n), + b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)), + solved(false) +{ + init(); +} + +GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols, + const double* da, const double* db, + const double* dc, double* dd, + const SylvParams& ps) + : pars(ps), + mem_driver(pars, 0, m, n, ord), order(ord), a(da, n), + b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)), + solved(false) +{ + init(); +} + +GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols, + const double* da, const double* db, + const double* dc, const double* dd, + bool alloc_for_check) + : pars(alloc_for_check), + mem_driver(pars, 1, m, n, ord), order(ord), a(da, n), + b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)), + solved(false) +{ + init(); +} + +GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols, + const double* da, const double* db, + const double* dc, double* dd, + bool alloc_for_check) + : pars(alloc_for_check), + mem_driver(pars, 0, m, n, ord), order(ord), a(da, n), + b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)), + solved(false) +{ + init(); +} + +void GeneralSylvester::init() +{ + GeneralMatrix ainvb(b); + double rcond1; + double rcondinf; + a.multInvLeft2(ainvb, d, rcond1, rcondinf); + pars.rcondA1 = rcond1; + pars.rcondAI = rcondinf; + bdecomp = new SchurDecompZero(ainvb); + cdecomp = new SimilarityDecomp(c.getData().base(), c.numRows(), *(pars.bs_norm)); + cdecomp->check(pars, c); + cdecomp->infoToPars(pars); + if (*(pars.method) == SylvParams::recurse) + sylv = new TriangularSylvester(*bdecomp, *cdecomp); + else + sylv = new IterativeSylvester(*bdecomp, *cdecomp); +} + +void GeneralSylvester::solve() +{ + if (solved) + throw SYLV_MES_EXCEPTION("Attempt to run solve() more than once."); + + mem_driver.setStackMode(true); + + clock_t start = clock(); + // multiply d + d.multLeftITrans(bdecomp->getQ()); + d.multRightKron(cdecomp->getQ(), order); + // convert to KronVector + KronVector dkron(d.getData(), getM(), getN(), order); + // solve + sylv->solve(pars, dkron); + // multiply d back + d.multLeftI(bdecomp->getQ()); + d.multRightKron(cdecomp->getInvQ(), order); + clock_t end = clock(); + pars.cpu_time = ((double)(end-start))/CLOCKS_PER_SEC; + + mem_driver.setStackMode(false); + + solved = true; +} + +void GeneralSylvester::check(const double* ds) +{ + if (!solved) + throw SYLV_MES_EXCEPTION("Cannot run check on system, which is not solved yet."); + + mem_driver.setStackMode(true); + + // calculate xcheck = AX+BXC^i-D + SylvMatrix dcheck(d.numRows(), d.numCols()); + dcheck.multLeft(b.numRows()-b.numCols(), b, d); + dcheck.multRightKron(c, order); + dcheck.multAndAdd(a,d); + ConstVector dv(ds, d.numRows()*d.numCols()); + dcheck.getData().add(-1.0, dv); + // calculate relative norms + pars.mat_err1 = dcheck.getNorm1()/d.getNorm1(); + pars.mat_errI = dcheck.getNormInf()/d.getNormInf(); + pars.mat_errF = dcheck.getData().getNorm()/d.getData().getNorm(); + pars.vec_err1 = dcheck.getData().getNorm1()/d.getData().getNorm1(); + pars.vec_errI = dcheck.getData().getMax()/d.getData().getMax(); + + mem_driver.setStackMode(false); +} + +GeneralSylvester::~GeneralSylvester() +{ + delete bdecomp; + delete cdecomp; + delete sylv; +} + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralSylvester.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralSylvester.h new file mode 100644 index 000000000..a81f5a2d4 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/GeneralSylvester.h @@ -0,0 +1,61 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/GeneralSylvester.h,v 1.1.1.1 2004/06/04 13:00:20 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef GENERAL_SYLVESTER_H +#define GENERAL_SYLVESTER_H + +#include "SylvMatrix.h" +#include "SylvMemory.h" +#include "SimilarityDecomp.h" +#include "SylvesterSolver.h" + +class GeneralSylvester { + SylvParams pars; + SylvMemoryDriver mem_driver; + int order; + const SqSylvMatrix a; + const SylvMatrix b; + const SqSylvMatrix c; + SylvMatrix d; + bool solved; + SchurDecompZero* bdecomp; + SimilarityDecomp* cdecomp; + SylvesterSolver* sylv; +public: + /* construct with my copy of d*/ + GeneralSylvester(int ord, int n, int m, int zero_cols, + const double* da, const double* db, + const double* dc, const double* dd, + const SylvParams& ps); + GeneralSylvester(int ord, int n, int m, int zero_cols, + const double* da, const double* db, + const double* dc, const double* dd, + bool alloc_for_check = false); + /* construct with provided storage for d */ + GeneralSylvester(int ord, int n, int m, int zero_cols, + const double* da, const double* db, + const double* dc, double* dd, + bool alloc_for_check = false); + GeneralSylvester(int ord, int n, int m, int zero_cols, + const double* da, const double* db, + const double* dc, double* dd, + const SylvParams& ps); + virtual ~GeneralSylvester(); + int getM() const {return c.numRows();} + int getN() const {return a.numRows();} + const double* getResult() const {return d.base();} + const SylvParams& getParams() const {return pars;} + SylvParams& getParams() {return pars;} + void solve(); + void check(const double* ds); +private: + void init(); +}; + +#endif /* GENERAL_SYLVESTER_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/IterativeSylvester.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/IterativeSylvester.cpp new file mode 100644 index 000000000..e585f655a --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/IterativeSylvester.cpp @@ -0,0 +1,53 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/IterativeSylvester.cpp,v 1.1.1.1 2004/06/04 13:00:20 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "IterativeSylvester.h" +#include "KronUtils.h" + +void IterativeSylvester::solve(SylvParams& pars, KronVector& x) const +{ + int max_steps = *(pars.max_num_iter); + int steps = 1; + double max_norm = *(pars.convergence_tol); + double norm = performFirstStep(x); + + QuasiTriangular* kpow = matrixK->clone(); + QuasiTriangular* fpow = matrixF->clone(); + while (steps < max_steps && norm > max_norm) { + kpow->multRight(SqSylvMatrix(*kpow)); // be careful to make copy + fpow->multRight(SqSylvMatrix(*fpow)); // also here + norm = performStep(*kpow, *fpow, x); + steps++; + } + + delete fpow; + delete kpow; + + pars.converged = (norm <= max_norm); + pars.iter_last_norm = norm; + pars.num_iter = steps; +} + +double IterativeSylvester::performFirstStep(KronVector& x) const +{ + KronVector xtmp((const KronVector&)x); + KronUtils::multKron(*matrixF, *matrixK, xtmp); + x.add(-1., xtmp); + double norm = xtmp.getMax(); + return norm; +} + +double IterativeSylvester::performStep(const QuasiTriangular& k, const QuasiTriangular& f, + KronVector& x) +{ + KronVector xtmp((const KronVector&)x); + KronUtils::multKron(f, k, xtmp); + x.add(1.0, xtmp); + double norm = xtmp.getMax(); + return norm; +} + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/IterativeSylvester.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/IterativeSylvester.h new file mode 100644 index 000000000..cb69fbf7c --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/IterativeSylvester.h @@ -0,0 +1,33 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/IterativeSylvester.h,v 1.1.1.1 2004/06/04 13:00:20 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef ITERATIVE_SYLVESTER_H +#define ITERATIVE_SYLVESTER_H + +#include "SylvesterSolver.h" +#include "KronVector.h" +#include "QuasiTriangular.h" +#include "SimilarityDecomp.h" + +class IterativeSylvester : public SylvesterSolver { +public: + IterativeSylvester(const QuasiTriangular& k, const QuasiTriangular& f) + : SylvesterSolver(k, f) {} + IterativeSylvester(const SchurDecompZero& kdecomp, const SchurDecomp& fdecomp) + : SylvesterSolver(kdecomp, fdecomp) {} + IterativeSylvester(const SchurDecompZero& kdecomp, const SimilarityDecomp& fdecomp) + : SylvesterSolver(kdecomp, fdecomp) {} + void solve(SylvParams& pars, KronVector& x) const; +private: + double performFirstStep(KronVector& x) const; + static double performStep(const QuasiTriangular& k, const QuasiTriangular& f, + KronVector& x); +}; + +#endif /* ITERATIVE_SYLVESTER_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/KronUtils.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/KronUtils.cpp new file mode 100644 index 000000000..013d16520 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/KronUtils.cpp @@ -0,0 +1,53 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/KronUtils.cpp,v 1.1.1.1 2004/06/04 13:00:31 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "KronUtils.h" + +void KronUtils::multAtLevel(int level, const QuasiTriangular& t, + KronVector& x) +{ + if (0 < level && level < x.getDepth()) { + for (int i = 0; i < x.getM(); i++) { + KronVector xi(x, i); + multAtLevel(level, t, xi); + } + } else if (0 == level && 0 < x.getDepth()) { + GeneralMatrix tmp(x.base(), x.getN(), power(x.getM(),x.getDepth())); + t.multLeftOther(tmp); + } else if (0 == level && 0 == x.getDepth()) { + Vector b((const Vector&)x); + t.multVec(x,b); + } else { // 0 < level == depth + t.multKron(x); + } +} + +void KronUtils::multAtLevelTrans(int level, const QuasiTriangular& t, + KronVector& x) +{ + if (0 < level && level < x.getDepth()) { + for (int i = 0; i < x.getM(); i++) { + KronVector xi(x, i); + multAtLevelTrans(level, t, xi); + } + } else if (0 == level && 0 < x.getDepth()) { + GeneralMatrix tmp(x.base(), x.getN(), power(x.getM(),x.getDepth())); + t.multLeftOtherTrans(tmp); + } else if (level == 0 && 0 == x.getDepth()) { + Vector b((const Vector&)x); + t.multVecTrans(x,b); + } else { // 0 < level == depth + t.multKronTrans(x); + } +} + +void KronUtils::multKron(const QuasiTriangular& f, const QuasiTriangular& k, + KronVector& x) +{ + multAtLevel(0, k, x); + if (x.getDepth() > 0) { + for (int level = 1; level <= x.getDepth(); level++) + multAtLevelTrans(level, f, x); + } +} diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/KronUtils.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/KronUtils.h new file mode 100644 index 000000000..2ebeeee30 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/KronUtils.h @@ -0,0 +1,32 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/KronUtils.h,v 1.1.1.1 2004/06/04 13:00:31 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef KRON_UTILS_H +#define KRON_UTILS_H + +#include "KronVector.h" +#include "QuasiTriangular.h" + +class KronUtils { +public: + /* multiplies I_m\otimes..\I_m\otimes T\otimes I_m...I_m\otimes I_n + with given b and returns x. T must be (m,m), number of + \otimes is b.getDepth(), level is a number of I_m's between T + and I_n plus 1. If level=0, then we multiply + \I_m\otimes ..\otimes I_m\otimes T, T is (n,n) */ + static void multAtLevel(int level, const QuasiTriangular& t, + KronVector& x); + static void multAtLevelTrans(int level, const QuasiTriangular& t, + KronVector& x); + + /* multiplies x=(F'\otimes F'\otimes..\otimes K)x */ + static void multKron(const QuasiTriangular& f, const QuasiTriangular& k, + KronVector& x); +}; + +#endif /* KRON_UTILS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/KronVector.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/KronVector.cpp new file mode 100644 index 000000000..71da28f7b --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/KronVector.cpp @@ -0,0 +1,109 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/KronVector.cpp,v 1.1.1.1 2004/06/04 13:00:31 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "KronVector.h" +#include "SylvException.h" + +int power(int m, int depth) +{ + int p = 1; + for (int i = 0; i < depth; i++) { + p *= m; + } + return p; +} + +KronVector::KronVector(int mm, int nn, int dp) + : Vector(power(mm,dp)*nn), m(mm), n(nn), depth(dp) +{} + +KronVector::KronVector(Vector& v, int mm, int nn, int dp) + : Vector(v), m(mm), n(nn), depth(dp) +{ + len = power(m,depth)*n; + if (v.length() != length()) { + throw SYLV_MES_EXCEPTION("Bad conversion KronVector from Vector."); + } +} + +KronVector::KronVector(KronVector& v, int i) + : Vector(v, i*power(v.m,v.depth-1)*v.n, power(v.m, v.depth-1)*v.n), m(v.m), n(v.n), + depth(v.depth-1) +{ + if (depth < 0) { + throw SYLV_MES_EXCEPTION("Bad KronVector pick, depth < 0."); + } +} + +KronVector::KronVector(const ConstKronVector& v) + : Vector(v.length()), m(v.getM()), n(v.getN()), depth(v.getDepth()) +{ + Vector::operator=(v); +} + +const KronVector& KronVector::operator=(const ConstKronVector& v) +{ + Vector::operator=(v); + m=v.getM(); + n=v.getN(); + depth = v.getDepth(); + return *this; +} + +const KronVector& KronVector::operator=(const Vector& v) +{ + if (length() != v.length()) { + throw SYLV_MES_EXCEPTION("Wrong lengths for vector operator =."); + } + Vector::operator=(v); + return *this; +} + + + +ConstKronVector::ConstKronVector(const KronVector& v) + : ConstVector(v), m(v.getM()), n(v.getN()), depth(v.getDepth()) +{} + +ConstKronVector::ConstKronVector(const ConstKronVector& v) + : ConstVector(power(v.getM(),v.getDepth())*v.getN()), m(v.getM()), n(v.getN()), + depth(v.getDepth()) +{} + +ConstKronVector::ConstKronVector(const Vector& v, int mm, int nn, int dp) + : ConstVector(v), m(mm), n(nn), depth(dp) +{ + len = power(m,depth)*n; + if (v.length() != length()) { + throw SYLV_MES_EXCEPTION("Bad conversion KronVector from Vector."); + } +} + +ConstKronVector::ConstKronVector(const ConstVector& v, int mm, int nn, int dp) + : ConstVector(v), m(mm), n(nn), depth(dp) +{ + len = power(m,depth)*n; + if (v.length() != length()) { + throw SYLV_MES_EXCEPTION("Bad conversion KronVector from Vector."); + } +} + +ConstKronVector::ConstKronVector(const KronVector& v, int i) + : ConstVector(v, i*power(v.getM(),v.getDepth()-1)*v.getN(), + power(v.getM(),v.getDepth()-1)*v.getN()), + m(v.getM()), n(v.getN()), depth(v.getDepth()-1) +{ + if (depth < 0) { + throw SYLV_MES_EXCEPTION("Bad KronVector pick, depth < 0."); + } +} + +ConstKronVector::ConstKronVector(const ConstKronVector& v, int i) + : ConstVector(v, i*power(v.m,v.depth-1)*v.n, power(v.m,v.depth-1)*v.n), + m(v.getM()), n(v.getN()), depth(v.getDepth()-1) +{ + if (depth < 0) { + throw SYLV_MES_EXCEPTION("Bad KronVector pick, depth < 0."); + } +} diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/KronVector.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/KronVector.h new file mode 100644 index 000000000..db721c3b7 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/KronVector.h @@ -0,0 +1,58 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/KronVector.h,v 1.1.1.1 2004/06/04 13:00:31 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef KRON_VECTOR_H +#define KRON_VECTOR_H + +#include "Vector.h" + +class ConstKronVector; + +class KronVector : public Vector { +protected: + int m; + int n; + int depth; +public: + KronVector() : Vector((double*)0, 0), m(0), n(0), depth(0) {} + KronVector(int mm, int nn, int dp); // new instance + KronVector(Vector& v, int mm, int nn, int dp); // conversion + KronVector(KronVector&, int i); // picks i-th subvector + KronVector(const ConstKronVector& v); // new instance and copy + const KronVector& operator=(KronVector& v) + {Vector::operator=(v); m=v.m; n=v.n; depth = v.depth; return *this;} + const KronVector& operator=(const KronVector& v) + {Vector::operator=(v); m=v.m; n=v.n; depth = v.depth; return *this;} + const KronVector& operator=(const ConstKronVector& v); + const KronVector& operator=(const Vector& v); + int getM() const {return m;} + int getN() const {return n;} + int getDepth() const {return depth;} +}; + +class ConstKronVector : public ConstVector +{ +protected: + int m; + int n; + int depth; +public: + ConstKronVector(const KronVector& v); + ConstKronVector(const ConstKronVector& v); + ConstKronVector(const Vector& v, int mm, int nn, int dp); + ConstKronVector(const ConstVector& v, int mm, int nn, int dp); + ConstKronVector(const KronVector& v, int i); + ConstKronVector(const ConstKronVector& v, int i); + int getM() const {return m;} + int getN() const {return n;} + int getDepth() const {return depth;} +}; + +int power(int m, int depth); + +#endif /* KRON_VECTOR */ + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/Makefile b/mex/sources/korderpert/Dyn_pp/sylv/cc/Makefile new file mode 100644 index 000000000..fa4a4701c --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/Makefile @@ -0,0 +1,34 @@ +# $Header: /var/lib/cvs/dynare_cpp/sylv/cc/Makefile,v 1.4 2005/01/18 21:28:26 kamenik Exp $ + +# Tag $Name: $ + +CC_FLAGS := -Wall -I../testing -I../cc \ + $(CC_INCLUDE_PATH) + +ifeq ($(DEBUG),yes) + CC_FLAGS := $(CC_FLAGS) -g +else + CC_FLAGS := $(CC_FLAGS) -O2 +endif + +ifeq ($(OS),Windows_NT) + CC_FLAGS := -mno-cygwin -mthreads $(CC_FLAGS) +endif + + +objects := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) +headers := $(wildcard *.h) + +all: $(objects) + +sylvester.a: $(objects) + ar cr sylvester.a $(objects) + ranlib sylvester.a + +clear: + rm -f *.o + rm -f sylvester.a + +%.o : %.cpp $(headers) + $(CC) $(CC_FLAGS) $(EXTERN_DEFS) -c $*.cpp + diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/QuasiTriangular.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/QuasiTriangular.cpp new file mode 100644 index 000000000..744a0df5f --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/QuasiTriangular.cpp @@ -0,0 +1,682 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/QuasiTriangular.cpp,v 1.1.1.1 2004/06/04 13:00:31 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "QuasiTriangular.h" +#include "SylvException.h" +#include "SchurDecomp.h" + +#include "cppblas.h" + +#include +#include + +using namespace std; + +double DiagonalBlock::getDeterminant() const +{ + return (*alpha)*(*alpha) + getSBeta(); +} + +double DiagonalBlock::getSBeta() const +{ + return -(*beta1)*(*beta2); +} + +double DiagonalBlock::getSize() const +{ + if (real) + return abs(*alpha); + else + return sqrt(getDeterminant()); +} + +// this function makes Diagonal inconsistent, it should only be used +// on temorary matrices, which will not be used any more, e.g. in +// QuasiTriangular::solve (we need fast performance) +void DiagonalBlock::setReal() +{ + *beta1 = 0; + *beta2 = 0; + real = true; +} + +void DiagonalBlock::checkBlock(const double* d, int d_size) +{ + const double* a1 = d + jbar*d_size+jbar; + const double* b1 = a1 + d_size; + const double* b2 = a1 + 1; + const double* a2 = b1 + 1; + if (a1 != alpha.a1) + throw SYLV_MES_EXCEPTION("Bad alpha1."); + if (!real && b1 != beta1) + throw SYLV_MES_EXCEPTION("Bad beta1."); + if (!real && b2 != beta2) + throw SYLV_MES_EXCEPTION("Bad beta2."); + if (!real && a2 != alpha.a2) + throw SYLV_MES_EXCEPTION("Bad alpha2."); +} + +Diagonal::Diagonal(double* data, int d_size) +{ + int nc = getNumComplex(data, d_size); // return nc <= d_size/2 + num_all = d_size - nc; + num_real = d_size - 2*nc; + + int jbar = 0; + int j = 0; + while (j < num_all) { + int id = jbar*d_size + jbar; // index of diagonal block in data + int ill = id + 1; // index of element below the diagonal + int iur = id + d_size; // index of element right to diagonal + int idd = id + d_size + 1; // index of element next on diagonal + if ((jbar < d_size-1) && !isZero(data[ill])) { + // it is not last column and we have nonzero below diagonal + DiagonalBlock b(jbar, false, &data[id], &data[idd], + &data[iur], &data[ill]); + blocks.push_back(b); + jbar++; + } else { + // it is last column or we have zero below diagonal + DiagonalBlock b(jbar, true, &data[id], &data[id], NULL, NULL); + blocks.push_back(b); + } + jbar++; + j++; + } +} + + +Diagonal::Diagonal(double* data, const Diagonal& d) +{ + num_all = d.num_all; + num_real = d.num_real; + int d_size = d.getSize(); + for (const_diag_iter it = d.begin(); it != d.end(); ++it) { + const DiagonalBlock& dit = *it; + double* beta1 = NULL; + double* beta2 = NULL; + int id = dit.getIndex()*(d_size+1); + int idd = id; + if (! dit.isReal()) { + beta1 = &data[id+d_size]; + beta2 = &data[id+1]; + idd = id + d_size + 1; + } + DiagonalBlock b(dit.getIndex(), dit.isReal(), + &data[id], &data[idd], beta1, beta2); + blocks.push_back(b); + } +} + + +void Diagonal::copy(const Diagonal& d) +{ + num_all = d.num_all; + num_real = d.num_real; + blocks = d.blocks; +} + +int Diagonal::getNumComplex(const double* data, int d_size) +{ + int num_complex = 0; + int in = 1; + for (int i = 0; i < d_size-1; i++, in = in + d_size + 1) { + if (! isZero(data[in])) { + num_complex++; + if (in < d_size - 2 && ! isZero(data[in + d_size +1])) { + throw SYLV_MES_EXCEPTION("Matrix is not quasi-triangular"); + } + } + } + return num_complex; +} + +void Diagonal::changeBase(double* p) +{ + int d_size = getSize(); + for (diag_iter it = begin(); it != end(); ++it) { + const DiagonalBlock& b = *it; + int jbar = b.getIndex(); + int base = d_size*jbar + jbar; + if (b.isReal()) { + DiagonalBlock bnew(jbar, true, &p[base], &p[base], + NULL, NULL); + *it = bnew; + } else { + DiagonalBlock bnew(jbar, false, &p[base], &p[base+d_size+1], + &p[base+d_size], &p[base+1]); + *it = bnew; + } + } +} + +void Diagonal::getEigenValues(Vector& eig) const +{ + int d_size = getSize(); + if (eig.length() != 2*d_size) { + char mes[500]; + sprintf(mes, "Wrong length of vector for eigenvalues len=%d, should be=%d.\n", + eig.length(), 2*d_size); + throw SYLV_MES_EXCEPTION(mes); + } + for (const_diag_iter it = begin(); it != end(); ++it) { + const DiagonalBlock& b = *it; + int ind = b.getIndex(); + eig[2*ind] = *(b.getAlpha()); + if (b.isReal()) { + eig[2*ind+1] = 0.0; + } else { + double beta = sqrt(b.getSBeta()); + eig[2*ind+1] = beta; + eig[2*ind+2] = eig[2*ind]; + eig[2*ind+3] = -beta; + } + } +} + +/* swaps logically blocks 'it', and '++it'. remember to move also + * addresses, alpha, beta1, beta2. This is a dirty (but most + * effective) way how to do it. */ +void Diagonal::swapLogically(diag_iter it) +{ + diag_iter itp = it; + ++itp; + + if ((*it).isReal() && !(*itp).isReal()) { + // first is real, second is complex + double* d1 = (*it).alpha.a1; + double* d2 = (*itp).alpha.a1; + double* d3 = (*itp).alpha.a2; + // swap + DiagonalBlock new_it((*it).jbar, d1, d2); + *it = new_it; + DiagonalBlock new_itp((*itp).jbar+1, d3); + *itp = new_itp; + } else if (!(*it).isReal() && (*itp).isReal()) { + // first is complex, second is real + double* d1 = (*it).alpha.a1; + double* d2 = (*it).alpha.a2; + double* d3 = (*itp).alpha.a1; + // swap + DiagonalBlock new_it((*it).jbar, d1); + *it = new_it; + DiagonalBlock new_itp((*itp).jbar-1, d2, d3); + *itp = new_itp; + } +} + +void Diagonal::checkConsistency(diag_iter it) +{ + if (!(*it).isReal() && isZero((*it).getBeta2())) { + (*it).getBeta2() = 0.0; // put exact zero + int jbar = (*it).getIndex(); + double* d2 = (*it).alpha.a2; + (*it).alpha.a2 = (*it).alpha.a1; + (*it).real = true; + (*it).beta1 = 0; + (*it).beta2 = 0; + DiagonalBlock b(jbar+1, d2); + blocks.insert((++it).iter(), b); + num_real += 2; + num_all++; + } +} + +double Diagonal::getAverageSize(diag_iter start, diag_iter end) +{ + double res = 0; + int num = 0; + for (diag_iter run = start; run != end; ++run) { + num++; + res += (*run).getSize(); + } + if (num > 0) + res = res/num; + return res; +} + +Diagonal::diag_iter Diagonal::findClosestBlock(diag_iter start, diag_iter end, double a) +{ + diag_iter closest = start; + double minim = 1.0e100; + for (diag_iter run = start; run != end; ++run) { + double dist = abs(a - (*run).getSize()); + if (dist < minim) { + minim = dist; + closest = run; + } + } + return closest; +} + +Diagonal::diag_iter Diagonal::findNextLargerBlock(diag_iter start, diag_iter end, double a) +{ + diag_iter closest = start; + double minim = 1.0e100; + for (diag_iter run = start; run != end; ++run) { + double dist = (*run).getSize() - a; + if ((0 <= dist) && (dist < minim)) { + minim = dist; + closest = run; + } + } + return closest; +} + +void Diagonal::print() const +{ + printf("Num real: %d, num complex: %d\n",getNumReal(), getNumComplex()); + for (const_diag_iter it = begin(); it != end(); ++it) { + if ((*it).isReal()) { + printf("real: jbar=%d, alpha=%f\n", (*it).getIndex(), *((*it).getAlpha())); + } + else { + printf("complex: jbar=%d, alpha=%f, beta1=%f, beta2=%f\n", + (*it).getIndex(), *((*it).getAlpha()), (*it).getBeta1(), (*it).getBeta2()); + } + } +} + +double Diagonal::EPS = 1.0e-300; + +bool Diagonal::isZero(double p) +{ + return (abs(p) + +using namespace std; + +class DiagonalBlock; +class Diagonal; +class DiagPair { +private: + double* a1; + double* a2; +public: + DiagPair() {} + DiagPair(double* aa1, double* aa2) {a1 = aa1; a2 = aa2;} + DiagPair(const DiagPair& p) {a1 = p.a1; a2 = p.a2;} + const DiagPair& operator=(const DiagPair& p) {a1 = p.a1; a2 = p.a2; return *this;} + const DiagPair& operator=(double v) {*a1 = v; *a2 = v; return *this;} + const double& operator*() const {return *a1;} + /** here we must not define double& operator*(), since it wouldn't + rewrite both values, we use operator= for this */ + friend class Diagonal; + friend class DiagonalBlock; +}; + +class DiagonalBlock { +private: + int jbar; + bool real; + DiagPair alpha; + double* beta1; + double* beta2; + + void copy(const DiagonalBlock& b) { + jbar = b.jbar; + real = b.real; + alpha = b.alpha; + beta1 = b.beta1; + beta2 = b.beta2; + } + +public: + DiagonalBlock() {} + DiagonalBlock(int jb, bool r, double* a1, double* a2, + double* b1, double* b2) + : alpha(a1, a2) + { + jbar = jb; + real = r; + beta1 = b1; + beta2 = b2; + } + // construct complex block + DiagonalBlock(int jb, double* a1, double* a2) + : alpha(a1, a2) + { + jbar = jb; + real = false; + beta1 = a2 - 1; + beta2 = a1 + 1; + } + // construct real block + DiagonalBlock(int jb, double* a1) + : alpha(a1, a1) + { + jbar = jb; + real = true; + beta1 = 0; + beta2 = 0; + } + DiagonalBlock(const DiagonalBlock& b) + {copy(b);} + const DiagonalBlock& operator=(const DiagonalBlock& b) + {copy(b); return *this;} + int getIndex() const + {return jbar;} + bool isReal() const + {return real;} + const DiagPair& getAlpha() const + {return alpha;} + DiagPair& getAlpha() + {return alpha;} + double& getBeta1() const + {return *beta1;} + double& getBeta2() const + {return *beta2;} + double getDeterminant() const; + double getSBeta() const; + double getSize() const; + void setReal(); + // for debugging + void checkBlock(const double* d, int d_size); + friend class Diagonal; +}; + +template +struct _diag_iter { + typedef _diag_iter<_Tdiag, _Tblock, _Titer> _Self; + _Tdiag diag; + _Titer it; +public: + _diag_iter(_Tdiag d, _Titer iter) : diag(d), it(iter) {} + _Tblock operator*() const {return *it;} + _Self& operator++() {++it; return *this;} + _Self& operator--() {--it; return *this;} + bool operator==(const _Self& x) const {return x.it == it;} + bool operator!=(const _Self& x) const {return x.it != it;} + const _Self& operator=(const _Self& x) {it = x.it; return *this;} + _Titer iter() const {return it;} +}; + +class Diagonal { +public: + typedef _diag_iter::const_iterator> const_diag_iter; + typedef _diag_iter::iterator> diag_iter; +private: + int num_all; + list blocks; + int num_real; + void copy(const Diagonal&); +public: + Diagonal() : num_all(0), num_real(0) {} + Diagonal(double* data, int d_size); + Diagonal(double* data, const Diagonal& d); + Diagonal(const Diagonal& d) {copy(d);} + const Diagonal& operator =(const Diagonal& d) {copy(d); return *this;} + virtual ~Diagonal() {} + + int getNumComplex() const {return num_all - num_real;} + int getNumReal() const {return num_real;} + int getSize() const {return getNumReal() + 2*getNumComplex();} + int getNumBlocks() const {return num_all;} + void getEigenValues(Vector& eig) const; + void swapLogically(diag_iter it); + void checkConsistency(diag_iter it); + double getAverageSize(diag_iter start, diag_iter end); + diag_iter findClosestBlock(diag_iter start, diag_iter end, double a); + diag_iter findNextLargerBlock(diag_iter start, diag_iter end, double a); + void print() const; + + diag_iter begin() + {return diag_iter(*this, blocks.begin());} + const_diag_iter begin() const + {return const_diag_iter(*this, blocks.begin());} + diag_iter end() + {return diag_iter(*this, blocks.end());} + const_diag_iter end() const + {return const_diag_iter(*this, blocks.end());} + + /* redefine pointers as data start at p */ + void changeBase(double* p); +private: + static double EPS; + static int getNumComplex(const double* data, int d_size); + static bool isZero(double p); +}; + +template +struct _matrix_iter { + typedef _matrix_iter<_TRef, _TPtr> _Self; + int d_size; + bool real; + _TPtr ptr; +public: + _matrix_iter(_TPtr base, int ds, bool r) + {ptr = base; d_size = ds; real = r;} + virtual ~_matrix_iter() {} + const _Self& operator=(const _Self& it) + {ptr = it.ptr; d_size = it.d_size; real = it.real; return *this;} + bool operator==(const _Self& it) const + {return ptr == it.ptr;} + bool operator!=(const _Self& it) const + {return ptr != it.ptr;} + _TRef operator*() const + {return *ptr;} + _TRef a() const + {return *ptr;} + virtual _Self& operator++() =0; +}; + +template +class _column_iter : public _matrix_iter<_TRef, _TPtr> { + typedef _matrix_iter<_TRef, _TPtr> _Tparent; + typedef _column_iter<_TRef, _TPtr> _Self; + int row; +public: + _column_iter(_TPtr base, int ds, bool r, int rw) + : _matrix_iter<_TRef, _TPtr>(base, ds, r), row(rw) {}; + _Self& operator++() + {_Tparent::ptr++; row++; return *this;} + _TRef b() const + { + if (_Tparent::real) { + return *(_Tparent::ptr); + } else { + return *(_Tparent::ptr+_Tparent::d_size); + } + } + int getRow() const {return row;} +}; + +template +class _row_iter : public _matrix_iter<_TRef, _TPtr> { + typedef _matrix_iter<_TRef, _TPtr> _Tparent; + typedef _row_iter<_TRef, _TPtr> _Self; + int col; +public: + _row_iter(_TPtr base, int ds, bool r, int cl) + : _matrix_iter<_TRef, _TPtr>(base, ds, r), col(cl) {}; + _Self& operator++() + {_Tparent::ptr += _Tparent::d_size; col++; return *this;} + virtual _TRef b() const + { + if (_Tparent::real) { + return *(_Tparent::ptr); + }else { + return *(_Tparent::ptr+1); + } + } + int getCol() const {return col;} +}; + +class SchurDecomp; +class SchurDecompZero; + +class QuasiTriangular : public SqSylvMatrix { +public: + typedef _column_iter const_col_iter; + typedef _column_iter col_iter; + typedef _row_iter const_row_iter; + typedef _row_iter row_iter; + typedef Diagonal::const_diag_iter const_diag_iter; + typedef Diagonal::diag_iter diag_iter; +protected: + Diagonal diagonal; +public: + QuasiTriangular(const double* d, int d_size); + QuasiTriangular(double r, const QuasiTriangular& t); + QuasiTriangular(double r, const QuasiTriangular& t, + double rr, const QuasiTriangular& tt); + QuasiTriangular(int p, const QuasiTriangular& t); + QuasiTriangular(const SchurDecomp& decomp); + QuasiTriangular(const SchurDecompZero& decomp); + QuasiTriangular(const QuasiTriangular& t); + virtual ~QuasiTriangular(); + const Diagonal& getDiagonal() const {return diagonal;} + int getNumOffdiagonal() const; + void swapDiagLogically(diag_iter it); + void checkDiagConsistency(diag_iter it); + double getAverageDiagSize(diag_iter start, diag_iter end); + diag_iter findClosestDiagBlock(diag_iter start, diag_iter end, double a); + diag_iter findNextLargerBlock(diag_iter start, diag_iter end, double a); + + + /* (I+T)y = x, y-->x */ + virtual void solvePre(Vector& x, double& eig_min); + /* (I+T')y = x, y-->x */ + virtual void solvePreTrans(Vector& x, double& eig_min); + /* (I+T)x = b */ + virtual void solve(Vector& x, const ConstVector& b, double& eig_min); + /* (I+T')x = b */ + virtual void solveTrans(Vector& x, const ConstVector& b, double& eig_min); + /* x = Tb */ + virtual void multVec(Vector& x, const ConstVector& b) const; + /* x = T'b */ + virtual void multVecTrans(Vector& x, const ConstVector& b) const; + /* x = x + Tb */ + virtual void multaVec(Vector& x, const ConstVector& b) const; + /* x = x + T'b */ + virtual void multaVecTrans(Vector& x, const ConstVector& b) const; + /* x = (T\otimes I)x */ + virtual void multKron(KronVector& x) const; + /* x = (T'\otimes I)x */ + virtual void multKronTrans(KronVector& x) const; + /* A = T*A */ + virtual void multLeftOther(GeneralMatrix& a) const; + /* A = T'*A */ + virtual void multLeftOtherTrans(GeneralMatrix& a) const; + + const_diag_iter diag_begin() const + {return diagonal.begin();} + diag_iter diag_begin() + {return diagonal.begin();} + const_diag_iter diag_end() const + {return diagonal.end();} + diag_iter diag_end() + {return diagonal.end();} + + /* iterators for off diagonal elements */ + virtual const_col_iter col_begin(const DiagonalBlock& b) const; + virtual col_iter col_begin(const DiagonalBlock& b); + virtual const_row_iter row_begin(const DiagonalBlock& b) const; + virtual row_iter row_begin(const DiagonalBlock& b); + virtual const_col_iter col_end(const DiagonalBlock& b) const; + virtual col_iter col_end(const DiagonalBlock& b); + virtual const_row_iter row_end(const DiagonalBlock& b) const; + virtual row_iter row_end(const DiagonalBlock& b); + + /* clone */ + virtual QuasiTriangular* clone() const + {return new QuasiTriangular(*this);} + virtual QuasiTriangular* clone(int p, const QuasiTriangular& t) const + {return new QuasiTriangular(p, t);} + virtual QuasiTriangular* clone(double r) const + {return new QuasiTriangular(r, *this);} + virtual QuasiTriangular* clone(double r, double rr, const QuasiTriangular& tt) const + {return new QuasiTriangular(r, *this, rr, tt);} +protected: + void setMatrix(double r, const QuasiTriangular& t); + void addMatrix(double r, const QuasiTriangular& t); +private: + void addUnit(); + /* x = x + (T\otimes I)b */ + void multaKron(KronVector& x, const ConstKronVector& b) const; + /* x = x + (T'\otimes I)b */ + void multaKronTrans(KronVector& x, const ConstKronVector& b) const; + /* implementation via iterators, useful for large matrices */ + void setMatrixViaIter(double r, const QuasiTriangular& t); + void addMatrixViaIter(double r, const QuasiTriangular& t); + /* hide noneffective implementations of parents */ + void multsVec(Vector& x, const ConstVector& d) const; + void multsVecTrans(Vector& x, const ConstVector& d) const; +}; + +#endif /* QUASI_TRIANGULAR_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/QuasiTriangularZero.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/QuasiTriangularZero.cpp new file mode 100644 index 000000000..49054970d --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/QuasiTriangularZero.cpp @@ -0,0 +1,148 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/QuasiTriangularZero.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "QuasiTriangularZero.h" +#include "SchurDecomp.h" +#include "SylvMatrix.h" +#include "SylvException.h" + +#include + +QuasiTriangularZero::QuasiTriangularZero(int num_zeros, const double* d, + int d_size) + : QuasiTriangular(SqSylvMatrix(GeneralMatrix(d, num_zeros+d_size, d_size), + num_zeros, 0, d_size).getData().base(), + d_size), + nz(num_zeros), + ru(GeneralMatrix(d, num_zeros+d_size, d_size), 0, 0, num_zeros, d_size) +{ +} + +QuasiTriangularZero::QuasiTriangularZero(double r, + const QuasiTriangularZero& t) + : QuasiTriangular(r, t), + nz(t.nz), + ru(t.ru) +{ + ru.mult(r); +} + +QuasiTriangularZero::QuasiTriangularZero(double r, + const QuasiTriangularZero& t, + double rr, + const QuasiTriangularZero& tt) + : QuasiTriangular(r, t, rr, tt), + nz(t.nz), + ru(t.ru) +{ + ru.mult(r); + ru.add(rr, tt.ru); +} + +QuasiTriangularZero::QuasiTriangularZero(int p, const QuasiTriangularZero& t) + : QuasiTriangular(p, t), + nz(t.nz), + ru(t.ru) +{ + ru.multRight(t); +} + +QuasiTriangularZero::QuasiTriangularZero(const SchurDecompZero& decomp) + : QuasiTriangular(decomp.getT().getData().base(), + decomp.getT().numRows()), + nz(decomp.getZeroCols()), + ru(decomp.getRU()) +{ +} + +QuasiTriangularZero::QuasiTriangularZero(const QuasiTriangular& t) + : QuasiTriangular(t), + nz(0), ru(0, t.getDiagonal().getSize()) +{ +} + +QuasiTriangularZero::~QuasiTriangularZero() +{ +} + +void QuasiTriangularZero::solvePre(Vector& x, double& eig_min) +{ + Vector xu(x, 0, nz); + Vector xl(x, nz, x.length()-nz); + QuasiTriangular::solvePre(xl, eig_min); + ru.multsVec(xu, xl); + if (nz > 0) + eig_min = (eig_min > 1.0)? 1.0 : eig_min; +} + +void QuasiTriangularZero::solvePreTrans(Vector& x, double& eig_min) +{ + Vector xu(x, 0, nz); + Vector xl(x, nz, x.length()-nz); + ru.multsVecTrans(xl, xu); + QuasiTriangular::solvePreTrans(xl, eig_min); + if (nz > 0) + eig_min = (eig_min > 1.0)? 1.0 : eig_min; +} + +void QuasiTriangularZero::multVec(Vector& x, const ConstVector& b) const +{ + x.zeros(); + multaVec(x, b); +} + +void QuasiTriangularZero::multVecTrans(Vector& x, const ConstVector& b) const +{ + x.zeros(); + multaVecTrans(x, b); +} + +void QuasiTriangularZero::multaVec(Vector& x, const ConstVector& b) const +{ + ConstVector bl(b, nz, b.length()-nz); + Vector xu(x, 0, nz); + Vector xl(x, nz, x.length()-nz); + xu.zeros(); + ru.multaVec(xu, bl); + QuasiTriangular::multVec(xl, bl); +} + +void QuasiTriangularZero::multaVecTrans(Vector& x, const ConstVector& b) const +{ + ConstVector bu(b, 0, b.length()); + ConstVector bl(b, nz, b.length()-nz); + Vector xu(x, 0, nz); + Vector xl(x, nz, x.length()-nz); + xu.zeros(); + QuasiTriangular::multVecTrans(xl, bl); + ru.multaVecTrans(xl, bu); +} + +void QuasiTriangularZero::multLeftOther(GeneralMatrix& a) const +{ + GeneralMatrix a1(a, 0, 0, nz, a.numCols()); + GeneralMatrix a2(a, nz, 0, a.numRows()-nz, a.numCols()); + a1.mult(ru, a2); + QuasiTriangular::multLeftOther(a2); +} + +void QuasiTriangularZero::print() const +{ + printf("super=\n"); + QuasiTriangular::print(); + printf("nz=%d\n",nz); + printf("ru=\n"); + ru.print(); +} + +void QuasiTriangularZero::multKron(KronVector& x) const +{ + throw SYLV_MES_EXCEPTION("Attempt to run QuasiTriangularZero::multKron."); +} + +void QuasiTriangularZero::multKronTrans(KronVector& x) const +{ + throw SYLV_MES_EXCEPTION("Attempt to run QuasiTriangularZero::multKronTrans."); +} + diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/QuasiTriangularZero.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/QuasiTriangularZero.h new file mode 100644 index 000000000..6396eed18 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/QuasiTriangularZero.h @@ -0,0 +1,48 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/QuasiTriangularZero.h,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef QUASI_TRIANGULAR_ZERO_H +#define QUASI_TRIANGULAR_ZERO_H + +#include "QuasiTriangular.h" +#include "GeneralMatrix.h" + +class QuasiTriangularZero : public QuasiTriangular { + int nz; // number of zero columns + GeneralMatrix ru; // data in right upper part (nz,d_size) +public: + QuasiTriangularZero(int num_zeros, const double* d, int d_size); + QuasiTriangularZero(double r, const QuasiTriangularZero& t); + QuasiTriangularZero(double r, const QuasiTriangularZero& t, + double rr, const QuasiTriangularZero& tt); + QuasiTriangularZero(int p, const QuasiTriangularZero& t); + QuasiTriangularZero(const QuasiTriangular& t); + QuasiTriangularZero(const SchurDecompZero& decomp); + ~QuasiTriangularZero(); + void solvePre(Vector& x, double& eig_min); + void solvePreTrans(Vector& x, double& eig_min); + void multVec(Vector& x, const ConstVector& b) const; + void multVecTrans(Vector& x, const ConstVector& b) const; + void multaVec(Vector& x, const ConstVector& b) const; + void multaVecTrans(Vector& x, const ConstVector& b) const; + void multKron(KronVector& x) const; + void multKronTrans(KronVector& x) const; + void multLeftOther(GeneralMatrix& a) const; + /* clone */ + virtual QuasiTriangular* clone() const + {return new QuasiTriangularZero(*this);} + virtual QuasiTriangular* clone(int p, const QuasiTriangular& t) const + {return new QuasiTriangularZero(p, (const QuasiTriangularZero&)t);} + virtual QuasiTriangular* clone(double r) const + {return new QuasiTriangularZero(r, *this);} + virtual QuasiTriangular* clone(double r, double rr, const QuasiTriangular& tt) const + {return new QuasiTriangularZero(r, *this, rr, (const QuasiTriangularZero&)tt);} + void print() const; +}; + +#endif /* QUASI_TRIANGULAR_ZERO_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecomp.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecomp.cpp new file mode 100644 index 000000000..63fe59ceb --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecomp.cpp @@ -0,0 +1,71 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SchurDecomp.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "SchurDecomp.h" + +#include "cpplapack.h" + +SchurDecomp::SchurDecomp(const SqSylvMatrix& m) + : q_destroy(true), t_destroy(true) +{ + int rows = m.numRows(); + q = new SqSylvMatrix(rows); + SqSylvMatrix auxt(m); + int sdim; + double* const wr = new double[rows]; + double* const wi = new double[rows]; + int lwork = 6*rows; + double* const work = new double[lwork]; + int info; + LAPACK_dgees("V", "N", 0, &rows, auxt.base(), &rows, &sdim, + wr, wi, q->base(), &rows, + work, &lwork, 0, &info); + delete [] work; + delete [] wi; + delete [] wr; + t = new QuasiTriangular(auxt.base(), rows); +} + +SchurDecomp::SchurDecomp(const QuasiTriangular& tr) + : q_destroy(true), t_destroy(true) +{ + q = new SqSylvMatrix(tr.numRows()); + q->setUnit(); + t = new QuasiTriangular(tr); +} + +SchurDecomp::SchurDecomp(QuasiTriangular& tr) + : q_destroy(true), t_destroy(false) +{ + q = new SqSylvMatrix(tr.numRows()); + q->setUnit(); + t = &tr; +} + +SchurDecomp::~SchurDecomp() +{ + if (t_destroy) + delete t; + if (q_destroy) + delete q; +} + +int SchurDecomp::getDim() const +{ + return t->numRows(); +} + +SchurDecompZero::SchurDecompZero(const GeneralMatrix& m) + : SchurDecomp(SqSylvMatrix(m, m.numRows()-m.numCols(), 0, m.numCols())), + ru(m, 0, 0, m.numRows()-m.numCols(), m.numCols()) +{ + ru.multRight(getQ()); +} + +int SchurDecompZero::getDim() const +{ + return getT().numRows()+ru.numRows(); +} + + diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecomp.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecomp.h new file mode 100644 index 000000000..644e5d5c5 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecomp.h @@ -0,0 +1,43 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SchurDecomp.h,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef SCHUR_DECOMP_H +#define SCHUR_DECOMP_H + +#include "SylvMatrix.h" +#include "QuasiTriangular.h" + +class QuasiTriangular; +class SchurDecomp { + bool q_destroy; + SqSylvMatrix* q; + bool t_destroy; + QuasiTriangular* t; +public: + SchurDecomp(const SqSylvMatrix& m); + SchurDecomp(const QuasiTriangular& tr); + SchurDecomp(QuasiTriangular& tr); + const SqSylvMatrix& getQ() const {return *q;} + const QuasiTriangular& getT() const {return *t;} + SqSylvMatrix& getQ() {return *q;} + QuasiTriangular& getT() {return *t;} + virtual int getDim() const; + virtual ~SchurDecomp(); +}; + +class SchurDecompZero : public SchurDecomp { + GeneralMatrix ru; /* right upper matrix */ +public: + SchurDecompZero(const GeneralMatrix& m); + const GeneralMatrix& getRU() const {return ru;} + int getDim() const; + int getZeroCols() const {return ru.numRows();} +}; + +#endif /* SCHUR_DECOMP_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecompEig.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecompEig.cpp new file mode 100644 index 000000000..623ad3c5a --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecompEig.cpp @@ -0,0 +1,91 @@ +#include "SchurDecompEig.h" +#include "SylvException.h" +#include "cpplapack.h" + +/* bubble diagonal 1-1, or 2-2 block from position 'from' to position + * 'to'. If an eigenvalue cannot be swapped with its neighbour, the + * neighbour is bubbled also in front. The method returns a new + * position 'to', where the original block pointed by 'to' happens to + * appear at the end. 'from' must be greater than 'to'. + */ +SchurDecompEig::diag_iter +SchurDecompEig::bubbleEigen(diag_iter from, diag_iter to) +{ + diag_iter run = from; + while (run != to) { + diag_iter runm = run; + if (!tryToSwap(run, runm) && runm == to) { + ++to; + } else { + // bubble all eigenvalues from runm(incl.) to run(excl.), + // this includes either bubbling generated eigenvalues due + // to split, or an eigenvalue which couldn't be swapped + while (runm != run) { + to = bubbleEigen(runm, to); + ++runm; + } + } + } + return to; +} + +/* this tries to swap two neighbouring eigenvalues, 'it' and '--it', + * and returns 'itadd'. If the blocks can be swapped, new eigenvalues + * can emerge due to possible 2-2 block splits. 'it' then points to + * the last eigenvalue coming from block pointed by 'it' at the + * begining, and 'itadd' points to the first. On swap failure, 'it' is + * not changed, and 'itadd' points to previous eignevalue (which must + * be moved backwards before). In either case, it is necessary to + * resolve eigenvalues from 'itadd' to 'it', before the 'it' can be + * resolved. + * The success is signaled by returned true. + */ +bool SchurDecompEig::tryToSwap(diag_iter& it, diag_iter& itadd) +{ + itadd = it; + --itadd; + + int n = getDim(); + int ifst = (*it).getIndex() + 1; + int ilst = (*itadd).getIndex() + 1; + double* work = new double[n]; + int info; + LAPACK_dtrexc("V", &n, getT().base(), &n, getQ().base(), &n, &ifst, &ilst, work, + &info); + delete [] work; + if (info < 0) { + throw SYLV_MES_EXCEPTION("Wrong argument to LAPACK_dtrexc."); + } + + if (info == 0) { + // swap successful + getT().swapDiagLogically(itadd); + //check for 2-2 block splits + getT().checkDiagConsistency(it); + getT().checkDiagConsistency(itadd); + // and go back by 'it' in NEW eigenvalue set + --it; + return true; + } + return false; +} + + +void SchurDecompEig::orderEigen() +{ + diag_iter run = getT().diag_begin(); + diag_iter runp = run; + ++runp; + double last_size = 0.0; + while (runp != getT().diag_end()) { + diag_iter least = getT().findNextLargerBlock(run, getT().diag_end(), + last_size); + last_size = (*least).getSize(); + if (run == least) + ++run; + else + run = bubbleEigen(least, run); + runp = run; + ++runp; + } +} diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecompEig.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecompEig.h new file mode 100644 index 000000000..0e0da38d5 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SchurDecompEig.h @@ -0,0 +1,31 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SchurDecompEig.h,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */ + +/* Tag $Name: $ */ + +// contains algorithms for eigenvalue reordering + +#ifndef SCHUR_DECOMP_EIG_H +#define SCHUR_DECOMP_EIG_H + +#include "SchurDecomp.h" +#include "QuasiTriangular.h" + +class SchurDecompEig : public SchurDecomp { +public: + typedef QuasiTriangular::diag_iter diag_iter; + SchurDecompEig(const SqSylvMatrix& m) : SchurDecomp(m) {} + SchurDecompEig(const QuasiTriangular& tr) : SchurDecomp(tr) {}; + SchurDecompEig(QuasiTriangular& tr) : SchurDecomp(tr) {} + diag_iter bubbleEigen(diag_iter from, diag_iter to); + void orderEigen(); +protected: + bool tryToSwap(diag_iter& it, diag_iter& itadd); +}; + +#endif /* SCHUR_DECOMP_EIG_H */ + + +// Local Variables: +// mode:C++ +// End: + diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SimilarityDecomp.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/SimilarityDecomp.cpp new file mode 100644 index 000000000..3b62e957f --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SimilarityDecomp.cpp @@ -0,0 +1,160 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SimilarityDecomp.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "SimilarityDecomp.h" +#include "SchurDecomp.h" +#include "SchurDecompEig.h" +#include "SylvException.h" + +#include "cpplapack.h" + +#include + +SimilarityDecomp::SimilarityDecomp(const double* d, int d_size, double log10norm) +{ + SchurDecomp sd(SqSylvMatrix(d, d_size)); + q = new SqSylvMatrix(sd.getQ()); + b = new BlockDiagonal(sd.getT()); + invq = new SqSylvMatrix(d_size); + invq->setUnit(); + invq->multLeftTrans(sd.getQ()); + double norm = pow(10.0, log10norm); + diagonalize(norm); +} + +SimilarityDecomp::~SimilarityDecomp() +{ + delete invq; + delete b; + delete q; +} + +void SimilarityDecomp::getXDim(diag_iter start, diag_iter end, + int &rows, int& cols) const +{ + int si = (*start).getIndex(); + int ei = (*end).getIndex(); + cols = b->numRows() - ei; + rows = ei - si; +} + +/* find solution of X for diagonal block given by start(incl.) and + * end(excl.). If the solution cannot be found, or it is greater than + * norm, X is not changed and flase is returned. + */ +bool SimilarityDecomp::solveX(diag_iter start, diag_iter end, + GeneralMatrix& X, double norm) const +{ + int si = (*start).getIndex(); + int ei = (*end).getIndex(); + + SqSylvMatrix A((const GeneralMatrix&)*b, si, si, X.numRows()); + SqSylvMatrix B((const GeneralMatrix&)*b, ei, ei, X.numCols()); + GeneralMatrix C((const GeneralMatrix&)*b, si, ei, X.numRows(), X.numCols()); + + int isgn = -1; + int m = A.numRows(); + int n = B.numRows(); + double scale; + int info; + LAPACK_dtrsyl("N", "N", &isgn, &m, &n, A.base(), &m, B.base(), &n, + C.base(), &m, &scale, &info); + if (info < -1) + throw SYLV_MES_EXCEPTION("Wrong parameter to LAPACK dtrsyl."); + + if (info == 1 || scale < 1) + return false; + if (C.getData().getMax() > norm) + return false; + + X = C; + return true; +} + +/* multiply Q and invQ with (I -X; 0 I), and (I X; 0 I). This also sets X=-X. */ +void SimilarityDecomp::updateTransform(diag_iter start, diag_iter end, + GeneralMatrix& X) +{ + int si = (*start).getIndex(); + int ei = (*end).getIndex(); + + SqSylvMatrix iX(q->numRows()); + iX.setUnit(); + iX.place(X, si, ei); + invq->GeneralMatrix::multLeft(iX); + + iX.setUnit(); + X.mult(-1.0); + iX.place(X, si, ei); + q->multRight(iX); +} + +void SimilarityDecomp::bringGuiltyBlock(diag_iter start, diag_iter& end) +{ + double av = b->getAverageDiagSize(start, end); + diag_iter guilty = b->findClosestDiagBlock(end, b->diag_end(), av); + SchurDecompEig sd((QuasiTriangular&)*b); // works on b including diagonal structure + end = sd.bubbleEigen(guilty, end); // iterators are valid + ++end; + q->multRight(sd.getQ()); + invq->multLeftTrans(sd.getQ()); +} + +void SimilarityDecomp::diagonalize(double norm) +{ + diag_iter start = b->diag_begin(); + diag_iter end = start; + ++end; + + while (end != b->diag_end()) { + int xrows; + int xcols; + getXDim(start, end, xrows, xcols); + GeneralMatrix X(xrows, xcols); + if (solveX(start, end, X, norm)) { + updateTransform(start, end, X); + b->setZeroBlockEdge(end); + start = end; + ++end; + } else { + bringGuiltyBlock(start, end); // moves with end + } + } +} + +void SimilarityDecomp::check(SylvParams& pars, const GeneralMatrix& m) const +{ + // M - Q*B*inv(Q) + SqSylvMatrix c(getQ(), getB()); + c.multRight(getInvQ()); + c.add(-1.0, m); + pars.f_err1 = c.getNorm1(); + pars.f_errI = c.getNormInf(); + + // I - Q*inv(Q) + c.setUnit(); + c.mult(-1); + c.multAndAdd(getQ(), getInvQ()); + pars.viv_err1 = c.getNorm1(); + pars.viv_errI = c.getNormInf(); + + // I - inv(Q)*Q + c.setUnit(); + c.mult(-1); + c.multAndAdd(getInvQ(), getQ()); + pars.ivv_err1 = c.getNorm1(); + pars.ivv_errI = c.getNormInf(); +} + +void SimilarityDecomp::infoToPars(SylvParams& pars) const +{ + pars.f_blocks = getB().getNumBlocks(); + pars.f_largest = getB().getLargestBlock(); + pars.f_zeros = getB().getNumZeros(); + pars.f_offdiag = getB().getNumOffdiagonal(); +} + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SimilarityDecomp.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/SimilarityDecomp.h new file mode 100644 index 000000000..14f79297a --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SimilarityDecomp.h @@ -0,0 +1,41 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SimilarityDecomp.h,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef SIMILARITY_DECOMP_H +#define SIMILARITY_DECOMP_H + +#include "SylvMatrix.h" +#include "BlockDiagonal.h" +#include "SylvParams.h" + +class SimilarityDecomp { + SqSylvMatrix* q; + BlockDiagonal* b; + SqSylvMatrix* invq; + typedef BlockDiagonal::diag_iter diag_iter; +public: + SimilarityDecomp(const double* d, int d_size, double log10norm = 3.0); + virtual ~SimilarityDecomp(); + const SqSylvMatrix& getQ() const + {return *q;} + const SqSylvMatrix& getInvQ() const + {return *invq;} + const BlockDiagonal& getB() const + {return *b;} + void check(SylvParams& pars, const GeneralMatrix& m) const; + void infoToPars(SylvParams& pars) const; +protected: + void getXDim(diag_iter start, diag_iter end, int& rows, int& cols) const; + bool solveX(diag_iter start, diag_iter end, GeneralMatrix& X, double norm) const; + void updateTransform(diag_iter start, diag_iter end, GeneralMatrix& X); + void bringGuiltyBlock(diag_iter start, diag_iter& end); + void diagonalize(double norm); +}; + +#endif /* SIMILARITY_DECOMP_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvException.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvException.cpp new file mode 100644 index 000000000..71466ea5e --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvException.cpp @@ -0,0 +1,69 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvException.cpp,v 1.2 2004/10/01 10:30:40 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "SylvException.h" + +#include +#include + +SylvException::SylvException(const char* f, int l, const SylvException* s) +{ + strcpy(file,f); + line = l; + source = s; +} + +SylvException::~SylvException() +{ + if (source != NULL) { + delete source; + } +} + +void SylvException::printMessage() const +{ + char mes[1500]; + mes[0] = '\0'; + printMessage(mes, 1499); + printf(mes); +} + +int SylvException::printMessage(char* str, int maxlen) const +{ + int remain = maxlen; + if (source != NULL) { + remain = source->printMessage(str, maxlen); + } + char aux[100]; + sprintf(aux, "From %s:%d\n", file, line); + int newremain = remain - strlen(aux); + if (newremain < 0) { + aux[remain] = '\0'; + newremain = 0; + } + strcat(str, aux); + return newremain; +} + +SylvExceptionMessage::SylvExceptionMessage(const char* f, int i, + const char* mes) + : SylvException(f,i,NULL) +{ + strcpy(message,mes); +} + +int SylvExceptionMessage::printMessage(char* str, int maxlen) const +{ + char aux[600]; + sprintf(aux, "At %s:%d:%s\n", file, line, message); + int newremain = maxlen - strlen(aux); + if (newremain < 0) { + aux[maxlen] = '\0'; + newremain = 0; + } + strcat(str, aux); + return newremain; +} + + diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvException.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvException.h new file mode 100644 index 000000000..f3c22338a --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvException.h @@ -0,0 +1,39 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvException.h,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef SYLV_EXCEPTION_H +#define SYLV_EXCEPTION_H + +#include "SylvMemory.h" + + +class SylvException : public MallocAllocator { +protected: + char file[50]; + int line; + const SylvException* source; +public: + SylvException(const char* f, int l, const SylvException* s); + virtual ~SylvException(); + virtual int printMessage(char* str, int maxlen) const; + void printMessage() const; +}; + +class SylvExceptionMessage : public SylvException { + char message[500]; +public: + SylvExceptionMessage(const char* f, int l, const char* mes); + virtual int printMessage(char* str, int maxlen) const; +}; + +// define macros: +#define SYLV_EXCEPTION(exc) (SylvException(__FILE__, __LINE__, exc)) +#define SYLV_MES_EXCEPTION(mes) (SylvExceptionMessage(__FILE__, __LINE__, mes)) + +#endif /* SYLV_EXCEPTION_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMatrix.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMatrix.cpp new file mode 100644 index 000000000..e228d73a9 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMatrix.cpp @@ -0,0 +1,251 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvMatrix.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "SylvException.h" +#include "SylvMatrix.h" + +#include "cppblas.h" +#include "cpplapack.h" + +#include +#include +#include + +void SylvMatrix::multLeftI(const SqSylvMatrix& m) +{ + int off = rows - m.numRows(); + if (off < 0) { + throw SYLV_MES_EXCEPTION("Wrong matrix dimensions for multLeftI."); + } + GeneralMatrix subtmp(*this, off, 0, m.numRows(), cols); + subtmp.multLeft(m); +} + +void SylvMatrix::multLeftITrans(const SqSylvMatrix& m) +{ + int off = rows - m.numRows(); + if (off < 0) { + throw SYLV_MES_EXCEPTION("Wrong matrix dimensions for multLeftITrans."); + } + GeneralMatrix subtmp(*this, off, 0, m.numRows(), cols); + subtmp.multLeftTrans(m); +} + + +void SylvMatrix::multLeft(int zero_cols, const GeneralMatrix& a, const GeneralMatrix& b) +{ + int off = a.numRows() - a.numCols(); + if (off < 0 || a.numRows() != rows || off != zero_cols || + rows != b.numRows() || cols != b.numCols()) { + throw SYLV_MES_EXCEPTION("Wrong matrix dimensions for multLeft."); + } + // here we cannot call SylvMatrix::gemm since it would require + // another copy of (usually big) b (we are not able to do inplace + // submatrix of const GeneralMatrix) + if (a.getLD() > 0 && ld > 0) { + int mm = a.numRows(); + int nn = cols; + int kk = a.numCols(); + double alpha = 1.0; + int lda = a.getLD(); + int ldb = ld; + double beta = 0.0; + int ldc = ld; + BLAS_dgemm("N", "N", &mm, &nn, &kk, &alpha, a.getData().base(), &lda, + b.getData().base()+off, &ldb, &beta, data.base(), &ldc); + } +} + + +void SylvMatrix::multRightKron(const SqSylvMatrix& m, int order) +{ + if (power(m.numRows(), order) != cols) { + throw SYLV_MES_EXCEPTION("Wrong number of cols for right kron multiply."); + } + KronVector auxrow(m.numRows(), m.numRows(), order-1); + for (int i = 0; i < rows; i++) { + Vector rowi(data.base()+i, rows, cols); + KronVector rowikron(rowi, m.numRows(), m.numRows(), order-1); + auxrow = rowi; // copy data + m.multVecKronTrans(rowikron, auxrow); + } +} + +void SylvMatrix::multRightKronTrans(const SqSylvMatrix& m, int order) +{ + if (power(m.numRows(), order) != cols) { + throw SYLV_MES_EXCEPTION("Wrong number of cols for right kron multiply."); + } + + KronVector auxrow(m.numRows(), m.numRows(), order-1); + for (int i = 0; i < rows; i++) { + Vector rowi(data.base()+i, rows, cols); + KronVector rowikron(rowi, m.numRows(), m.numRows(), order-1); + auxrow = rowi; // copy data + m.multVecKron(rowikron, auxrow); + } +} + +void SylvMatrix::eliminateLeft(int row, int col, Vector& x) +{ + double d = get(col, col); + double e = get(row, col); + if (std::abs(d) > std::abs(e)) { + get(row, col) = 0.0; + double mult = e/d; + for (int i = col + 1; i < numCols(); i++) { + get(row, i) = get(row, i) - mult*get(col, i); + } + x[row] = x[row] - mult*x[col]; + } else if (std::abs(e) > std::abs(d)) { + get(row, col) = 0.0; + get(col, col) = e; + double mult = d/e; + for (int i = col + 1; i < numCols(); i++) { + double tx = get(col, i); + double ty = get(row, i); + get(col, i) = ty; + get(row, i) = tx - mult*ty; + } + double tx = x[col]; + double ty = x[row]; + x[col] = ty; + x[row] = tx - mult*ty; + } +} + +void SylvMatrix::eliminateRight(int row, int col, Vector& x) +{ + double d = get(row, row); + double e = get(row, col); + + if (std::abs(d) > std::abs(e)) { + get(row, col) = 0.0; + double mult = e/d; + for (int i = 0; i < row; i++) { + get(i, col) = get(i, col) - mult*get(i, row); + } + x[col] = x[col] - mult*x[row]; + } else if (std::abs(e) > std::abs(d)) { + get(row, col) = 0.0; + get(row, row) = e; + double mult = d/e; + for (int i = 0; i < row; i++) { + double tx = get(i, row); + double ty = get(i, col); + get(i, row) = ty; + get(i, col) = tx - mult*ty; + } + double tx = x[row]; + double ty = x[col]; + x[row] = ty; + x[col] = tx - mult*ty; + } +} + + + +SqSylvMatrix::SqSylvMatrix(const GeneralMatrix& a, const GeneralMatrix& b) + : SylvMatrix(a,b) +{ + if (rows != cols) + throw SYLV_MES_EXCEPTION("Wrong matrix dimensions in multiplication constructor of square matrix."); +} + +void SqSylvMatrix::multVecKron(KronVector& x, const KronVector& d) const +{ + x.zeros(); + if (d.getDepth() == 0) { + multaVec(x, d); + } else { + KronVector aux(x.getM(), x.getN(), x.getDepth()); + for (int i = 0; i < x.getM(); i++) { + KronVector auxi(aux, i); + ConstKronVector di(d, i); + multVecKron(auxi, di); + } + for (int i = 0; i < rows; i++) { + KronVector xi(x, i); + for (int j = 0; j < cols; j++) { + KronVector auxj(aux, j); + xi.add(get(i,j),auxj); + } + } + } +} + + +void SqSylvMatrix::multVecKronTrans(KronVector& x, const KronVector& d) const +{ + x.zeros(); + if (d.getDepth() == 0) { + multaVecTrans(x, d); + } else { + KronVector aux(x.getM(), x.getN(), x.getDepth()); + for (int i = 0; i < x.getM(); i++) { + KronVector auxi(aux, i); + ConstKronVector di(d, i); + multVecKronTrans(auxi, di); + } + for (int i = 0; i < rows; i++) { + KronVector xi(x, i); + for (int j = 0; j < cols; j++) { + KronVector auxj(aux, j); + xi.add(get(j,i), auxj); + } + } + } +} + +void SqSylvMatrix::multInvLeft2(GeneralMatrix& a, GeneralMatrix& b, + double& rcond1, double& rcondinf) const +{ + if (rows != a.numRows() || rows != b.numRows()) { + throw SYLV_MES_EXCEPTION("Wrong dimensions for multInvLeft2."); + } + // PLU factorization + Vector inv(data); + int * const ipiv = new int[rows]; + int info; + LAPACK_dgetrf(&rows, &rows, inv.base(), &rows, ipiv, &info); + // solve a + int acols = a.numCols(); + double* abase = a.base(); + LAPACK_dgetrs("N", &rows, &acols, inv.base(), &rows, ipiv, + abase, &rows, &info); + // solve b + int bcols = b.numCols(); + double* bbase = b.base(); + LAPACK_dgetrs("N", &rows, &bcols, inv.base(), &rows, ipiv, + bbase, &rows, &info); + delete [] ipiv; + + // condition numbers + double* const work = new double[4*rows]; + int* const iwork = new int[rows]; + double norm1 = getNorm1(); + LAPACK_dgecon("1", &rows, inv.base(), &rows, &norm1, &rcond1, + work, iwork, &info); + double norminf = getNormInf(); + LAPACK_dgecon("I", &rows, inv.base(), &rows, &norminf, &rcondinf, + work, iwork, &info); + delete [] iwork; + delete [] work; +} + +void SqSylvMatrix::setUnit() +{ + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (i==j) + get(i,j) = 1.0; + else + get(i,j) = 0.0; + } + } +} + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMatrix.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMatrix.h new file mode 100644 index 000000000..99ab504ae --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMatrix.h @@ -0,0 +1,81 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvMatrix.h,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef SYLV_MATRIX_H +#define SYLV_MATRIX_H + +#include "GeneralMatrix.h" +#include "KronVector.h" + +class SqSylvMatrix; + +class SylvMatrix : public GeneralMatrix { +public: + SylvMatrix(int m, int n) + : GeneralMatrix(m,n) {} + SylvMatrix(const double* d, int m, int n) + : GeneralMatrix(d, m, n) {} + SylvMatrix(double* d, int m, int n) + : GeneralMatrix(d, m, n) {} + SylvMatrix(const GeneralMatrix& m) + : GeneralMatrix(m) {} + SylvMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols) + : GeneralMatrix(m, i, j, nrows, ncols) {} + SylvMatrix(GeneralMatrix& m, int i, int j, int nrows, int ncols) + : GeneralMatrix(m, i, j, nrows, ncols) {} + SylvMatrix(const GeneralMatrix& a, const GeneralMatrix& b) + : GeneralMatrix(a, b) {} + + /* this = |I 0|* this + |0 m| */ + void multLeftI(const SqSylvMatrix& m); + /* this = |I 0|* this + |0 m'| */ + void multLeftITrans(const SqSylvMatrix& m); + /* this = |0 a|*b, so that |0 a| is square */ + void multLeft(int zero_cols, const GeneralMatrix& a, const GeneralMatrix& b); + /* this = this * (m\otimes m..\otimes m) */ + void multRightKron(const SqSylvMatrix& m, int order); + /* this = this * (m'\otimes m'..\otimes m') */ + void multRightKronTrans(const SqSylvMatrix& m, int order); + /* this = P*this, x = P*x, where P is gauss transformation setting + * a given element to zero */ + void eliminateLeft(int row, int col, Vector& x); + /* this = this*P, x = P'*x, where P is gauss transformation setting + * a given element to zero */ + void eliminateRight(int row, int col, Vector& x); +}; + + +class SqSylvMatrix : public SylvMatrix { +public: + SqSylvMatrix(int m) : SylvMatrix(m, m) {} + SqSylvMatrix(const double* d, int m) : SylvMatrix(d, m, m) {} + SqSylvMatrix(double* d, int m) : SylvMatrix(d, m, m) {} + SqSylvMatrix(const SqSylvMatrix& m) : SylvMatrix(m) {} + SqSylvMatrix(const GeneralMatrix& m, int i, int j, int nrows) + : SylvMatrix(m, i, j, nrows, nrows) {} + SqSylvMatrix(GeneralMatrix& m, int i, int j, int nrows) + : SylvMatrix(m, i, j, nrows, nrows) {} + SqSylvMatrix(const GeneralMatrix& a, const GeneralMatrix& b); + const SqSylvMatrix& operator=(const SqSylvMatrix& m) + {GeneralMatrix::operator=(m); return *this;} + /* x = (this \otimes this..\otimes this)*d */ + void multVecKron(KronVector& x, const KronVector& d) const; + /* x = (this' \otimes this'..\otimes this')*d */ + void multVecKronTrans(KronVector& x, const KronVector& d) const; + /* a = inv(this)*a, b=inv(this)*b */ + void multInvLeft2(GeneralMatrix& a, GeneralMatrix& b, + double& rcond1, double& rcondinf) const; + /* this = I */ + void setUnit(); +}; + + +#endif /* SYLV_MATRIX_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMemory.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMemory.cpp new file mode 100644 index 000000000..d9f7efa1a --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMemory.cpp @@ -0,0 +1,221 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvMemory.cpp,v 1.1.1.1 2004/06/04 13:00:49 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "SylvMemory.h" +#include "SylvException.h" +#include "KronVector.h" + +#ifdef MATLAB +#include "mex.h" +#endif + +#include +#include +#include + +/**********************************************************/ +/* SylvMemoryPool */ +/**********************************************************/ + +SylvMemoryPool memory_pool; + +SylvMemoryPool::SylvMemoryPool() + : base(0), length(0), allocated(0), stack_mode(false) +{ +} + +void SylvMemoryPool::init(size_t size) +{ +#ifdef USE_MEMORY_POOL + length = size; + +#ifdef MATLAB + if (base) + throw SYLV_MES_EXCEPTION("Attempt to use matlab memory pool twice."); + base = (char*) mxMalloc(length); +#else + base = (char*) malloc(length); +#endif + +#else + throw SYLV_MES_EXCEPTION("SylvMemoryPool::init() called for non memory pool code."); +#endif +} + +void* SylvMemoryPool::allocate(size_t size) +{ +#ifdef USE_MEMORY_POOL + if (allocated + size < length) { + char* res = base + allocated; + allocated += size; + return res; + } else { + throw SYLV_MES_EXCEPTION("Run out of memory space"); + } +#else + throw SYLV_MES_EXCEPTION("SylvMemoryPool::allocate() called for non memory pool code."); +#endif +} + +void SylvMemoryPool::free(void* p) +{ +#ifdef USE_MEMORY_POOL + int offset = ((char*)p) - base; + +#ifdef DEBUG + if (offset < 0) + throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() frees wrong address < begin."); + if (offset >= (int)length) + throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() frees wrong address > end."); +#endif + + if (stack_mode && offset >= 0 && offset < (int)allocated) + allocated = offset; + +#else + throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() called for non memory pool code."); +#endif +} + +void SylvMemoryPool::setStackMode(bool mode) +{ + stack_mode = mode; +} + +SylvMemoryPool::~SylvMemoryPool() +{ + reset(); +} + +void SylvMemoryPool::reset() +{ +#ifndef MATLAB + delete [] base; + base = 0; + allocated = 0; + length = 0; + stack_mode = false; +#endif +} + +/**********************************************************/ +/* global new and delete */ +/**********************************************************/ + +#ifdef USE_MEMORY_POOL + +void* operator new(size_t size) +{ + return memory_pool.allocate(size); +} + +void* operator new[](size_t size) +{ + return memory_pool.allocate(size); +} + +void operator delete(void* p) +{ + memory_pool.free(p); +} + +void operator delete[](void* p) +{ + memory_pool.free(p); +} + +#endif + +/**********************************************************/ +/* saved version of global new and delete */ +/**********************************************************/ + +#ifdef USE_MEMORY_POOL +void* MallocAllocator::operator new(size_t size) +{ +#ifdef MATLAB + throw SYLV_MES_EXCEPTION("Attempt to call wrong memory allocator."); +#else + void* res = malloc(size); + if (!res) + throw SYLV_MES_EXCEPTION("Malloc unable to allocate memory."); + return res; +#endif +} + +void* MallocAllocator::operator new[](size_t size) +{ +#ifdef MATLAB + throw SYLV_MES_EXCEPTION("Attempt to call wrong memory allocator."); +#else + void* res = malloc(size); + if (!res) + throw SYLV_MES_EXCEPTION("Malloc unable allocate memory."); + return res; +#endif +} + +void MallocAllocator::operator delete(void* p) +{ +#ifdef MATLAB + throw SYLV_MES_EXCEPTION("Attempt to call wrong memory destructor."); +#else + free(p); +#endif +} + +void MallocAllocator::operator delete[](void* p) +{ +#ifdef MATLAB + throw SYLV_MES_EXCEPTION("Attempt to call wrong memory destructor."); +#else + free(p); +#endif +} + +#endif + + +/**********************************************************/ +/* SylvMemoryDriver */ +/**********************************************************/ + +void SylvMemoryDriver::allocate(int num_d, int m, int n, int order) +{ +#ifdef USE_MEMORY_POOL + int x_cols = power(m,order); + int total = num_d*x_cols*n; // storage for big matrices + total += x_cols; // storage for one extra row of a big matrix + int dig_vectors = (int)ceil(((double)(power(m,order)-1))/(m-1)); + total += 8*n*dig_vectors; // storage for kron vectors instantiated during solv + total += 50*(m*m+n*n); // some storage for small square matrices + total *= sizeof(double); // everything in doubles + memory_pool.init(total); +#endif +} + + +SylvMemoryDriver::SylvMemoryDriver(int num_d, int m, int n, int order) +{ + allocate(num_d, m, n, order); +} + +SylvMemoryDriver::SylvMemoryDriver(const SylvParams& pars, int num_d, + int m, int n, int order) +{ + if (*(pars.method) == SylvParams::iter) + num_d++; + if (*(pars.want_check)) + num_d++; + allocate(num_d, m, n, order); +} + +SylvMemoryDriver::~SylvMemoryDriver() +{ + memory_pool.reset(); +} + +void SylvMemoryDriver::setStackMode(bool mode) { + memory_pool.setStackMode(mode); +} diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMemory.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMemory.h new file mode 100644 index 000000000..187aac0b5 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvMemory.h @@ -0,0 +1,63 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvMemory.h,v 1.1.1.1 2004/06/04 13:00:49 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef SYLV_MEMORY_H +#define SYLV_MEMORY_H + +#include "SylvParams.h" + +#include + +class MallocAllocator { +#ifdef USE_MEMORY_POOL +public: + void* operator new(size_t size); + void* operator new[](size_t size); + void operator delete(void* p); + void operator delete[](void* p); +#endif +}; + +#ifdef USE_MEMORY_POOL +void* operator new(size_t size); +void* operator new[](size_t size); +void operator delete(void* p); +void operator delete[](void* p); +#endif + +class SylvMemoryPool { + char* base; + size_t length; + size_t allocated; + bool stack_mode; + SylvMemoryPool(const SylvMemoryPool&); + const SylvMemoryPool& operator=(const SylvMemoryPool&); +public: + SylvMemoryPool(); + ~SylvMemoryPool(); + void init(size_t size); + void* allocate(size_t size); + void free(void* p); + void reset(); + void setStackMode(bool); +}; + +class SylvMemoryDriver { + SylvMemoryDriver(const SylvMemoryDriver&); + const SylvMemoryDriver& operator=(const SylvMemoryDriver&); +public: + SylvMemoryDriver(int num_d, int m, int n, int order); + SylvMemoryDriver(const SylvParams& pars, int num_d, int m, int n, int order); + static void setStackMode(bool); + ~SylvMemoryDriver(); +protected: + void allocate(int num_d, int m, int n, int order); +}; + +#endif /* SYLV_MEMORY_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvParams.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvParams.cpp new file mode 100644 index 000000000..9c00a438d --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvParams.cpp @@ -0,0 +1,230 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvParams.cpp,v 1.1.1.1 2004/06/04 13:00:52 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "SylvParams.h" + + +void SylvParams::print(const char* prefix) const +{ + print(stdout, prefix); +} + +void SylvParams::print(FILE* fdesc, const char* prefix) const +{ + rcondA1.print(fdesc, prefix, "reci. cond1 A ", "%8.4g"); + rcondAI.print(fdesc, prefix, "reci. condInf A ", "%8.4g"); + bs_norm.print(fdesc, prefix, "log10 diag norm ", "%8.4g"); + f_err1.print(fdesc, prefix, "abs. err 1 F diag ", "%8.4g"); + f_errI.print(fdesc, prefix, "abs. err I F diag ", "%8.4g"); + viv_err1.print(fdesc, prefix, "abs. err 1 V*invV ", "%8.4g"); + viv_errI.print(fdesc, prefix, "abs. err I V*invV ", "%8.4g"); + ivv_err1.print(fdesc, prefix, "abs. err 1 invV*V ", "%8.4g"); + ivv_errI.print(fdesc, prefix, "abs. err I invV*V ", "%8.4g"); + f_blocks.print(fdesc, prefix, "num blocks in F ", "%d"); + f_largest.print(fdesc, prefix,"largest block in F ", "%d"); + f_zeros.print(fdesc, prefix, "num zeros in F ", "%d"); + f_offdiag.print(fdesc, prefix,"num offdiag in F ", "%d"); + if (*method == iter) { + converged.print(fdesc, prefix, "converged ", "%d"); + convergence_tol.print(fdesc, prefix, "convergence tol. ", "%8.4g"); + iter_last_norm.print(fdesc, prefix, "last norm ", "%8.4g"); + max_num_iter.print(fdesc, prefix, "max num iter ", "%d"); + num_iter.print(fdesc, prefix, "num iter ", "%d"); + } else { + eig_min.print(fdesc, prefix, "minimum eigenvalue ", "%8.4g"); + } + mat_err1.print(fdesc, prefix, "rel. matrix norm1 ", "%8.4g"); + mat_errI.print(fdesc, prefix, "rel. matrix normInf", "%8.4g"); + mat_errF.print(fdesc, prefix, "rel. matrix normFro", "%8.4g"); + vec_err1.print(fdesc, prefix, "rel. vector norm1 ", "%8.4g"); + vec_errI.print(fdesc, prefix, "rel. vector normInf", "%8.4g"); + cpu_time.print(fdesc, prefix, "time (CPU secs) ", "%8.4g"); +} + +void SylvParams::copy(const SylvParams& p) +{ + method = p.method; + convergence_tol = p.convergence_tol; + max_num_iter = p.max_num_iter; + bs_norm = p.bs_norm; + want_check = p.want_check; + converged = p.converged; + iter_last_norm = p.iter_last_norm; + num_iter = p.num_iter; + f_err1 = p.f_err1; + f_errI = p.f_errI; + viv_err1 = p.viv_err1; + viv_errI = p.viv_errI; + ivv_err1 = p.ivv_err1; + ivv_errI = p.ivv_errI; + f_blocks = p.f_blocks; + f_largest = p.f_largest; + f_zeros = p.f_zeros; + f_offdiag = p.f_offdiag; + rcondA1 = p.rcondA1; + rcondAI = p.rcondAI; + eig_min = p.eig_min; + mat_err1 = p.mat_err1; + mat_errI = p.mat_errI; + mat_errF = p.mat_errF; + vec_err1 = p.vec_err1; + vec_errI = p.vec_errI; + cpu_time = p.cpu_time; +} + +void SylvParams::setArrayNames(int& num, const char** names) const +{ + num = 0; + if (method.getStatus() != undef) + names[num++] = "method"; + if (convergence_tol.getStatus() != undef) + names[num++] = "convergence_tol"; + if (max_num_iter.getStatus() != undef) + names[num++] = "max_num_iter"; + if (bs_norm.getStatus() != undef) + names[num++] = "bs_norm"; + if (converged.getStatus() != undef) + names[num++] = "converged"; + if (iter_last_norm.getStatus() != undef) + names[num++] = "iter_last_norm"; + if (num_iter.getStatus() != undef) + names[num++] = "num_iter"; + if (f_err1.getStatus() != undef) + names[num++] = "f_err1"; + if (f_errI.getStatus() != undef) + names[num++] = "f_errI"; + if (viv_err1.getStatus() != undef) + names[num++] = "viv_err1"; + if (viv_errI.getStatus() != undef) + names[num++] = "viv_errI"; + if (ivv_err1.getStatus() != undef) + names[num++] = "ivv_err1"; + if (ivv_errI.getStatus() != undef) + names[num++] = "ivv_errI"; + if (f_blocks.getStatus() != undef) + names[num++] = "f_blocks"; + if (f_largest.getStatus() != undef) + names[num++] = "f_largest"; + if (f_zeros.getStatus() != undef) + names[num++] = "f_zeros"; + if (f_offdiag.getStatus() != undef) + names[num++] = "f_offdiag"; + if (rcondA1.getStatus() != undef) + names[num++] = "rcondA1"; + if (rcondAI.getStatus() != undef) + names[num++] = "rcondAI"; + if (eig_min.getStatus() != undef) + names[num++] = "eig_min"; + if (mat_err1.getStatus() != undef) + names[num++] = "mat_err1"; + if (mat_errI.getStatus() != undef) + names[num++] = "mat_errI"; + if (mat_errF.getStatus() != undef) + names[num++] = "mat_errF"; + if (vec_err1.getStatus() != undef) + names[num++] = "vec_err1"; + if (vec_errI.getStatus() != undef) + names[num++] = "vec_errI"; + if (cpu_time.getStatus() != undef) + names[num++] = "cpu_time"; +} + +#ifdef MATLAB +mxArray* SylvParams::DoubleParamItem::createMatlabArray() const +{ + return mxCreateScalarDouble(value); +} + +mxArray* SylvParams::IntParamItem::createMatlabArray() const +{ + mxArray* res = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL); + *((int*)mxGetData(res)) = value; + return res; +} + +mxArray* SylvParams::BoolParamItem::createMatlabArray() const +{ + if (value) + return mxCreateString("true"); + else + return mxCreateString("false"); +} + +mxArray* SylvParams::MethodParamItem::createMatlabArray() const +{ + if (value == iter) + return mxCreateString("iterative"); + else + return mxCreateString("recursive"); +} + +mxArray* SylvParams::createStructArray() const +{ + const char* names[50]; + int num; + setArrayNames(num, names); + const int dims[] = {1, 1}; + mxArray* const res = mxCreateStructArray(2, dims, num, names); + + int i = 0; + if (method.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, method.createMatlabArray()); + if (convergence_tol.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, convergence_tol.createMatlabArray()); + if (max_num_iter.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, max_num_iter.createMatlabArray()); + if (bs_norm.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, bs_norm.createMatlabArray()); + if (converged.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, converged.createMatlabArray()); + if (iter_last_norm.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, iter_last_norm.createMatlabArray()); + if (num_iter.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, num_iter.createMatlabArray()); + if (f_err1.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, f_err1.createMatlabArray()); + if (f_errI.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, f_errI.createMatlabArray()); + if (viv_err1.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, viv_err1.createMatlabArray()); + if (viv_errI.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, viv_errI.createMatlabArray()); + if (ivv_err1.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, ivv_err1.createMatlabArray()); + if (ivv_errI.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, ivv_errI.createMatlabArray()); + if (f_blocks.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, f_blocks.createMatlabArray()); + if (f_largest.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, f_largest.createMatlabArray()); + if (f_zeros.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, f_zeros.createMatlabArray()); + if (f_offdiag.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, f_offdiag.createMatlabArray()); + if (rcondA1.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, rcondA1.createMatlabArray()); + if (rcondAI.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, rcondAI.createMatlabArray()); + if (eig_min.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, eig_min.createMatlabArray()); + if (mat_err1.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, mat_err1.createMatlabArray()); + if (mat_errI.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, mat_errI.createMatlabArray()); + if (mat_errF.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, mat_errF.createMatlabArray()); + if (vec_err1.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, vec_err1.createMatlabArray()); + if (vec_errI.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, vec_errI.createMatlabArray()); + if (cpu_time.getStatus() != undef) + mxSetFieldByNumber(res, 0, i++, cpu_time.createMatlabArray()); + + return res; +} +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvParams.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvParams.h new file mode 100644 index 000000000..afb5b874a --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvParams.h @@ -0,0 +1,162 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvParams.h,v 1.1.1.1 2004/06/04 13:00:54 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef SYLV_PARAMS_H +#define SYLV_PARAMS_H + +#include +#include + +#ifdef MATLAB +#include "mex.h" +#endif + +typedef enum {def, changed, undef} status; + +template +struct ParamItem { +protected: + typedef ParamItem<_Type> _Self; + status s; + _Type value; +public: + ParamItem() + {s = undef;} + ParamItem(_Type val) + {value = val; s = def;} + ParamItem(const _Self& item) + {value = item.value; s = item.s;} + const _Self& operator=(const _Self& item) + {value = item.value; s = item.s; return *this;} + const _Self& operator=(const _Type& val) + {value = val; s = changed; return *this;} + _Type operator*() const + {return value;} + status getStatus() const + {return s;} + void print(FILE* f, const char* prefix, const char* str, const char* fmt) const + { + if (s == undef) + return; + char out[1000]; + strcpy(out, prefix); + strcat(out, str); + strcat(out, "= "); + strcat(out, fmt); + if (s == def) + strcat(out, " "); + strcat(out,"\n"); + fprintf(f, out, value); + } +}; + +class SylvParams { +public: + typedef enum {iter, recurse} solve_method; + +protected: + class DoubleParamItem : public ParamItem { + public: + DoubleParamItem() : ParamItem() {} + DoubleParamItem(double val) : ParamItem(val) {} + DoubleParamItem(const DoubleParamItem& item) : ParamItem(item) {} + const DoubleParamItem& operator=(const double& val) + {ParamItem::operator=(val); return *this;} +#ifdef MATLAB + mxArray* createMatlabArray() const; +#endif + }; + + class IntParamItem : public ParamItem { + public: + IntParamItem() : ParamItem() {} + IntParamItem(int val) : ParamItem(val) {} + IntParamItem(const IntParamItem& item) : ParamItem(item) {} + const IntParamItem& operator=(const int& val) + {ParamItem::operator=(val); return *this;} +#ifdef MATLAB + mxArray* createMatlabArray() const; +#endif + }; + + class BoolParamItem : public ParamItem { + public: + BoolParamItem() : ParamItem() {} + BoolParamItem(bool val) : ParamItem(val) {} + BoolParamItem(const BoolParamItem& item) : ParamItem(item) {} + const BoolParamItem& operator=(const bool& val) + {ParamItem::operator=(val); return *this;} +#ifdef MATLAB + mxArray* createMatlabArray() const; +#endif + }; + + class MethodParamItem : public ParamItem { + public: + MethodParamItem() : ParamItem() {} + MethodParamItem(solve_method val) : ParamItem(val) {} + MethodParamItem(const MethodParamItem& item) : ParamItem(item) {} + const MethodParamItem operator=(const solve_method& val) + {ParamItem::operator=(val); return *this;} +#ifdef MATLAB + mxArray* createMatlabArray() const; +#endif + }; + +public: + // input parameters + MethodParamItem method; // method of solution: iter/recurse + DoubleParamItem convergence_tol; // norm for what we consider converged + IntParamItem max_num_iter; // max number of iterations + DoubleParamItem bs_norm; // Bavely Stewart log10 of norm for diagonalization + BoolParamItem want_check; // true => allocate extra space for checks + // output parameters + BoolParamItem converged; // true if converged + DoubleParamItem iter_last_norm; // norm of the last iteration + IntParamItem num_iter; // number of iterations + DoubleParamItem f_err1; // norm 1 of diagonalization abs. error C-V*F*inv(V) + DoubleParamItem f_errI; // norm Inf of diagonalization abs. error C-V*F*inv(V) + DoubleParamItem viv_err1; // norm 1 of error I-V*inv(V) + DoubleParamItem viv_errI; // norm Inf of error I-V*inv(V) + DoubleParamItem ivv_err1; // norm 1 of error I-inv(V)*V + DoubleParamItem ivv_errI; // norm Inf of error I-inv(V)*V + IntParamItem f_blocks; // number of diagonal blocks of F + IntParamItem f_largest; // size of largest diagonal block in F + IntParamItem f_zeros; // number of off diagonal zeros in F + IntParamItem f_offdiag; // number of all off diagonal elements in F + DoubleParamItem rcondA1; // reciprocal cond 1 number of A + DoubleParamItem rcondAI; // reciprocal cond Inf number of A + DoubleParamItem eig_min; // minimum eigenvalue of the solved system + DoubleParamItem mat_err1; // rel. matrix 1 norm of A*X-B*X*kron(C,..,C)-D + DoubleParamItem mat_errI; // rel. matrix Inf norm of A*X-B*X*kron(C,..,C)-D + DoubleParamItem mat_errF; // rel. matrix Frob. norm of A*X-B*X*kron(C,..,C)-D + DoubleParamItem vec_err1; // rel. vector 1 norm of A*X-B*X*kron(C,..,C)-D + DoubleParamItem vec_errI; // rel. vector Inf norm of A*X-B*X*kron(C,..,C)-D + DoubleParamItem cpu_time; // time of the job in CPU seconds + // note: remember to change copy() if adding/removing member + + SylvParams(bool wc = false) + : method(recurse), convergence_tol(1.e-30), max_num_iter(15), + bs_norm(1.3), want_check(wc) {} + SylvParams(const SylvParams& p) + {copy(p);} + const SylvParams& operator=(const SylvParams& p) + {copy(p); return *this;} + ~SylvParams() {} + void print(const char* prefix) const; + void print(FILE* fdesc, const char* prefix) const; + void setArrayNames(int& num, const char** names) const; +#ifdef MATLAB + mxArray* createStructArray() const; +#endif +private: + void copy(const SylvParams& p); +}; + +#endif /* SYLV_PARAMS_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvesterSolver.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvesterSolver.h new file mode 100644 index 000000000..df9bcce45 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SylvesterSolver.h @@ -0,0 +1,51 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvesterSolver.h,v 1.1.1.1 2004/06/04 13:00:54 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef SYLVESTER_SOLVER_H +#define SYLVESTER_SOLVER_H + +#include "KronVector.h" +#include "QuasiTriangular.h" +#include "QuasiTriangularZero.h" +#include "SimilarityDecomp.h" +#include "SylvParams.h" +#include "SchurDecomp.h" + +class SylvesterSolver { +protected: + const QuasiTriangular* const matrixK; + const QuasiTriangular* const matrixF; +private: + /* return true when it is more efficient to use QuasiTriangular + * than QuasiTriangularZero */ + static bool zeroPad(const SchurDecompZero& kdecomp) { + return ((kdecomp.getZeroCols()*3 < kdecomp.getDim()*2) || + (kdecomp.getZeroCols() < 10)); + } +public: + SylvesterSolver(const QuasiTriangular& k, const QuasiTriangular& f) + : matrixK(new QuasiTriangular(k)), + matrixF(new QuasiTriangular(f)) + {} + SylvesterSolver(const SchurDecompZero& kdecomp, const SchurDecomp& fdecomp) + : matrixK((zeroPad(kdecomp)) ? + new QuasiTriangular(kdecomp) : new QuasiTriangularZero(kdecomp)), + matrixF(new QuasiTriangular(fdecomp)) + {} + SylvesterSolver(const SchurDecompZero& kdecomp, const SimilarityDecomp& fdecomp) + : matrixK((zeroPad(kdecomp)) ? + new QuasiTriangular(kdecomp) : new QuasiTriangularZero(kdecomp)), + matrixF(new BlockDiagonal(fdecomp.getB())) + {} + virtual ~SylvesterSolver() + {delete matrixK; delete matrixF;} + virtual void solve(SylvParams& pars, KronVector& x) const = 0; +}; + +#endif /* SYLVESTER_SOLVER_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SymSchurDecomp.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/SymSchurDecomp.cpp new file mode 100644 index 000000000..3c11314ac --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SymSchurDecomp.cpp @@ -0,0 +1,101 @@ +/* $Header$ */ + +/* Tag $Name$ */ + +#include "SymSchurDecomp.h" +#include "SylvException.h" + +#include "cpplapack.h" + +#include +#include + +SymSchurDecomp::SymSchurDecomp(const GeneralMatrix& mata) + : lambda(mata.numRows()), q(mata.numRows()) +{ + // check mata is square + if (mata.numRows() != mata.numCols()) + throw SYLV_MES_EXCEPTION("Matrix is not square in SymSchurDecomp constructor"); + + // prepare for dsyevr + const char* jobz = "V"; + const char* range = "A"; + const char* uplo = "U"; + int n = mata.numRows(); + GeneralMatrix tmpa(mata); + double* a = tmpa.base(); + int lda = tmpa.getLD(); + double dum; + double* vl = &dum; + double* vu = &dum; + int idum; + int* il = &idum; + int* iu = &idum; + double abstol = 0.0; + int m = n; + double* w = lambda.base(); + double* z = q.base(); + int ldz = q.getLD(); + int* isuppz = new int[2*std::max(1,m)]; + double tmpwork; + int lwork = -1; + int tmpiwork; + int liwork = -1; + int info; + + // query for lwork and liwork + LAPACK_dsyevr(jobz, range, uplo, &n, a, &lda, vl, vu, il, iu, &abstol, + &m, w, z, &ldz, isuppz, &tmpwork, &lwork, &tmpiwork, &liwork, &info); + lwork = (int)tmpwork; + liwork = tmpiwork; + // allocate work arrays + double* work = new double[lwork]; + int* iwork = new int[liwork]; + + // do the calculation + LAPACK_dsyevr(jobz, range, uplo, &n, a, &lda, vl, vu, il, iu, &abstol, + &m, w, z, &ldz, isuppz, work, &lwork, iwork, &liwork, &info); + + if (info < 0) + throw SYLV_MES_EXCEPTION("Internal error in SymSchurDecomp constructor"); + if (info > 0) + throw SYLV_MES_EXCEPTION("Internal LAPACK error in DSYEVR"); + + delete [] work; + delete [] iwork; + delete [] isuppz; +} + +void SymSchurDecomp::getFactor(GeneralMatrix& f) const +{ + if (f.numRows() != q.numRows()) + throw SYLV_MES_EXCEPTION("Wrong dimension of factor matrix in SymSchurDecomp::getFactor"); + if (f.numRows() != f.numCols()) + throw SYLV_MES_EXCEPTION("Factor matrix is not square in SymSchurDecomp::getFactor"); + if (! isPositiveSemidefinite()) + throw SYLV_MES_EXCEPTION("Symmetric decomposition not positive semidefinite in SymSchurDecomp::getFactor"); + + f = q; + for (int i = 0; i < f.numCols(); i++) { + Vector fi(f, i); + fi.mult(std::sqrt(lambda[i])); + } +} + + +// LAPACK says that eigenvalues are ordered in ascending order, but we +// do not rely her on it +bool SymSchurDecomp::isPositiveSemidefinite() const +{ + for (int i = 0; i < lambda.length(); i++) + if (lambda[i] < 0) + return false; + return true; +} + +void SymSchurDecomp::correctDefinitness(double tol) +{ + for (int i = 0; i < lambda.length(); i++) + if (lambda[i] < 0 && lambda[i] > - tol) + lambda[i] = 0.0; +} diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/SymSchurDecomp.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/SymSchurDecomp.h new file mode 100644 index 000000000..784042111 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/SymSchurDecomp.h @@ -0,0 +1,41 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SchurDecomp.h,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef SYM_SCHUR_DECOMP_H +#define SYM_SCHUR_DECOMP_H + +#include "SylvMatrix.h" + +class SymSchurDecomp { +protected: + Vector lambda; + SqSylvMatrix q; +public: + /** Calculates A = Q*Lambda*Q^T, where A is assummed to be + * symmetric and Lambda real diagonal, hence a vector. */ + SymSchurDecomp(const GeneralMatrix& a); + SymSchurDecomp(const SymSchurDecomp& ssd) + : lambda(ssd.lambda), q(ssd.q) {} + virtual ~SymSchurDecomp() {} + const Vector& getLambda() const + {return lambda;} + const SqSylvMatrix& getQ() const + {return q;} + /** Return factor F*F^T = A, raises and exception if A is not + * positive semidefinite, F must be square. */ + void getFactor(GeneralMatrix& f) const; + /** Returns true if A is positive semidefinite. */ + bool isPositiveSemidefinite() const; + /** Correct definitness. This sets all eigenvalues between minus + * tolerance and zero to zero. */ + void correctDefinitness(double tol); + +}; + +#endif + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/TriangularSylvester.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/TriangularSylvester.cpp new file mode 100644 index 000000000..64471afe8 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/TriangularSylvester.cpp @@ -0,0 +1,392 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/TriangularSylvester.cpp,v 1.1.1.1 2004/06/04 13:00:59 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "TriangularSylvester.h" +#include "QuasiTriangularZero.h" +#include "KronUtils.h" +#include "BlockDiagonal.h" + +#include +#include + +double TriangularSylvester::diag_zero = 1.e-15; +double TriangularSylvester::diag_zero_sq = 1.e-30; + +TriangularSylvester::TriangularSylvester(const QuasiTriangular& k, + const QuasiTriangular& f) + : SylvesterSolver(k, f), + matrixKK(matrixK->clone(2, *matrixK)), + matrixFF(new QuasiTriangular(2, *matrixF)) +{ +} + +TriangularSylvester::TriangularSylvester(const SchurDecompZero& kdecomp, + const SchurDecomp& fdecomp) + : SylvesterSolver(kdecomp, fdecomp), + matrixKK(matrixK->clone(2, *matrixK)), + matrixFF(new QuasiTriangular(2, *matrixF)) +{ +} + +TriangularSylvester::TriangularSylvester(const SchurDecompZero& kdecomp, + const SimilarityDecomp& fdecomp) + : SylvesterSolver(kdecomp, fdecomp), + matrixKK(matrixK->clone(2, *matrixK)), + matrixFF(new BlockDiagonal(2, *matrixF)) +{ +} + +TriangularSylvester::~TriangularSylvester() +{ + delete matrixKK; + delete matrixFF; +} + +void TriangularSylvester::print() const +{ + printf("matrix K (%d):\n",matrixK->getDiagonal().getSize()); + matrixK->print(); + printf("matrix F (%d):\n",matrixF->getDiagonal().getSize()); + matrixF->print(); +} + +void TriangularSylvester::solve(SylvParams& pars, KronVector& d) const +{ + double eig_min = 1e30; + solvi(1., d, eig_min); + pars.eig_min = sqrt(eig_min); +} + +void TriangularSylvester::solvi(double r, KronVector& d, double& eig_min) const +{ + if (d.getDepth() == 0) { + QuasiTriangular* t = matrixK->clone(r); + t->solvePre(d, eig_min); + delete t; + } else { + for (const_diag_iter di = matrixF->diag_begin(); + di != matrixF->diag_end(); + ++di) { + if ((*di).isReal()) { + solviRealAndEliminate(r, di, d, eig_min); + } else { + solviComplexAndEliminate(r, di, d, eig_min); + } + } + } +} + + +void TriangularSylvester::solvii(double alpha, double beta1, double beta2, + KronVector& d1, KronVector& d2, + double& eig_min) const +{ + KronVector d1tmp(d1); + KronVector d2tmp(d2); + linEval(alpha, beta1, beta2, d1, d2, d1tmp, d2tmp); + solviip(alpha, beta1*beta2, d1, eig_min); + solviip(alpha, beta1*beta2, d2, eig_min); +} + + +void TriangularSylvester::solviip(double alpha, double betas, + KronVector& d, double& eig_min) const +{ + // quick exit to solvi if betas is small + if (betas < diag_zero_sq) { + solvi(alpha, d, eig_min); + solvi(alpha, d, eig_min); + return; + } + + if (d.getDepth() == 0) { + double aspbs = alpha*alpha+betas; + QuasiTriangular* t= matrixK->clone(2*alpha, aspbs, *matrixKK); + t->solvePre(d, eig_min); + delete t; + } else { + const_diag_iter di = matrixF->diag_begin(); + const_diag_iter dsi = matrixFF->diag_begin(); + for (; di != matrixF->diag_end(); ++di, ++dsi) { + if ((*di).isReal()) { + solviipRealAndEliminate(alpha, betas, di, dsi, d, eig_min); + } else { + solviipComplexAndEliminate(alpha, betas, di, dsi, d, eig_min); + } + } + } +} + + +void TriangularSylvester::solviRealAndEliminate(double r, const_diag_iter di, + KronVector& d, double& eig_min) const +{ + // di is real + int jbar = (*di).getIndex(); + double f = *((*di).getAlpha()); + KronVector dj(d, jbar); + // solve system + if (abs(r*f) > diag_zero) { + solvi(r*f, dj, eig_min); + } + // calculate y + KronVector y((const KronVector&)dj); + KronUtils::multKron(*matrixF, *matrixK, y); + y.mult(r); + double divisor = 1.0; + solviEliminateReal(di, d, y, divisor); +} + +void TriangularSylvester::solviEliminateReal(const_diag_iter di, KronVector& d, + const KronVector& y, double divisor) const +{ + for (const_row_iter ri = matrixF->row_begin(*di); + ri != matrixF->row_end(*di); + ++ri) { + KronVector dk(d, ri.getCol()); + dk.add(-(*ri)/divisor, y); + } +} + +void TriangularSylvester::solviComplexAndEliminate(double r, const_diag_iter di, + KronVector& d, double& eig_min) const +{ + // di is complex + int jbar = (*di).getIndex(); + // pick data + double alpha = *(*di).getAlpha(); + double beta1 = (*di).getBeta2(); + double beta2 = -(*di).getBeta1(); + double aspbs = (*di).getDeterminant(); + KronVector dj(d, jbar); + KronVector djj(d, jbar+1); + // solve + if (r*r*aspbs > diag_zero_sq) { + solvii(r*alpha, r*beta1, r*beta2, dj, djj, eig_min); + } + KronVector y1(dj); + KronVector y2(djj); + KronUtils::multKron(*matrixF, *matrixK, y1); + KronUtils::multKron(*matrixF, *matrixK, y2); + y1.mult(r); + y2.mult(r); + double divisor = 1.0; + solviEliminateComplex(di, d, y1, y2, divisor); +} + +void TriangularSylvester::solviEliminateComplex(const_diag_iter di, KronVector& d, + const KronVector& y1, const KronVector& y2, + double divisor) const +{ + for (const_row_iter ri = matrixF->row_begin(*di); + ri != matrixF->row_end(*di); + ++ri) { + KronVector dk(d, ri.getCol()); + dk.add(-ri.a()/divisor, y1); + dk.add(-ri.b()/divisor, y2); + } +} + +void TriangularSylvester::solviipRealAndEliminate(double alpha, double betas, + const_diag_iter di, const_diag_iter dsi, + KronVector& d, double& eig_min) const +{ + // di, and dsi are real + int jbar = (*di).getIndex(); + double aspbs = alpha*alpha+betas; + // pick data + double f = *((*di).getAlpha()); + double fs = f*f; + KronVector dj(d, jbar); + // solve + if (fs*aspbs > diag_zero_sq) { + solviip(f*alpha, fs*betas, dj, eig_min); + } + KronVector y1((const KronVector&)dj); + KronVector y2((const KronVector&)dj); + KronUtils::multKron(*matrixF, *matrixK, y1); + y1.mult(2*alpha); + KronUtils::multKron(*matrixFF, *matrixKK, y2); + y2.mult(aspbs); + double divisor = 1.0; + double divisor2 = 1.0; + solviipEliminateReal(di, dsi, d, y1, y2, divisor, divisor2); +} + +void TriangularSylvester::solviipEliminateReal(const_diag_iter di, const_diag_iter dsi, + KronVector& d, + const KronVector& y1, const KronVector& y2, + double divisor, double divisor2) const +{ + const_row_iter ri = matrixF->row_begin(*di); + const_row_iter rsi = matrixFF->row_begin(*dsi); + for (; ri != matrixF->row_end(*di); ++ri, ++rsi) { + KronVector dk(d, ri.getCol()); + dk.add(-(*ri)/divisor, y1); + dk.add(-(*rsi)/divisor2, y2); + } +} + +void TriangularSylvester::solviipComplexAndEliminate(double alpha, double betas, + const_diag_iter di, const_diag_iter dsi, + KronVector& d, double& eig_min) const +{ + // di, and dsi are complex + int jbar = (*di).getIndex(); + double aspbs = alpha*alpha+betas; + // pick data + double gamma = *((*di).getAlpha()); + double delta1 = (*di).getBeta2(); // swap because of transpose + double delta2 = -(*di).getBeta1(); + double gspds = (*di).getDeterminant(); + KronVector dj(d, jbar); + KronVector djj(d, jbar+1); + if (gspds*aspbs > diag_zero_sq) { + solviipComplex(alpha, betas, gamma, delta1, delta2, dj, djj, eig_min); + } + // here dj, djj is solution, set y1, y2, y11, y22 + // y1 + KronVector y1((const KronVector&) dj); + KronUtils::multKron(*matrixF, *matrixK, y1); + y1.mult(2*alpha); + // y11 + KronVector y11((const KronVector&) djj); + KronUtils::multKron(*matrixF, *matrixK, y11); + y11.mult(2*alpha); + // y2 + KronVector y2((const KronVector&) dj); + KronUtils::multKron(*matrixFF, *matrixKK, y2); + y2.mult(aspbs); + // y22 + KronVector y22((const KronVector&) djj); + KronUtils::multKron(*matrixFF, *matrixKK, y22); + y22.mult(aspbs); + + double divisor = 1.0; + solviipEliminateComplex(di, dsi, d, y1, y11, y2, y22, divisor); +} + + +void TriangularSylvester::solviipComplex(double alpha, double betas, double gamma, + double delta1, double delta2, + KronVector& d1, KronVector& d2, + double& eig_min) const +{ + KronVector d1tmp(d1); + KronVector d2tmp(d2); + quaEval(alpha, betas, gamma, delta1, delta2, + d1, d2, d1tmp, d2tmp); + double delta = sqrt(delta1*delta2); + double beta = sqrt(betas); + double a1 = alpha*gamma - beta*delta; + double b1 = alpha*delta + gamma*beta; + double a2 = alpha*gamma + beta*delta; + double b2 = alpha*delta - gamma*beta; + solviip(a2, b2*b2, d1, eig_min); + solviip(a1, b1*b1, d1, eig_min); + solviip(a2, b2*b2, d2, eig_min); + solviip(a1, b1*b1, d2, eig_min); +} + +void TriangularSylvester::solviipEliminateComplex(const_diag_iter di, const_diag_iter dsi, + KronVector& d, + const KronVector& y1, const KronVector& y11, + const KronVector& y2, const KronVector& y22, + double divisor) const +{ + const_row_iter ri = matrixF->row_begin(*di); + const_row_iter rsi = matrixFF->row_begin(*dsi); + for (; ri != matrixF->row_end(*di); ++ri, ++rsi) { + KronVector dk(d, ri.getCol()); + dk.add(-ri.a()/divisor, y1); + dk.add(-ri.b()/divisor, y11); + dk.add(-rsi.a()/divisor, y2); + dk.add(-rsi.b()/divisor, y22); + } +} + +void TriangularSylvester::linEval(double alpha, double beta1, double beta2, + KronVector& x1, KronVector& x2, + const ConstKronVector& d1, const ConstKronVector& d2) const +{ + KronVector d1tmp(d1); // make copy + KronVector d2tmp(d2); // make copy + KronUtils::multKron(*matrixF, *matrixK, d1tmp); + KronUtils::multKron(*matrixF, *matrixK, d2tmp); + x1 = d1; + x2 = d2; + Vector::mult2a(alpha, beta1, -beta2, x1, x2, d1tmp, d2tmp); +} + +void TriangularSylvester::quaEval(double alpha, double betas, + double gamma, double delta1, double delta2, + KronVector& x1, KronVector& x2, + const ConstKronVector& d1, const ConstKronVector& d2) const +{ + KronVector d1tmp(d1); // make copy + KronVector d2tmp(d2); // make copy + KronUtils::multKron(*matrixF, *matrixK, d1tmp); + KronUtils::multKron(*matrixF, *matrixK, d2tmp); + x1 = d1; + x2 = d2; + Vector::mult2a(2*alpha*gamma, 2*alpha*delta1, -2*alpha*delta2, + x1, x2, d1tmp, d2tmp); + d1tmp = d1; // restore to d1 + d2tmp = d2; // restore to d2 + KronUtils::multKron(*matrixFF, *matrixKK, d1tmp); + KronUtils::multKron(*matrixFF, *matrixKK, d2tmp); + double aspbs = alpha*alpha + betas; + double gspds = gamma*gamma - delta1*delta2; + Vector::mult2a(aspbs*gspds, 2*aspbs*gamma*delta1, -2*aspbs*gamma*delta2, + x1, x2, d1tmp, d2tmp); +} + + +double TriangularSylvester::getEigSep(int depth) const +{ + int f_size = matrixF->getDiagonal().getSize(); + Vector feig(2*f_size); + matrixF->getDiagonal().getEigenValues(feig); + int k_size = matrixK->getDiagonal().getSize(); + Vector keig(2*k_size); + matrixK->getDiagonal().getEigenValues(keig); + + KronVector eig(f_size, 2*k_size, depth); + multEigVector(eig, feig, keig); + + double min = 1.0e20; + for (int i = 0; i < eig.length()/2; i++) { + double alpha = eig[2*i]; + double beta = eig[2*i+1]; + double ss = (alpha+1)*(alpha+1)+beta*beta; + if (min > ss) + min = ss; + } + + return min; +} + +void TriangularSylvester::multEigVector(KronVector& eig, const Vector& feig, + const Vector& keig) +{ + int depth = eig.getDepth(); + int m = eig.getM(); + int n = eig.getN(); + + if (depth == 0) { + eig = keig; + } else { + KronVector aux(m, n, depth-1); + multEigVector(aux, feig, keig); + for (int i = 0; i < m; i++) { + KronVector eigi(eig, i); + eigi.zeros(); + eigi.add(&feig[2*i], aux); + } + } +} + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/TriangularSylvester.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/TriangularSylvester.h new file mode 100644 index 000000000..b4908729e --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/TriangularSylvester.h @@ -0,0 +1,115 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/TriangularSylvester.h,v 1.1.1.1 2004/06/04 13:01:03 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef TRIANGULAR_SYLVESTER_H +#define TRIANGULAR_SYLVESTER_H + +#include "SylvesterSolver.h" +#include "KronVector.h" +#include "QuasiTriangular.h" +#include "QuasiTriangularZero.h" +#include "SimilarityDecomp.h" + +class TriangularSylvester : public SylvesterSolver { + const QuasiTriangular* const matrixKK; + const QuasiTriangular* const matrixFF; +public: + TriangularSylvester(const QuasiTriangular& k, const QuasiTriangular& f); + TriangularSylvester(const SchurDecompZero& kdecomp, const SchurDecomp& fdecomp); + TriangularSylvester(const SchurDecompZero& kdecomp, const SimilarityDecomp& fdecomp); + virtual ~TriangularSylvester(); + void print() const; + void solve(SylvParams& pars, KronVector& d) const; + + void solvi(double r, KronVector& d, double& eig_min) const; + void solvii(double alpha, double beta1, double beta2, + KronVector& d1, KronVector& d2, + double& eig_min) const; + void solviip(double alpha, double betas, + KronVector& d, double& eig_min) const; + /* evaluates: + |x1| |d1| |alpha -beta1| |d1| + | | = | |+| |\otimes F'...\otimes K | | + |x2| |d2| |beta2 alpha| |d2| + */ + void linEval(double alpha, double beta1, double beta2, + KronVector& x1, KronVector& x2, + const ConstKronVector& d1, const ConstKronVector& d2) const; + void linEval(double alpha, double beta1, double beta2, + KronVector& x1, KronVector& x2, + const KronVector& d1, const KronVector& d2) const + {linEval(alpha, beta1, beta2, x1, x2, + ConstKronVector(d1), ConstKronVector(d2));} + + /* evaluates: + |x1| |d1| |gamma -delta1| |d1| + | | = | | + 2alpha*| |\otimes F'...\otimes K | | + + |x2| |d2| |delta2 gamma| |d2| + + |gamma -delta1|^2 |d1| + + (alpha^2+betas)*| |\otimes F'2...\otimes K2 | | + |delta2 gamma| |d2| + */ + void quaEval(double alpha, double betas, + double gamma, double delta1, double delta2, + KronVector& x1, KronVector& x2, + const ConstKronVector& d1, const ConstKronVector& d2) const; + void quaEval(double alpha, double betas, + double gamma, double delta1, double delta2, + KronVector& x1, KronVector& x2, + const KronVector& d1, const KronVector& d2) const + {quaEval(alpha, betas, gamma, delta1, delta2, x1, x2, + ConstKronVector(d1), ConstKronVector(d2));} +private: + /* returns square of size of minimal eigenvalue of the system solved, + now obsolete */ + double getEigSep(int depth) const; + /* recursivelly calculates kronecker product of complex vectors (used in getEigSep) */ + static void multEigVector(KronVector& eig, const Vector& feig, const Vector& keig); + /* auxiliary typedefs */ + typedef QuasiTriangular::const_diag_iter const_diag_iter; + typedef QuasiTriangular::const_row_iter const_row_iter; + /* called from solvi */ + void solviRealAndEliminate(double r, const_diag_iter di, + KronVector& d, double& eig_min) const; + void solviComplexAndEliminate(double r, const_diag_iter di, + KronVector& d, double& eig_min) const; + /* called from solviip */ + void solviipRealAndEliminate(double alpha, double betas, + const_diag_iter di, const_diag_iter dsi, + KronVector& d, double& eig_min) const; + void solviipComplexAndEliminate(double alpha, double betas, + const_diag_iter di, const_diag_iter dsi, + KronVector& d, double& eig_min) const; + /* eliminations */ + void solviEliminateReal(const_diag_iter di, KronVector& d, + const KronVector& y, double divisor) const; + void solviEliminateComplex(const_diag_iter di, KronVector& d, + const KronVector& y1, const KronVector& y2, + double divisor) const; + void solviipEliminateReal(const_diag_iter di, const_diag_iter dsi, + KronVector& d, + const KronVector& y1, const KronVector& y2, + double divisor, double divisor2) const; + void solviipEliminateComplex(const_diag_iter di, const_diag_iter dsi, + KronVector& d, + const KronVector& y1, const KronVector& y11, + const KronVector& y2, const KronVector& y22, + double divisor) const; + /* Lemma 2 */ + void solviipComplex(double alpha, double betas, double gamma, + double delta1, double delta2, + KronVector& d1, KronVector& d2, + double& eig_min) const; + /* norms for what we consider zero on diagonal of F */ + static double diag_zero; + static double diag_zero_sq; // square of diag_zero +}; + +#endif /* TRIANGULAR_SYLVESTER_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/Vector.cpp b/mex/sources/korderpert/Dyn_pp/sylv/cc/Vector.cpp new file mode 100644 index 000000000..22ae280fa --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/Vector.cpp @@ -0,0 +1,366 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/Vector.cpp,v 1.1.1.1 2004/06/04 13:01:13 kamenik Exp $ */ + +/* Tag $Name: $ */ + + +#include "Vector.h" +#include "GeneralMatrix.h" +#include "SylvException.h" +#include "cppblas.h" + +#include +#include +#include +#include +#include +#include + +using namespace std; + +ZeroPad zero_pad; + +Vector::Vector(const ConstVector& v) + : len(v.length()), s(1), data(new double[len]), destroy(true) +{ + copy(v.base(), v.skip()); +} + +const Vector& Vector::operator=(const Vector& v) +{ + if (this == &v) + return *this; + + if (v.length() != length()) { + throw SYLV_MES_EXCEPTION("Attempt to assign vectors with different lengths."); + } + if (s == v.s && + (data <= v.data && v.data < data+len*s || + v.data <= data && data < v.data+v.len*v.s) && + (data-v.data) % s == 0) { + printf("this destroy=%d, v destroy=%d, data-v.data=%d, len=%d\n", destroy, v.destroy, data-v.data, len); + throw SYLV_MES_EXCEPTION("Attempt to assign overlapping vectors."); + } + copy(v.base(), v.skip()); + return *this; +} + +const Vector& Vector::operator=(const ConstVector& v) +{ + if (v.length() != length()) { + throw SYLV_MES_EXCEPTION("Attempt to assign vectors with different lengths."); + } + if (v.skip() == 1 && skip() == 1 && ( + (base() < v.base() + v.length() && base() >= v.base()) || + (base() + length() < v.base() + v.length() && + base() + length() > v.base()))) { + throw SYLV_MES_EXCEPTION("Attempt to assign overlapping vectors."); + } + copy(v.base(), v.skip()); + return *this; +} + +void Vector::copy(const double* d, int inc) +{ + int n = length(); + int incy = skip(); + BLAS_dcopy(&n, d, &inc, base(), &incy); +} + +Vector::Vector(Vector& v, int off, int l) + : len(l), s(v.skip()), data(v.base()+off*v.skip()), destroy(false) +{ + if (off < 0 || off + length() > v.length()) + throw SYLV_MES_EXCEPTION("Subvector not contained in supvector."); +} + +Vector::Vector(const Vector& v, int off, int l) + : len(l), s(1), data(new double[len]), destroy(true) +{ + if (off < 0 || off + length() > v.length()) + throw SYLV_MES_EXCEPTION("Subvector not contained in supvector."); + copy(v.base()+off*v.skip(), v.skip()); +} + +Vector::Vector(GeneralMatrix& m, int col) + : len(m.numRows()), s(1), data(&(m.get(0, col))), destroy(false) +{ +} + +Vector::Vector(int row, GeneralMatrix& m) + : len(m.numCols()), s(m.getLD()), data(&(m.get(row, 0))), destroy(false) +{ +} + +bool Vector::operator==(const Vector& y) const +{ + return ConstVector(*this) == y; +} + +bool Vector::operator!=(const Vector& y) const +{ + return ConstVector(*this) != y; +} + +bool Vector::operator<(const Vector& y) const +{ + return ConstVector(*this) < y; +} + +bool Vector::operator<=(const Vector& y) const +{ + return ConstVector(*this) <= y; +} + +bool Vector::operator>(const Vector& y) const +{ + return ConstVector(*this) > y; +} + +bool Vector::operator>=(const Vector& y) const +{ + return ConstVector(*this) >= y; +} + +void Vector::zeros() +{ + if (skip() == 1) { + double* p = base(); + for (int i = 0; i < length()/ZeroPad::length; + i++, p += ZeroPad::length) + memcpy(p, zero_pad.getBase(), sizeof(double)*ZeroPad::length); + for ( ; p < base()+length(); p++) + *p = 0.0; + } else { + for (int i = 0; i < length(); i++) + operator[](i) = 0.0; + } +} + +void Vector::nans() +{ + for (int i = 0; i < length(); i++) + operator[](i) = std::numeric_limits::quiet_NaN(); +} + +void Vector::infs() +{ + for (int i = 0; i < length(); i++) + operator[](i) = std::numeric_limits::infinity(); +} + +Vector::~Vector() +{ + if (destroy) { + delete [] data; + } +} + +void Vector::rotatePair(double alpha, double beta1, double beta2, int i) +{ + double tmp = alpha*operator[](i) - beta1*operator[](i+1); + operator[](i+1) = alpha*operator[](i+1) - beta2*operator[](i); + operator[](i) = tmp; +} + +void Vector::add(double r, const Vector& v) +{ + add(r, ConstVector(v)); +} + +void Vector::add(double r, const ConstVector& v) +{ + int n = length(); + int incx = v.skip(); + int incy = skip(); + BLAS_daxpy(&n, &r, v.base(), &incx, base(), &incy); +} + +void Vector::add(const double* z, const Vector& v) +{ + add(z, ConstVector(v)); +} + +void Vector::add(const double* z, const ConstVector& v) +{ + int n = length()/2; + int incx = v.skip(); + int incy = skip(); + BLAS_zaxpy(&n, z, v.base(), &incx, base(), &incy); +} + +void Vector::mult(double r) +{ + int n = length(); + int incx = skip(); + BLAS_dscal(&n, &r, base(), &incx); +} + +void Vector::mult2(double alpha, double beta1, double beta2, + Vector& x1, Vector& x2, + const Vector& b1, const Vector& b2) +{ + x1.zeros(); + x2.zeros(); + mult2a(alpha, beta1, beta2, x1, x2, b1, b2); +} + +void Vector::mult2a(double alpha, double beta1, double beta2, + Vector& x1, Vector& x2, + const Vector& b1, const Vector& b2) +{ + x1.add(alpha, b1); + x1.add(-beta1, b2); + x2.add(alpha, b2); + x2.add(-beta2, b1); +} + +double Vector::getNorm() const +{ + ConstVector v(*this); + return v.getNorm(); +} + +double Vector::getMax() const +{ + ConstVector v(*this); + return v.getMax(); +} + +double Vector::getNorm1() const +{ + ConstVector v(*this); + return v.getNorm1(); +} + +double Vector::dot(const Vector& y) const +{ + return ConstVector(*this).dot(ConstVector(y)); +} + +bool Vector::isFinite() const +{ + return (ConstVector(*this)).isFinite(); +} + +void Vector::print() const +{ + for (int i = 0; i < length(); i++) { + printf("%d\t%8.4g\n", i, operator[](i)); + } +} + + +ConstVector::ConstVector(const Vector& v, int off, int l) + : BaseConstVector(l, v.skip(), v.base() + v.skip()*off) +{ + if (off < 0 || off + length() > v.length()) { + throw SYLV_MES_EXCEPTION("Subvector not contained in supvector."); + } +} + +ConstVector::ConstVector(const ConstVector& v, int off, int l) + : BaseConstVector(l, v.skip(), v.base() + v.skip()*off) +{ + if (off < 0 || off + length() > v.length()) { + throw SYLV_MES_EXCEPTION("Subvector not contained in supvector."); + } +} + +ConstVector::ConstVector(const double* d, int skip, int l) + : BaseConstVector(l, skip, d) +{ +} + +ConstVector::ConstVector(const ConstGeneralMatrix& m, int col) + : BaseConstVector(m.numRows(), 1, &(m.get(0, col))) +{ +} + +ConstVector::ConstVector(int row, const ConstGeneralMatrix& m) + : BaseConstVector(m.numCols(), m.getLD(), &(m.get(row, 0))) +{ +} + +bool ConstVector::operator==(const ConstVector& y) const +{ + if (length() != y.length()) + return false; + if (length() == 0) + return true; + int i = 0; + while (i < length() && operator[](i) == y[i]) + i++; + return i == length(); +} + +bool ConstVector::operator<(const ConstVector& y) const +{ + int i = std::min(length(), y.length()); + int ii = 0; + while (ii < i && operator[](ii) == y[ii]) + ii++; + if (ii < i) + return operator[](ii) < y[ii]; + else + return length() < y.length(); +} + +double ConstVector::getNorm() const +{ + double s = 0; + for (int i = 0; i < length(); i++) { + s+=operator[](i)*operator[](i); + } + return sqrt(s); +} + +double ConstVector::getMax() const +{ + double r = 0; + for (int i = 0; i < length(); i++) { + if (abs(operator[](i))>r) + r = abs(operator[](i)); + } + return r; +} + +double ConstVector::getNorm1() const +{ + double norm = 0.0; + for (int i = 0; i < length(); i++) { + norm += abs(operator[](i)); + } + return norm; +} + +double ConstVector::dot(const ConstVector& y) const +{ + if (length() != y.length()) + throw SYLV_MES_EXCEPTION("Vector has different length in ConstVector::dot."); + int n = length(); + int incx = skip(); + int incy = y.skip(); + return BLAS_ddot(&n, base(), &incx, y.base(), &incy); +} + +bool ConstVector::isFinite() const +{ + int i = 0; + while (i < length() && isfinite(operator[](i))) + i++; + return i == length(); +} + +void ConstVector::print() const +{ + for (int i = 0; i < length(); i++) { + printf("%d\t%8.4g\n", i, operator[](i)); + } +} + + +ZeroPad::ZeroPad() +{ + for (int i = 0; i < length; i++) + pad[i] = 0.0; +} diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/Vector.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/Vector.h new file mode 100644 index 000000000..405743776 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/Vector.h @@ -0,0 +1,178 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/Vector.h,v 1.1.1.1 2004/06/04 13:01:13 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef VECTOR_H +#define VECTOR_H + +/* NOTE! Vector and ConstVector have not common super class in order + * to avoid running virtual method invokation mechanism. Some + * members, and methods are thus duplicated */ + +#include + +class GeneralMatrix; +class ConstVector; + +class Vector { +protected: + int len; + int s; + double* data; + bool destroy; +public: + Vector() : len(0), s(1), data(0), destroy(false) {} + Vector(int l) : len(l), s(1), data(new double[l]), destroy(true) {} + Vector(Vector& v) : len(v.length()), s(v.skip()), data(v.base()), destroy(false) {} + Vector(const Vector& v) + : len(v.length()), s(1), data(new double[len]), destroy(true) + {copy(v.base(), v.skip());} + Vector(const ConstVector& v); + Vector(const double* d, int l) + : len(l), s(1), data(new double[len]), destroy(true) + {copy(d, 1);} + Vector(double* d, int l) + : len(l), s(1), data(d), destroy(false) {} + Vector(double* d, int skip, int l) + : len(l), s(skip), data(d), destroy(false) {} + Vector(Vector& v, int off, int l); + Vector(const Vector& v, int off, int l); + Vector(GeneralMatrix& m, int col); + Vector(int row, GeneralMatrix& m); + const Vector& operator=(const Vector& v); + const Vector& operator=(const ConstVector& v); + double& operator[](int i) + {return data[s*i];} + const double& operator[](int i) const + {return data[s*i];} + const double* base() const + {return data;} + double* base() + {return data;} + int length() const + {return len;} + int skip() const + {return s;} + + /** Exact equality. */ + bool operator==(const Vector& y) const; + bool operator!=(const Vector& y) const; + /** Lexicographic ordering. */ + bool operator<(const Vector& y) const; + bool operator<=(const Vector& y) const; + bool operator>(const Vector& y) const; + bool operator>=(const Vector& y) const; + + virtual ~Vector(); + void zeros(); + void nans(); + void infs(); + bool toBeDestroyed() const {return destroy;} + void rotatePair(double alpha, double beta1, double beta2, int i); + void add(double r, const Vector& v); + void add(double r, const ConstVector& v); + void add(const double* z, const Vector& v); + void add(const double* z, const ConstVector& v); + void mult(double r); + double getNorm() const; + double getMax() const; + double getNorm1() const; + double dot(const Vector& y) const; + bool isFinite() const; + void print() const; + + /* multiplies | alpha -beta1| |b1| |x1| + | |\otimes I .| | = | | + | -beta2 alpha| |b2| |x2| + */ + static void mult2(double alpha, double beta1, double beta2, + Vector& x1, Vector& x2, + const Vector& b1, const Vector& b2); + /* same, but adds instead of set */ + static void mult2a(double alpha, double beta1, double beta2, + Vector& x1, Vector& x2, + const Vector& b1, const Vector& b2); + /* same, but subtracts instead of add */ + static void mult2s(double alpha, double beta1, double beta2, + Vector& x1, Vector& x2, + const Vector& b1, const Vector& b2) + {mult2a(-alpha, -beta1, -beta2, x1, x2, b1, b2);} +private: + void copy(const double* d, int inc); + const Vector& operator=(int); // must not be used (not implemented) + const Vector& operator=(double); // must not be used (not implemented) +}; + + +class BaseConstVector { +protected: + int len; + int s; + const double* data; +public: + BaseConstVector(int l, int si, const double* d) : len(l), s(si), data(d) {} + BaseConstVector(const BaseConstVector& v) : len(v.len), s(v.s), data(v.data) {} + const BaseConstVector& operator=(const BaseConstVector& v) + {len = v.len; s = v.s; data = v.data; return *this;} + const double& operator[](int i) const + {return data[s*i];} + const double* base() const + {return data;} + int length() const + {return len;} + int skip() const + {return s;} +}; + +class ConstGeneralMatrix; + +class ConstVector : public BaseConstVector { +public: + ConstVector(const Vector& v) : BaseConstVector(v.length(), v.skip(), v.base()) {} + ConstVector(const ConstVector& v) : BaseConstVector(v) {} + ConstVector(const double* d, int l) : BaseConstVector(l, 1, d) {} + ConstVector(const Vector& v, int off, int l); + ConstVector(const ConstVector& v, int off, int l); + ConstVector(const double* d, int skip, int l); + ConstVector(const ConstGeneralMatrix& m, int col); + ConstVector(int row, const ConstGeneralMatrix& m); + + virtual ~ConstVector() {} + /** Exact equality. */ + bool operator==(const ConstVector& y) const; + bool operator!=(const ConstVector& y) const + {return ! operator==(y);} + /** Lexicographic ordering. */ + bool operator<(const ConstVector& y) const; + bool operator<=(const ConstVector& y) const + {return operator<(y) || operator==(y);} + bool operator>(const ConstVector& y) const + {return ! operator<=(y);} + bool operator>=(const ConstVector& y) const + {return ! operator<(y);} + + double getNorm() const; + double getMax() const; + double getNorm1() const; + double dot(const ConstVector& y) const; + bool isFinite() const; + void print() const; +}; + +class ZeroPad { +public: + //static const int length = 16; + enum { length = 16}; +private: + double pad[16]; +public: + ZeroPad(); + const double* getBase() const {return pad;} +}; + +#endif /* VECTOR_H */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/cppblas.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/cppblas.h new file mode 100644 index 000000000..65df7aeb4 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/cppblas.h @@ -0,0 +1,68 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/cppblas.h,v 1.2 2004/11/24 20:42:52 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef CPPBLAS_H +#define CPPBLAS_H + +#if defined(MATLAB) && !defined(__linux__) +#define BLAS_dgemm dgemm +#define BLAS_dgemv dgemv +#define BLAS_dtrsv dtrsv +#define BLAS_dtrmv dtrmv +#define BLAS_daxpy daxpy +#define BLAS_dcopy dcopy +#define BLAS_zaxpy zaxpy +#define BLAS_dscal dscal +#define BLAS_dtrsm dtrsm +#define BLAS_ddot ddot +#else /* defined(MATLAB) && !defined(__linux__) */ +#define BLAS_dgemm dgemm_ +#define BLAS_dgemv dgemv_ +#define BLAS_dtrsv dtrsv_ +#define BLAS_dtrmv dtrmv_ +#define BLAS_daxpy daxpy_ +#define BLAS_dcopy dcopy_ +#define BLAS_zaxpy zaxpy_ +#define BLAS_dscal dscal_ +#define BLAS_dtrsm dtrsm_ +#define BLAS_ddot ddot_ +#endif /* defined(MATLAB) && !defined(__linux__) */ + +#define BLCHAR const char* +#define CONST_BLINT const int* +#define CONST_BLDOU const double* +#define BLDOU double* + +extern "C" { + void BLAS_dgemm(BLCHAR transa, BLCHAR transb, CONST_BLINT m, CONST_BLINT n, + CONST_BLINT k, CONST_BLDOU alpha, CONST_BLDOU a, CONST_BLINT lda, + CONST_BLDOU b, CONST_BLINT ldb, CONST_BLDOU beta, + BLDOU c, CONST_BLINT ldc); + void BLAS_dgemv(BLCHAR trans, CONST_BLINT m, CONST_BLINT n, CONST_BLDOU alpha, + CONST_BLDOU a, CONST_BLINT lda, CONST_BLDOU x, CONST_BLINT incx, + CONST_BLDOU beta, BLDOU y, CONST_BLINT incy); + void BLAS_dtrsv(BLCHAR uplo, BLCHAR trans, BLCHAR diag, CONST_BLINT n, + CONST_BLDOU a, CONST_BLINT lda, BLDOU x, CONST_BLINT incx); + void BLAS_dtrmv(BLCHAR uplo, BLCHAR trans, BLCHAR diag, CONST_BLINT n, + CONST_BLDOU a, CONST_BLINT lda, BLDOU x, CONST_BLINT incx); + void BLAS_daxpy(CONST_BLINT n, CONST_BLDOU a, CONST_BLDOU x, CONST_BLINT incx, + BLDOU y, CONST_BLINT incy); + void BLAS_dcopy(CONST_BLINT n, CONST_BLDOU x, CONST_BLINT incx, + BLDOU y, CONST_BLINT incy); + void BLAS_zaxpy(CONST_BLINT n, CONST_BLDOU a, CONST_BLDOU x, CONST_BLINT incx, + BLDOU y, CONST_BLINT incy); + void BLAS_dscal(CONST_BLINT n, CONST_BLDOU a, BLDOU x, CONST_BLINT incx); + void BLAS_dtrsm(BLCHAR side, BLCHAR uplo, BLCHAR transa, BLCHAR diag, CONST_BLINT m, + CONST_BLINT n, CONST_BLDOU alpha, CONST_BLDOU a, CONST_BLINT lda, + BLDOU b, CONST_BLINT ldb); + double BLAS_ddot(CONST_BLINT n, CONST_BLDOU x, CONST_BLINT incx, CONST_BLDOU y, + CONST_BLINT incy); +}; + + +#endif /* CPPBLAS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/cc/cpplapack.h b/mex/sources/korderpert/Dyn_pp/sylv/cc/cpplapack.h new file mode 100644 index 000000000..bee6a4394 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/cc/cpplapack.h @@ -0,0 +1,82 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/cpplapack.h,v 1.3 2004/11/24 20:43:10 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef CPPLAPACK_H +#define CPPLAPACK_H + +#if defined(MATLAB) && !defined(__linux__) +#define LAPACK_dgetrs dgetrs +#define LAPACK_dgetrf dgetrf +#define LAPACK_dgees dgees +#define LAPACK_dgecon dgecon +#define LAPACK_dtrexc dtrexc +#define LAPACK_dtrsyl dtrsyl +#define LAPACK_dpotrf dpotrf +#define LAPACK_dgges dgges +#define LAPACK_dsyev dsyev +#define LAPACK_dsyevr dsyevr +#else /* MATLAB */ +#define LAPACK_dgetrs dgetrs_ +#define LAPACK_dgetrf dgetrf_ +#define LAPACK_dgees dgees_ +#define LAPACK_dgecon dgecon_ +#define LAPACK_dtrexc dtrexc_ +#define LAPACK_dtrsyl dtrsyl_ +#define LAPACK_dpotrf dpotrf_ +#define LAPACK_dgges dgges_ +#define LAPACK_dsyev dsyev_ +#define LAPACK_dsyevr dsyevr_ +#endif /* MATLAB */ + +#define LACHAR const char* +#define CONST_LAINT const int* +#define LAINT int* +#define CONST_LADOU const double* +#define LADOU double* +typedef int (*DGGESCRIT)(const double*, const double*, const double*); + +extern "C" { + void LAPACK_dgetrs(LACHAR trans, CONST_LAINT n, CONST_LAINT nrhs, + CONST_LADOU a, CONST_LAINT lda, CONST_LAINT ipiv, + LADOU b, CONST_LAINT ldb, LAINT info); + void LAPACK_dgetrf(CONST_LAINT m, CONST_LAINT n, LADOU a, + CONST_LAINT lda, LAINT ipiv, LAINT info); + void LAPACK_dgees(LACHAR jobvs, LACHAR sort, const void* select, + CONST_LAINT n, LADOU a, CONST_LAINT lda, LAINT sdim, + LADOU wr, LADOU wi, LADOU vs, CONST_LAINT ldvs, + LADOU work, CONST_LAINT lwork, const void* bwork, LAINT info); + void LAPACK_dgecon(LACHAR norm, CONST_LAINT n, CONST_LADOU a, CONST_LAINT lda, + CONST_LADOU anorm, LADOU rnorm, LADOU work, LAINT iwork, + LAINT info); + void LAPACK_dtrexc(LACHAR compq, CONST_LAINT n, LADOU t, CONST_LAINT ldt, + LADOU q, CONST_LAINT ldq, LAINT ifst, LAINT ilst, LADOU work, + LAINT info); + void LAPACK_dtrsyl(LACHAR trana, LACHAR tranb, CONST_LAINT isgn, CONST_LAINT m, + CONST_LAINT n, CONST_LADOU a, CONST_LAINT lda, CONST_LADOU b, + CONST_LAINT ldb, LADOU c, CONST_LAINT ldc, LADOU scale, + LAINT info); + void LAPACK_dpotrf(LACHAR uplo, CONST_LAINT n, LADOU a, CONST_LAINT lda, + LAINT info); + void LAPACK_dgges(LACHAR jobvsl, LACHAR jobvsr, LACHAR sort, DGGESCRIT delztg, + CONST_LAINT n, LADOU a, CONST_LAINT lda, LADOU b, CONST_LAINT ldb, + LAINT sdim, LADOU alphar, LADOU alphai, LADOU beta, + LADOU vsl, CONST_LAINT ldvsl, LADOU vsr, CONST_LAINT ldvsr, + LADOU work, CONST_LAINT lwork, LAINT bwork, LAINT info); + void LAPACK_dsyev(LACHAR jobz, LACHAR uplo, CONST_LAINT n, LADOU a, CONST_LAINT lda, + LADOU w, LADOU work, CONST_LAINT lwork, LAINT info); + void LAPACK_dsyevr(LACHAR jobz, LACHAR range, LACHAR uplo, CONST_LAINT n, LADOU a, + CONST_LAINT lda, LADOU lv, LADOU vu, CONST_LAINT il, CONST_LAINT iu, + CONST_LADOU abstol, LAINT m, LADOU w, LADOU z, CONST_LAINT ldz, + LAINT isuppz, LADOU work, CONST_LAINT lwork, LAINT iwork, CONST_LAINT liwork, + LAINT info); +}; + + +#endif /* CPPLAPACK_H */ + + +// Local Variables: +// mode:C++ +// End: + diff --git a/mex/sources/korderpert/Dyn_pp/sylv/change_log.html b/mex/sources/korderpert/Dyn_pp/sylv/change_log.html new file mode 100644 index 000000000..8fd665f35 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/change_log.html @@ -0,0 +1,140 @@ + + + + +Sylvester Solver Change Log + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Tag Date Description/Changes
2003/09/10Initial version solving triangular system put to repository
Implemented solution of general case.
Implemented a memory pool (Paris).
Implemented MEX interface to the routine (Paris).
Implemented QuasiTriangularZero (Paris) (not fully used yet).
rel-12003/10-02Version sent to Michel.
Inheritance streamlined, QuasiTriangular inherits from GeneralMatrix.
Implemented block diagonalization algorithm.
Solution routines rewritten so that the output rewrites input, +considerable memory improvement.
MEX interface now links with LAPACK library from Matlab.
Added a hack to MEX library loading in order to avoid Matlab crash in Wins.
rel-22003/10/15Version sent to Michel.
KronUtils now rewrite input by output using less memory.
Added iterative solution algorithm (doubling).
Introduced abstraction for set of parameters (SylvParams).
Algorithm enabled to solve problems with singular C.
Implemented a class chooser chossing between QuasiTriangularZero, +and QuasiTriangular (padded with zero) depending on size of the +problem. Full use of QuasiTriangularZero.
Reimplemented QuasiTriangular::solve, offdiagonal elements are +eleiminated by gauss with partial pivoting, not by transformation of +complex eigenvalues. More stable for ill conditioned eigenvalues.
Reimplemented calculation of eliminating vectors, much more +numerically stable now.
Implemented algorithm for ordering of eigenvalues (not used now, +no numerical improvements).
rel-32003/12/4Version sent to Michel.
GeneralMatrix separated for use outside, in sylv module we use +its subclass SylvMatrix. Implemented ConstGeneralMatrix (useful outside). +
rel-42004/6/4Version, which was moved to pythie.cepremap.cnrs.fr repository.
+ + diff --git a/mex/sources/korderpert/Dyn_pp/sylv/matlab/Makefile b/mex/sources/korderpert/Dyn_pp/sylv/matlab/Makefile new file mode 100644 index 000000000..0cad09308 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/matlab/Makefile @@ -0,0 +1,35 @@ +# $Header: /var/lib/cvs/dynare_cpp/sylv/matlab/Makefile,v 1.1.1.1 2004/06/04 13:01:13 kamenik Exp $ + +# Tag $Name: $ + +# set directory to sylvester code +sylv=../cc + +LD_LIBS := -llapack -lcblas -lblas -latlas +CC_FLAGS := -Wall -I../cc +CC_DEFS := -I/usr/local/matlab73/extern/include -DMATLAB #-DUSE_MEMORY_POOL +MEX := mex.bat + +objects := $(patsubst %.cpp,%.o,$(wildcard ../cc/*.cpp)) +headers := $(wildcard ../cc/*.h) + +# set mex file suffix +mex_suffix=dll +ifeq ($(OSTYPE),linux-gnu) + mex_suffix=mexglx +endif + +aa_gensylv.$(mex_suffix): gensylv.cpp ../cc/sylvester.a + $(MEX) -I../cc -DMATLAB gensylv.cpp ../cc/sylvester.a c:/matlab6p5/extern/lib/win32/microsoft/msvc60/libmwlapack.lib + mv gensylv.$(mex_suffix) aa_gensylv.$(mex_suffix) + +../cc/sylvester.a : $(objects) + make -C ../cc sylvester.a + +../cc/%.o: ../cc/%.cpp $(headers) + make EXTERN_DEFS="$(CC_DEFS)" -C ../cc $*.o + +clear: + make -C ../cc clear + rm -f *.dll + rm -f *.mexglx diff --git a/mex/sources/korderpert/Dyn_pp/sylv/matlab/dummy.h b/mex/sources/korderpert/Dyn_pp/sylv/matlab/dummy.h new file mode 100644 index 000000000..9ce95e82b --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/matlab/dummy.h @@ -0,0 +1,3 @@ +/* this is only dummy header file to be able to loadlibrary to MATLAB */ +void mexFunction(int nhls, mxArray* plhs[], + int nhrs, const mxArray* prhs[]); diff --git a/mex/sources/korderpert/Dyn_pp/sylv/matlab/gensylv.cpp b/mex/sources/korderpert/Dyn_pp/sylv/matlab/gensylv.cpp new file mode 100644 index 000000000..9cfad4300 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/matlab/gensylv.cpp @@ -0,0 +1,100 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/matlab/gensylv.cpp,v 1.1.1.1 2004/06/04 13:01:13 kamenik Exp $ */ + +/* Tag $Name: $ */ + + +#include "mex.h" + +#include "GeneralSylvester.h" +#include "SylvException.h" + + +void gen_sylv_solve(int order, int n, int m, int zero_cols, + const double* A, const double* B, + const double* C, double* X) +{ + try { + GeneralSylvester s(order, n, m, zero_cols, A, B, C, X, false); + s.solve(); + } catch (const SylvException& e) { + char mes[1000]; + e.printMessage(mes, 999); + mexErrMsgTxt(mes); + } +} + +void gen_sylv_solve_and_check(int order, int n, int m, int zero_cols, + const double* A, const double* B, + const double* C, const double* D, + double* X, mxArray*& p) +{ + try { + GeneralSylvester s(order, n, m, zero_cols, A, B, C, X, true); + s.solve(); + s.check(D); + p = s.getParams().createStructArray(); + } catch (const SylvException& e) { + char mes[1000]; + e.printMessage(mes, 999); + mexErrMsgTxt(mes); + } +} + +void checkDimensions(const mwSize* const Adims, const mwSize* const Bdims, + const mwSize* const Cdims, const mwSize* const Ddims, + int order) +{ + if (Adims[0] != Adims[1]) + mexErrMsgTxt("Matrix A must be a square matrix."); + if (Adims[0] != Bdims[0]) + mexErrMsgTxt("Matrix A and matrix B must have the same number of rows."); + if (Adims[0] != Ddims[0]) + mexErrMsgTxt("Matrix A and matrix B must have the same number of rows."); + if (Cdims[0] != Cdims[1]) + mexErrMsgTxt("Matrix C must be square."); + if (Bdims[0] < Bdims[1]) + mexErrMsgTxt("Matrix B must not have more columns than rows."); + if (Ddims[1] != power(Cdims[0], order)) + mexErrMsgTxt("Matrix D has wrong number of columns."); +} + +extern "C" { + void mexFunction(int nhls, mxArray* plhs[], + int nhrs, const mxArray* prhs[]) + { + if (nhrs != 5) + mexErrMsgTxt("Must have exactly 5 input args."); + if (nhls !=1 && nhls != 2) + mexErrMsgTxt("Must have 1 or 2 output args."); + + int order = (int)mxGetScalar(prhs[0]); + const mxArray* const A = prhs[1]; + const mxArray* const B = prhs[2]; + const mxArray* const C = prhs[3]; + const mxArray* const D = prhs[4]; + const mwSize* const Adims = mxGetDimensions(A); + const mwSize* const Bdims = mxGetDimensions(B); + const mwSize* const Cdims = mxGetDimensions(C); + const mwSize* const Ddims = mxGetDimensions(D); + checkDimensions(Adims, Bdims, Cdims, Ddims, order); + int n = Adims[0]; + int m = Cdims[0]; + int zero_cols = Bdims[0] - Bdims[1]; + mxArray* X = mxCreateDoubleMatrix(Ddims[0], Ddims[1], mxREAL); + // copy D to X + Vector Xvec((double*)mxGetPr(X), power(m, order)*n); + ConstVector Dvec((double*)mxGetPr(D), power(m, order)*n); + Xvec = Dvec; + // solve (or solve and check) + if (nhls == 1) { + gen_sylv_solve(order, n, m, zero_cols, + mxGetPr(A), mxGetPr(B), mxGetPr(C), + mxGetPr(X)); + } else if (nhls == 2) { + gen_sylv_solve_and_check(order, n, m, zero_cols, + mxGetPr(A), mxGetPr(B), mxGetPr(C), + mxGetPr(D), mxGetPr(X), plhs[1]); + } + plhs[0] = X; + } +}; diff --git a/mex/sources/korderpert/Dyn_pp/sylv/matlab/gensylv.m b/mex/sources/korderpert/Dyn_pp/sylv/matlab/gensylv.m new file mode 100644 index 000000000..b6cb0dccb --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/matlab/gensylv.m @@ -0,0 +1,74 @@ +% +% GENSYLV solves the following matrix equation: +% A*X + [0 B]*X*kron(C,..,C) = D, +% where +% A ...... regular (n,n) matrix, +% [0 B] .. (n,n) matrix with a few first +% columns equal to zeros +% B ...... rectangular (n, nz) matrix with nz<=n +% C ...... regular (m,m) matrix, whose spectrum is +% within (-1, 1) +% kron(C,..,C) +% ...... Kronecker power of C of order 'order' +% D ..... rectangular (n, m^order) matrix. +% +% X = gensylv(order, A, B, C, D) +% returns X as the solution, doesn't perform any checks +% +% [X, par] = gensylv(order, A, B, C, D) +% solves the system, and performs checks. 'par' is struct +% containing information about solution and error norms +% returned by the check. This is a list of the struct +% members, some of them may be missing in actual returned +% value: +% method = method used for solution recursive/iterative +% convergence_tol = convergence tolerance for iter. method +% max_num_iter = max number of steps for iter. method +% bs_norm = Bavely Stewart log10 norm for diagonalization +% converged = convergence status for iterative method +% iter_last_norm = residual norm of the last step of iterations +% num_iter = number of iterations performed +% f_err1 = norm 1 of abs. error C-V*F*inv(V) +% f_errI = norm Inf of abs. error C-V*F*inv(V) +% viv_err1 = norm 1 of abs. error I-V*inv(V) +% viv_errI = norm Inf of abs. error I-V*inv(V) +% ivv_err1 = norm 1 of abs. error I-inv(V)*V +% ivv_errI = norm Inf of abs. error I-inv(V)*V +% f_blocks = number of diagonal blocks of F +% f_largest = size of largest diagonal block in F +% f_zeros = number of off diagonal zeros in F +% f_offdiag = number of all offdiagonal elements in F +% rcondA1 = reciprocal cond 1 number of A +% rcondAI = reciprocal cond Inf number of A +% eig_min = minimum eigenvalue of vectorized system +% mat_err1 = rel. matrix 1 norm of A*X-[0 B]*X*kron(C,..,C)-D +% mat_errI = rel. matrix Inf norm of --"-- +% mat_errF = rel. matrix Frobenius norm of --"-- +% vec_err1 = rel. vector 1 norm of --"-- +% vec_errI = rel. vector Inf norm of --"-- +% cpu_time = CPU time needed for solution in CPU seconds +% + +% $Header: /var/lib/cvs/dynare_cpp/sylv/matlab/gensylv.m,v 1.1.1.1 2004/06/04 13:01:13 kamenik Exp $ +% Tag $Name: $ + +function [X, varargout] = gensylv(order, A, B, C, D) + +% in Windows, ensure that aa_gensylv.dll is loaded, this prevents +% clearing the function and a successive Matlab crash +if strcmp('PCWIN', computer) + if ~ libisloaded('aa_gensylv') + loadlibrary('aa_gensylv', 'dummy'); + end +end + +% launch aa_gensylv +if nargout == 1 + X = aa_gensylv(order, A, B, C, D); +elseif nargout == 2 + [X, par] = aa_gensylv(order, A, B, C, D); + varargout(1) = {par}; +else + error('Must have 1 or 2 output arguments.'); +end + \ No newline at end of file diff --git a/mex/sources/korderpert/Dyn_pp/sylv/matlab/mexopts.bat b/mex/sources/korderpert/Dyn_pp/sylv/matlab/mexopts.bat new file mode 100644 index 000000000..fe71cb2a0 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/matlab/mexopts.bat @@ -0,0 +1,59 @@ +@echo off +rem $Header: /var/lib/cvs/dynare_cpp/sylv/matlab/mexopts.bat,v 1.1.1.1 2004/06/04 13:01:13 kamenik Exp $ +rem Tag $Name: $ +rem c:\ondra\wk\sylv\matlab\mexopts.bat +rem Generated by gnumex.m script in c:\fs\gnumex +rem gnumex version: 1.08 +rem Compile and link options used for building MEX etc files with +rem the Mingw/Cygwin tools. Options here are: +rem Cygwin (cygwin*.dll) linking +rem Mex file creation +rem Standard (safe) linking to temporary libraries +rem Language C / C++ +rem Matlab version 6.5 +rem +set MATLAB=C:\MATLAB~2 +set GM_PERLPATH=C:\MATLAB~2\sys\perl\win32\bin\perl.exe +set GM_UTIL_PATH=c:\fs\gnumex +set PATH=C:\fs\cygwin\bin;%PATH% +rem +rem Added libraries for linking +set GM_ADD_LIBS= +rem +rem Type of file to compile (mex or engine) +set GM_MEXTYPE=mex +rem +rem Language for compilation +set GM_MEXLANG=c +rem +rem def files to be converted to libs +set GM_DEFS2LINK=libmx.def;libmex.def;libmat.def;_libmatlbmx.def; +rem +rem dlltool command line +set GM_DLLTOOL=c:\fs\gnumex\mexdlltool -E --as C:\fs\cygwin\bin\as.exe +rem +rem compiler options; add compiler flags to compflags as desired +set NAME_OBJECT=-o +set COMPILER=gcc +set COMPFLAGS=-c -DMATLAB_MEX_FILE +set OPTIMFLAGS=-O3 -mcpu=pentium -malign-double +set DEBUGFLAGS=-g +set CPPCOMPFLAGS=%COMPFLAGS% -x c++ +set CPPOPTIMFLAGS=%OPTIMFLAGS% +set CPPDEBUGFLAGS=%DEBUGFLAGS% +rem +rem NB Library creation commands occur in linker scripts +rem +rem Linker parameters +set LINKER=%GM_PERLPATH% %GM_UTIL_PATH%\linkmex.pl +set LINKFLAGS= +set CPPLINKFLAGS= --driver-name c++ +set LINKOPTIMFLAGS=-s +set LINKDEBUGFLAGS=-g +set LINK_FILE= +set LINK_LIB= +set NAME_OUTPUT=-o %OUTDIR%%MEX_NAME%.dll +rem +rem Resource compiler parameters +set RC_COMPILER=%GM_PERLPATH% %GM_UTIL_PATH%\rccompile.pl --unix -o %OUTDIR%mexversion.res +set RC_LINKER= diff --git a/mex/sources/korderpert/Dyn_pp/sylv/sylvester.tex b/mex/sources/korderpert/Dyn_pp/sylv/sylvester.tex new file mode 100644 index 000000000..a5476183a --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/sylvester.tex @@ -0,0 +1,541 @@ +\input amstex +\documentstyle{amsppt} +\def\vec{\mathop{\hbox{vec}}} +\def\otimesi{\mathop{\overset{\ssize i}\to{\otimes}}} +\def\iF{\,^i\!F} +\def\imF{\,^{i-1}\!F} +\def\solvi{\bold{solv1}} +\def\solvii{\bold{solv2}} +\def\solviip{\bold{solv2p}} + +\topmatter +\title Solution of Specialized Sylvester Equation\endtitle +\author Ondra Kamenik\endauthor +\email ondrej.kamenik@cnb.cz\endemail +\endtopmatter + +\document +Given the following matrix equation +$$AX+BX\left(\otimesi C\right)=D,$$ where $A$ is regular $n\times n$ +matrix, $X$ is $n\times m^i$ matrix of unknowns, $B$ is singular +$n\times n$ matrix, $C$ is $m\times m$ regular matrix with +$|\beta(C)|<1$ (i.e. modulus of largest eigenvalue is less than one), +$i$ is an order of Kronecker product, and finally $D$ is $n\times m^i$ +matrix. + +First we multiply the equation from the left by $A^{-1}$ to obtain: +$$X+A^{-1}BX\left(\otimesi C\right)=A^{-1}D$$ +Then we find real Schur decomposition $K=UA^{-1}BU^T$, and +$F=VCV^T$. The equation can be written as +$$UX\left(\otimesi V^T\right) + +KUX\left(\otimesi V^T\right)\left(\otimesi F\right) = +UA^{-1}D\left(\otimesi V^T\right)$$ +This can be rewritten as +$$Y + KY\left(\otimesi F\right)=\widehat{D},$$ +and vectorized +$$\left(I+\otimesi F^T\otimes K\right)\vec(Y)=\vec(\widehat{D})$$ +Let $\iF$ denote $\otimesi F^T$ for the rest of the text. + +\proclaim{Lemma 1} +For any $n\times n$ matrix $A$ and $\beta_1\beta_2>0$, if there is +exactly one solution of +$$\left(I_2\otimes I_n + +\pmatrix\alpha&\beta_1\cr-\beta_2&\alpha\endpmatrix +\otimes A\right)\pmatrix x_1\cr x_2\endpmatrix = +\pmatrix d_1\cr d_2\endpmatrix,$$ +then it can be obtained as solution of +$$\align +\left(I_n + 2\alpha A+(\alpha^2+\beta^2)A^2\right)x_1 & = +\widehat{d_1}\\ +\left(I_n + 2\alpha A+(\alpha^2+\beta^2)A^2\right)x_2 & = +\widehat{d_2} + \endalign$$ +where $\beta=\sqrt{\beta1\beta2}$, and +$$ +\pmatrix \widehat{d_1}\cr\widehat{d_2}\endpmatrix = +\left(I_2\otimes I_n + +\pmatrix\alpha&-\beta_1\cr\beta_2&\alpha\endpmatrix +\otimes A\right)\pmatrix d_1\cr d_2\endpmatrix$$ +\endproclaim + +\demo{Proof} Since +$$ +\pmatrix \alpha&\beta_1\cr-\beta_2&\alpha\endpmatrix +\pmatrix \alpha&-\beta_1\cr\beta_2&\alpha\endpmatrix += +\pmatrix \alpha&-\beta_1\cr\beta_2&\alpha\endpmatrix +\pmatrix \alpha&\beta_1\cr-\beta_2&\alpha\endpmatrix += +\pmatrix \alpha^2+\beta^2&0\cr 0&\alpha^2+\beta^2\endpmatrix, +$$ +it is easy to see that if the equation is multiplied by +$$I_2\otimes I_n + +\pmatrix\alpha&-\beta_1\cr\beta_2&\alpha\endpmatrix +\otimes A$$ +we obtain the result. We only need to prove that the matrix is +regular. But this is clear because matrix +$$\pmatrix \alpha&-\beta_1\cr\beta_2&\alpha\endpmatrix$$ +collapses an eigenvalue of $A$ to $-1$ iff the matrix +$$\pmatrix \alpha&\beta_1\cr-\beta_2&\alpha\endpmatrix$$ +does.\qed +\enddemo + +\proclaim{Lemma 2} +For any $n\times n$ matrix $A$ and $\delta_1\delta_2>0$, if there is +exactly one solution of +$$\left(I_2\otimes I_n + +2\alpha\pmatrix\gamma&\delta_1\cr-\delta_2&\gamma\endpmatrix\otimes A ++(\alpha^2+\beta^2) +\pmatrix\gamma&\delta_1\cr-\delta_2&\gamma\endpmatrix^2\otimes A^2\right) +\pmatrix x_1\cr x_2\endpmatrix= +\pmatrix d_1\cr d_2\endpmatrix +$$ +it can be obtained as +$$ +\align +\left(I_n+2a_1A+(a_1^2+b_1^2)A^2\right)\left(I_n+2a_2A+(a_2^2+b_2^2)A^2\right) +x_1 & =\widehat{d_1}\\ +\left(I_n+2a_1A+(a_1^2+b_1^2)A^2\right)\left(I_n+2a_2A+(a_2^2+b_2^2)A^2\right) +x_2 & =\widehat{d_2} +\endalign$$ +where +$$ +\pmatrix \widehat{d_1}\cr\widehat{d_2}\endpmatrix = +\left(I_2\otimes I_n + +2\alpha\pmatrix\gamma&-\delta_1\cr\delta_2&\gamma\endpmatrix\otimes A ++(\alpha^2+\beta^2) +\pmatrix\gamma&-\delta_1\cr\delta_2&\gamma\endpmatrix^2\otimes A^2\right) +\pmatrix d_1\cr d_2\endpmatrix +$$ +and +$$ +\align +a_1 & = \alpha\gamma - \beta\delta\\ +b_1 & = \alpha\delta + \gamma\beta\\ +a_2 & = \alpha\gamma + \beta\delta\\ +b_2 & = \alpha\delta - \gamma\beta\\ +\delta & = \sqrt{\delta_1\delta_2} +\endalign$$ +\endproclaim + +\demo{Proof} +The matrix can be written as +$$\left(I_2\otimes I_n+(\alpha+\roman i\beta) +\pmatrix\gamma&\delta_1\cr-\delta_2&\gamma\endpmatrix\otimes A\right) +\left(I_2\otimes I_n +(\alpha-\roman i\beta) +\pmatrix\gamma&\delta_1\cr-\delta_2&\gamma\endpmatrix\otimes A\right). +$$ +Note that the both matrices are regular since their product is +regular. For the same reason as in the previous proof, the following +matrix is also regular +$$\left(I_2\otimes I_n+(\alpha+\roman i\beta) +\pmatrix\gamma&-\delta_1\cr\delta_2&\gamma\endpmatrix\otimes A\right) +\left(I_2\otimes I_n +(\alpha-\roman i\beta) +\pmatrix\gamma&-\delta_1\cr\delta_2&\gamma\endpmatrix\otimes A\right), +$$ +and we may multiply the equation by this matrix obtaining +$\widehat{d_1}$ and $\widehat{d_2}$. Note that the four matrices +commute, that is why we can write the whole product as +$$ +\align +\left(I_2\otimes I_n + (\alpha+\roman i\beta) +\pmatrix\gamma&\delta_1\cr-\delta_2&\gamma\endpmatrix\otimes A\right)\cdot +\left(I_2\otimes I_n + (\alpha+\roman i\beta) +\pmatrix\gamma&-\delta_1\cr\delta_2&\gamma\endpmatrix\otimes A\right)&\cdot\\ +\left(I_2\otimes I_n + (\alpha-\roman i\beta) +\pmatrix\gamma&\delta_1\cr-\delta_2&\gamma\endpmatrix\otimes A\right)\cdot +\left(I_2\otimes I_n + (\alpha-\roman i\beta) +\pmatrix\gamma&-\delta_1\cr\delta_2&\gamma\endpmatrix\otimes A\right)&=\\ +\left(I_2\otimes I_n + 2(\alpha + \roman i\beta) +\pmatrix\gamma&0\cr 0&\gamma\endpmatrix\otimes A + +(\alpha + \roman i\beta)^2 +\pmatrix\gamma^2+\delta^2&0\cr 0&\gamma^2+\delta^2\endpmatrix\otimes A^2 +\right)&\cdot\\ +\left(I_2\otimes I_n + 2(\alpha - \roman i\beta) +\pmatrix\gamma&0\cr 0&\gamma\endpmatrix\otimes A + +(\alpha - \roman i\beta)^2 +\pmatrix\gamma^2+\delta^2&0\cr 0&\gamma^2+\delta^2\endpmatrix\otimes A^2 +\right)& +\endalign +$$ +The product is a diagonal consiting of two $n\times n$ blocks, which are the +same. The block can be rewritten as product: +$$ +\align +(I_n+(\alpha+\roman i\beta)(\gamma+\roman i\delta)A)\cdot +(I_n+(\alpha+\roman i\beta)(\gamma-\roman i\delta)A)&\cdot\\ +(I_n+(\alpha-\roman i\beta)(\gamma+\roman i\delta)A)\cdot +(I_n+(\alpha-\roman i\beta)(\gamma-\roman i\delta)A)& +\endalign +$$ +and after reordering +$$ +\align +(I_n+(\alpha+\roman i\beta)(\gamma+\roman i\delta)A)\cdot +(I_n+(\alpha-\roman i\beta)(\gamma-\roman i\delta)A)&\cdot\\ +(I_n+(\alpha+\roman i\beta)(\gamma-\roman i\delta)A)\cdot +(I_n+(\alpha-\roman i\beta)(\gamma+\roman i\delta)A)&=\\ +(I_n+2(\alpha\gamma-\beta\delta)A+ +(\alpha^2+\beta^2)(\gamma^2+\delta^2)A^2)&\cdot\\ +(I_n+2(\alpha\gamma+\beta\delta)A+ +(\alpha^2+\beta^2)(\gamma^2+\delta^2)A^2)& +\endalign +$$ +Now it suffices to compare $a_1=\alpha\gamma-\beta\delta$ and verify +that +$$ +\align +b_1^2 & = (\alpha^2+\beta^2)(\gamma^2+\delta^2)-a_1^2 =\cr + & = \alpha^2\gamma^2+\beta^2\gamma^2+\alpha^2\beta^2+\beta^2\delta^2- + (\alpha\gamma)^2+2\alpha\beta\gamma\delta-(\beta\delta)^2=\cr + & = (\beta\gamma)^2 + (\alpha\beta)^2 + 2\alpha\beta\gamma\delta=\cr + & = (\beta\gamma +\alpha\beta)^2 +\endalign +$$ +For $b_2$ it is done in the same way. +\qed +\enddemo + +\head The Algorithm\endhead + +Below we define three functions of which +$\vec(Y)=\solvi(1,\vec(\widehat{D}),i)$ provides the solution $Y$. $X$ +is then obtained as $X=U^TY\left(\otimesi V\right)$. + +\subhead Synopsis\endsubhead + +$F^T$ is $m\times m$ lower quasi-triangular matrix. Let $m_r$ be a +number of real eigenvalues, $m_c$ number of complex pairs. Thus +$m=m_r+2m_c$. Let $F_j$ denote +$j$-th diagonal block of $F^T$ ($1\times 1$ or $2\times 2$ matrix) for +$j=1,\ldots, m_r+m_c$. For a fixed $j$, let $\bar j$ denote index of the +first column of $F_j$ in $F^T$. Whenever we write something like +$(I_{m^i}\otimes I_n+r\iF\otimes K)x = d$, $x$ and $d$ denote column +vectors of appropriate dimensions, and $x_{\bar j}$ is $\bar j$-th +partition of $x$, and $x_j=(x_{\bar j}\quad x_{\bar j+1})^T$ if $j$-th +eigenvalue is complex, and $x_j=x_{\bar j}$ if $j$-th eigenvalue is real. + +\subhead Function $\solvi$\endsubhead + +The function $x=\solvi(r,d,i)$ solves equation +$$\left(I_{m^i}\otimes I_n+r\iF\otimes K\right)x = d.$$ +The function proceedes as follows: + +If $i=0$, the equation is solved directly, $K$ is upper +quasi-triangular matrix, so this is easy. + +If $i>0$, then we go through diagonal blocks $F_j$ for +$j=1,\ldots, m_r+m_c$ and perform: +\roster +\item if $F_j=(f_{\bar j\bar j}) = (f)$, then we return +$x_j=\solvi(rf,d_{\bar j}, i-1)$. Then precalculate $y=d_j-x_j$, and +eliminate guys below $F_j$. This is, for each $k=\bar j+1,\ldots, m$, we +put +$$d_k = d_k-rf_{\bar jk}\left(\imF\otimes K\right)x_{\bar j}= +d_k - \frac{f_{\bar jk}}{f}y$$ + +\item if $F_j=\pmatrix\alpha&\beta_1\cr -\beta_2&\alpha\endpmatrix$, +we return $x_j=\solvii(r\alpha, r\beta_1, r\beta_2, d_j, i-1)$. Then +we precalculate +$$y=\left(\pmatrix\alpha&-\beta_1\cr \beta_2&\alpha\endpmatrix +\otimes I_{m^{i-1}}\otimes I_n\right) +\pmatrix d_{\bar j} - x_{\bar j}\cr + d_{\bar j+1} - x_{\bar j+1} +\endpmatrix$$ +and eliminate guys below $F_j$. This is, for each $k=\bar j+2,\ldots, n$ +we put +$$ +\align +d_k &= d_k - r(f_{{\bar j}k}\quad f_{{\bar j}+1 k}) + \otimes\left(\imF\otimes K\right)x_j\\ + &= d_k - \frac{1}{\alpha^2+\beta_1\beta_2} + \left((f_{{\bar j}k}\quad f_{{\bar j}+1 k}) + \otimes I_{m^{i-1}}\otimes I_n\right)y +\endalign +$$ +\endroster + +\subhead Function $\solvii$\endsubhead + +The function $x=\solvii(\alpha, \beta_1, \beta_2, d, i)$ solves +equation +$$ +\left(I_2\otimes I_{m^i}\otimes I_n + +\pmatrix\alpha&\beta_1\cr-\beta_2&\alpha\endpmatrix +\otimes\iF\otimes K\right)x=d +$$ + +According to {\bf Lemma 1} the function returns +$$ +x=\pmatrix\solviip(\alpha,\beta_1\beta_2,\widehat{d_1},i)\cr + \solviip(\alpha,\beta_1\beta_2,\widehat{d_2},i)\endpmatrix, +$$ +where $\widehat{d_1}$, and $\widehat{d_2}$ are partitions of +$\widehat{d}$ from the lemma. + +\subhead Function $\solviip$\endsubhead + +The function $x=\solviip(\alpha,\beta^2,d,i)$ solves equation +$$ +\left(I_{m^i}\otimes I_n + 2\alpha\iF\otimes K + +(\alpha^2+\beta^2)\iF^2\otimes K^2\right)x = d +$$ +The function proceedes as follows: + +If $i=0$, the matrix $I_n+2\alpha K+(\alpha^2+\beta^2)K^2$ is +calculated and the solution is obtained directly. + +Now note that diagonal blocks of $F^{2T}$ are of the form $F_j^2$, +since if the $F^T$ is block partitioned according to diagonal blocks, +then it is lower triangular. + +If $i>0$, then we go through diagonal blocks $F_j$ for $j=1,\ldots, m_r+m_c$ +and perform: +\roster +\item if $F_j=(f_{\bar j\bar j})=(f)$ then $j$-th diagonal block of +$$ +I_{m^i}\otimes I_n + 2\alpha\iF\otimes K + +(\alpha^2+\beta^2)\iF^2\otimes K^2 +$$ +takes the form +$$ +I_{m^{i-1}}\otimes I_n +2\alpha f\imF\otimes K + +(\alpha^2+\beta^2)f^2\imF^2\otimes K^2 +$$ +and we can put $x_j = \solviip(f\alpha,f^2\beta^2,d_j,i-1)$. + +Then we need to eliminate guys below $F_j$. Note that $|f^2|<|f|$, +therefore we precalculate $y_2=(\alpha^2+\beta^2)f^2(\imF^2\otimes K^2)x_j$, +and then precalculate +$$y_1 = 2\alpha f(\imF\otimes K)x_j = d_j-x_j-y_2.$$ +Let $g_{pq}$ denote element of $F^{2T}$ at position $(q,p)$. +The elimination is done by going through $k=\bar j+1,\ldots, m$ and +putting +$$ +\align +d_k &= d_k - \left(2\alpha f_{\bar j k}\imF\otimes K + +(\alpha^2+\beta^2)g_{\bar j k}\imF^2\otimes K^2\right)x_j\\ + &= d_k - \frac{f_{\bar j k}}{f}y_1 - + \frac{g_{\bar j k}}{f^2}y_2 +\endalign +$$ + +\item if $F_j=\pmatrix\gamma&\delta_1\cr -\delta_2&\gamma\endpmatrix$, +then $j$-th diagonal block of +$$ +I_{m^i}\otimes I_n + 2\alpha\iF\otimes K + +(\alpha^2+\beta^2)\iF^2\otimes K^2 +$$ +takes the form +$$ +I_{m^{i-1}}\otimes I_n +2\alpha +\pmatrix\gamma&\delta_1\cr -\delta_2&\gamma\endpmatrix\imF\otimes K ++(\alpha^2+\beta^2) +\pmatrix\gamma&\delta_1\cr -\delta_2&\gamma\endpmatrix^2\imF^2\otimes K^2 +$$ +According to {\bf Lemma 2}, we need to calculate +$\widehat{d}_{\bar j}$, and $\widehat{d}_{\bar j+1}$, and $a_1$, +$b_1$, $a_2$, $b_2$. Then we obtain +$$ +\align +x_{\bar j}&= + \solviip(a_1,b_1^2,\solviip(a_2,b_2^2,\widehat{d}_{\bar j},i-1),i-1)\\ +x_{\bar j+1}&= + \solviip(a_1,b_1^2,\solviip(a_2,b_2^2,\widehat{d}_{\bar j+1},i-1),i-1) +\endalign +$$ + +Now we need to eliminate guys below $F_j$. Since $\Vert F^2_j\Vert < +\Vert F_j\Vert$, we precalculate +$$ +\align +y_2&=(\alpha^2+\beta^2)(\gamma^2+\delta^2) +\left(I_2\otimes\imF^2\otimes K^2\right)x_j\\ +y_1&=2\alpha(\gamma^2+\delta^2)\left(I_2\otimes\imF\otimes +K\right)x_j\\ + &=(\gamma^2+\delta^2) + \left(F_j^{-1} + \otimes I_{m^{i-1}n}\right) + \left(d_j-x_j-\frac{1}{(\gamma^2+\delta^2)} + \left( + F_j^2 + \otimes I_{m^{i-1}n}\right)y_2\right)\\ + &=\left(\pmatrix\gamma&-\delta_1\cr\delta_2&\gamma\endpmatrix + \otimes I_{m^{i-1}n}\right)(d_j-x_j) + -\left(\pmatrix\gamma&\delta_1\cr-\delta_2&\gamma\endpmatrix + \otimes I_{m^{i-1}n}\right)y_2 +\endalign +$$ +Then we go through all $k=\bar j+2,\ldots, m$. For clearer formulas, let +$\bold f_k$ denote pair of $F^T$ elements in $k$-th line below $F_j$, +this is $\bold f_k=(f_{\bar jk}\quad f_{\bar j+1k})$. And let $\bold g_k$ +denote the same for $F^{2T}$, this is $\bold g_k=(g_{\bar jk}\quad +g_{\bar j+1k})$. For each $k$ we put +$$ +\align +d_k &= d_k - \left(2\alpha\bold f_k\otimes + \imF\otimes K + + (\alpha^2+\beta^2)\bold g_k\otimes + \imF^2\otimes K^2\right)x_j\\ + &= d_k - \frac{1}{\gamma^2+\delta^2} + \left(\bold f_k\otimes + I_{m^{i-1}n}\right)y_1 + - \frac{1}{\gamma^2+\delta^2} + \left(\bold g_k\otimes + I_{m^{i-1}n}\right)y_2 +\endalign +$$ + +\endroster + +\head Final Notes\endhead + +\subhead Numerical Issues of $A^{-1}B$\endsubhead + +We began the solution of the Sylvester equation with multiplication by +$A^{-1}$. This can introduce numerical errors, and we need more +numerically stable supplement. Its aim is to make $A$ and $B$ +commutative, this is we need to find a regular matrix $P$, such that +$(PA)(PB)=(PB)(PA)$. Recall that this is neccessary in solution of +$$ +(I_2\otimes I_{m^i}\otimes (PA)+(D+C)\otimes\,\iF\otimes (PB))x=d, +$$ +since this equation is +multiplied by $I_2\otimes I_{m^i}\otimes (PA)+(D-C)\otimes\,\iF\otimes PB$, +and the diagonal +result +$$ +I_2\otimes I_{m^i}\otimes (PAPA) + 2D\otimes\,\iF\otimes (PAPB) + +(D^2-C^2)\otimes\,\iF^2\otimes (PBPB) +$$ +is obtained only if +$(PA)(PB)=(PB)(PA)$. + +Finding regular solution of $(PA)(PB)=(PB)(PA)$ is equivalent to +finding regular solution of $APB-BPA=0$. Numerical error of the former +equation is $P$-times greater than the numerical error of the latter +equation. And the numerical error of the latter equation also grows +with the size of $P$. On the other hand, truncation error in $P$ +multiplication decreases with growing the size of $P$. By intuition, +stability analysis will show that the best choice is some orthonormal +$P$. + +Obviously, since $A$ is regular, the equation $APB-BPA=0$ has solution +of the form $P=\alpha A^{-1}$, where $\alpha\neq 0$. There is a vector +space of all solutions $P$ (including singular ones). In precise +arithmetics, its dimension is $\sum n^2_i$, where $n_i$ is number of +repetitions of $i$-th eigenvalue of $A^{-1}B$ which is similar to +$BA^{-1}$. In floating point arithmetics, without any further +knowledge about $A$, and $B$, we are only sure about dimension $n$ +which is implied by similarity of $A^{-1}B$ and $BA^{-1}$. Now we try +to find the base of the vector space of solutions. + +Let $L$ denote the following linear operator: +$$L(X)=(AXB-BXA)^T.$$ + +Let $\vec(X)$ denote a vector made by stacking all the +columns of $X$. Let $T_n$ denote $n^2\times n^2$ matrix representing +operator $\vec(X)\mapsto \vec(X^T)$. And +finally let $M$ denote $n^2\times n^2$ matrix represening the operator +$L$. It is not difficult to verify that: +$$M=T_n(B^T\otimes A - A^T\otimes B)$$ +Now we show that $M$ is skew symmetric. Recall that $T_n(X\otimes +Y)=(Y\otimes X)T_n$, we have: +$$M^T=(B^T\otimes A - A^T\otimes B)^TT_n=(B\otimes A^T - A\otimes B^T)T_n= +T_n(A^T\otimes B - B^T\otimes A) = -M$$ + +We try to solve $M\vec(X) = T_n(0) = 0$. Since $M$ is +skew symmetric, there is real orthonormal matrix $Q$, such that +$M=Q\widehat{M}Q^T$, and $\widehat{M}$ is block diagonal matrix +consisting of $2\times 2$ blocks of the form +$$\left(\matrix 0&\alpha_i\cr-\alpha_i&0\endmatrix\right),$$ +and of additional zero, if $n^2$ is odd. + +Now we solve equation $\widehat{M}y=0$, where $y=Q^T\vec(X)$. Now +there are $n$ zero rows in $\widehat{M}$ coming from similarity of +$A^{-1}B$ and $BA^{-1}$ (structural zeros). Note that the additional +zero for odd $n^2$ is already included in that number, since for odd +$n^2$ is $n^2-n$ even. Besides those, there are also zeros (esp. in +floating point arithmetics), coming from repetitive (or close) +eigenvalues of $A^{-1}B$. If we are able to select the rows with the +structural zeros, a solution is obtained by picking arbitrary numbers +for the same positions in $y$, and put $\vec(X)=Qy$. + +The following questions need to be answered: +\roster +\item How to recognize the structural rows? +\item Is $A^{-1}$ generated by a $y$, which has non-zero elements only +on structural rows? Note that $A$ can have repetitive eigenvalues. The +positive answer to the question implies that in each $n$-partition of +$y$ there is exactly one structural row. +\item And very difficult one: How to pick $y$ so that $X$ would be +regular, or even close to orthonormal (pure orthonormality +overdeterminates $y$)? +\endroster + +\subhead Making Zeros in $F$\endsubhead + +It is clear that the numerical complexity of the proposed algorithm +strongly depends on a number of non-zero elements in the Schur factor +$F$. If we were able to find $P$, such that $PFP^{-1}$ has +substantially less zeros than $F$, then the computation would be +substantially faster. However, it seems that we have to pay price for +any additional zero in terms of less numerical stability of $PFP^{-1}$ +multiplication. Consider $P$, and $F$ in form +$$P=\pmatrix I &X\cr 0&I\endpmatrix, +\qquad F=\pmatrix A&C\cr 0&B\endpmatrix$$ +we obtain +$$PFP^{-1}=\pmatrix A& C + XB - AX\cr 0&B \endpmatrix$$ + +Thus, we need to solve $C = AX - XB$. Its clear that numerical +stability of operator $Y\mapsto PYP^{-1}$ and its inverse $Y\mapsto +P^{-1}YP$ is worse with growing norm $\Vert X\Vert$. The norm can be +as large as $\Vert F\Vert/\delta$, where $\delta$ is a distance of +eigenspectra of $A$ and $B$. Also, a numerical error of the solution is +proportional to $\Vert C\Vert/\delta$. + +Although, these difficulties cannot be overcome completely, we may +introduce an algorithm, which works on $F$ with ordered eigenvalues on +diagonal, and seeks such partitioning to maximize $\delta$ and +minimize $C$. If the partitioning is found, the algorithm finds $P$ +and then is run for $A$ and $B$ blocks. It stops when further +partitioning is not possible without breaking some user given limit +for numerical errors. We have to keep in mind that the numerical +errors are accumulated in product of all $P$'s of every step. + +\subhead Exploiting constant rows in $F$\endsubhead + +If some of $F$'s rows consists of the same numbers, or a number of +distict values within a row is small, then this structure can be +easily exploited in the algorithm. Recall, that in both functions +$\solvi$, and $\solviip$, we eliminate guys below diagonal element (or +block) (of $F^T$), by multiplying solution of the diagonal and +cancelling it from right side. If the elements below the diagonal +block are the same, we save one vector multiplication. Note that in +$\solviip$ we still need to multiply by elements below diagonal of the +matrix $F^{T2}$, which obviously has not the property. However, the +heaviest elimination is done at the very top level, in the first call +to $\solvi$. + +Another way of exploitation the property is to proceed all +calculations in complex numbers. In that case, only $\solvi$ is run. + +How the structure can be introduced into the matrix? Following the +same notation as in previous section, we solve $C = AX - XB$ in order +to obtain zeros at place of $C$. If it is not possible, we may relax +the equation by solving $C - R = AX - XB$, where $R$ is suitable +matrix with constant rows. The matrix $R$ minimizes $\Vert C-R\Vert$ +in order to minimize $\Vert X\Vert$ if $A$, and $B$ are given. Now, in +the next step we need to introduce zeros (or constant rows) to matrix +$A$, so we seek for regular matrix $P$, doing the +job. If found, the product looks like: +$$\pmatrix P&0\cr 0&I\endpmatrix\pmatrix A&R\cr 0&B\endpmatrix +\pmatrix P^{-1}&0\cr 0&I\endpmatrix= +\pmatrix PAP^{-1}&PR\cr 0&B\endpmatrix$$ +Now note, that matrix $PR$ has also constant rows. Thus, +preconditioning of the matrix in upper left corner doesn't affect the +property. However, a preconditioning of the matrix in lower right +corner breaks the property, since we would obtain $RP^{-1}$. + + +\enddocument diff --git a/mex/sources/korderpert/Dyn_pp/sylv/testing/MMMatrix.cpp b/mex/sources/korderpert/Dyn_pp/sylv/testing/MMMatrix.cpp new file mode 100644 index 000000000..b3c699da9 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/testing/MMMatrix.cpp @@ -0,0 +1,71 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/testing/MMMatrix.cpp,v 1.1.1.1 2004/06/04 13:01:13 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "MMMatrix.h" + +#include +#include + +MMMatrixIn::MMMatrixIn(const char* fname) +{ + FILE* fd; + if (NULL==(fd = fopen(fname,"r"))) + throw MMException(string("Cannot open file ")+fname+" for reading\n"); + + char buffer[1000]; + // jump over initial comments + while (fgets(buffer, 1000, fd) && strncmp(buffer, "%%", 2)) {} + // read in number of rows and cols + if (!fgets(buffer, 1000, fd)) + throw MMException(string("Cannot read rows and cols while reading ")+fname+"\n"); + if (2 != sscanf(buffer, "%d %d", &rows, &cols)) + throw MMException("Couldn't parse rows and cols\n"); + // read in data + data = (double*) operator new[](rows*cols*sizeof(double)); + int len = rows*cols; + int i = 0; + while (fgets(buffer, 1000, fd) && i < len) { + if (1 != sscanf(buffer, "%lf", &data[i])) + throw MMException(string("Couldn't parse float number ")+buffer+"\n"); + i++; + } + if (i < len) { + char mes[1000]; + sprintf(mes,"Couldn't read all %d lines, read %d so far\n",len,i); + throw MMException(mes); + } + fclose(fd); +} + +MMMatrixIn::~MMMatrixIn() +{ + operator delete [](data); +} + + +void MMMatrixOut::write(const char* fname, int rows, int cols, const double* data) +{ + FILE* fd; + if (NULL==(fd = fopen(fname,"w"))) + throw MMException(string("Cannot open file ")+fname+" for writing\n"); + + if (0 > fprintf(fd, "%%%%MatrixMarket matrix array real general\n")) + throw MMException(string("Output error when writing file ")+fname); + if (0 > fprintf(fd, "%d %d\n", rows, cols)) + throw MMException(string("Output error when writing file ")+fname); + int running = 0; + for (int i = 0; i < cols; i++) { + for (int j = 0 ; j < rows; j++) { + if (0 > fprintf(fd, "%40.35g\n", data[running])) + throw MMException(string("Output error when writing file ")+fname); + running++; + } + } + fclose(fd); +} + +void MMMatrixOut::write(const char* fname, const GeneralMatrix& m) +{ + write(fname, m.numRows(), m.numCols(), m.base()); +} diff --git a/mex/sources/korderpert/Dyn_pp/sylv/testing/MMMatrix.h b/mex/sources/korderpert/Dyn_pp/sylv/testing/MMMatrix.h new file mode 100644 index 000000000..e30842caf --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/testing/MMMatrix.h @@ -0,0 +1,46 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/testing/MMMatrix.h,v 1.1.1.1 2004/06/04 13:01:13 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#ifndef MM_MATRIX_H +#define MM_MATRIX_H + +#include "GeneralMatrix.h" +#include "SylvMemory.h" + +#include + +using namespace std; + +class MMException : public MallocAllocator { + string message; +public: + MMException(string mes) : message(mes) {} + MMException(const char* mes) : message(mes) {} + const char* getMessage() const {return message.data();} +}; + +class MMMatrixIn : public MallocAllocator { + double* data; + int rows; + int cols; +public: + MMMatrixIn(const char* fname); + ~MMMatrixIn(); + const double* getData() const {return data;} + int size() const {return rows*cols;} + int row() const {return rows;} + int col() const {return cols;} +}; + +class MMMatrixOut : public MallocAllocator { +public: + static void write(const char* fname, int rows, int cols, const double* data); + static void write(const char* fname, const GeneralMatrix& m); +}; + +#endif /* MM_MATRIX_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/sylv/testing/Makefile b/mex/sources/korderpert/Dyn_pp/sylv/testing/Makefile new file mode 100644 index 000000000..924cb3ee8 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/testing/Makefile @@ -0,0 +1,36 @@ +# $Header: /var/lib/cvs/dynare_cpp/sylv/testing/Makefile,v 1.2 2004/09/28 16:16:43 kamenik Exp $ + +# Tag $Name: $ + +LD_LIBS := -llapack -lcblas -lf77blas -latlas -lg2c +CC_FLAGS := -Wall -I../cc $(CC_INCLUDE_PATH) +CC_DEFS := #-DUSE_MEMORY_POOL +ifeq ($(DEBUG),yes) + CC_FLAGS := $(CC_FLAGS) -g + CC_DEFS := $(CC_DEFS) -DDEBUG +else + CC_FLAGS := $(CC_FLAGS) -O2 +endif + +objects := $(patsubst %.cpp,%.o,$(wildcard ../cc/*.cpp)) +headers := $(wildcard ../cc/*.h) + +clear: + make -C ../cc clear + rm -f tests.exe + rm -f tests + rm -f *.o + +../cc/%.o : ../cc/%.cpp $(headers) + make EXTERN_DEFS="$(CC_DEFS)" -C ../cc $*.o + +%.o : %.cpp $(headers) + $(CC) $(CC_FLAGS) $(CC_DEFS) -c $*.cpp + +# untar testing data +tdata.done : tdata.tgz + tar -xzf tdata.tgz + touch tdata.done + +test: $(objects) tests.o MMMatrix.o tdata.done + $(CC) $(CC_FLAGS) -o test $(objects) tests.o MMMatrix.o $(LD_LIBS) diff --git a/mex/sources/korderpert/Dyn_pp/sylv/testing/tdata.tgz b/mex/sources/korderpert/Dyn_pp/sylv/testing/tdata.tgz new file mode 100644 index 000000000..e659354f2 Binary files /dev/null and b/mex/sources/korderpert/Dyn_pp/sylv/testing/tdata.tgz differ diff --git a/mex/sources/korderpert/Dyn_pp/sylv/testing/tests.cpp b/mex/sources/korderpert/Dyn_pp/sylv/testing/tests.cpp new file mode 100644 index 000000000..27a3f0120 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/sylv/testing/tests.cpp @@ -0,0 +1,1022 @@ +/* $Header: /var/lib/cvs/dynare_cpp/sylv/testing/tests.cpp,v 1.2 2004/07/05 19:55:48 kamenik Exp $ */ + +/* Tag $Name: $ */ + +#include "SylvException.h" +#include "QuasiTriangular.h" +#include "QuasiTriangularZero.h" +#include "Vector.h" +#include "KronVector.h" +#include "KronUtils.h" +#include "TriangularSylvester.h" +#include "GeneralSylvester.h" +#include "SylvMemory.h" +#include "SchurDecompEig.h" +#include "SimilarityDecomp.h" +#include "IterativeSylvester.h" +#include "SylvMatrix.h" + +#include "MMMatrix.h" + +#include +#include +#include + +#include + +class TestRunnable : public MallocAllocator { + char name[100]; + static double eps_norm; +public: + TestRunnable(const char* n){strncpy(name, n, 100);} + bool test() const; + virtual bool run() const =0; + const char* getName() const {return name;} +protected: + // declaration of auxiliary static methods + static bool quasi_solve(bool trans, const char* mname, const char* vname); + static bool mult_kron(bool trans, const char* mname, const char* vname, + const char* cname, int m, int n, int depth); + static bool level_kron(bool trans, const char* mname, const char* vname, + const char* cname, int level, int m, int n, int depth); + static bool kron_power(const char* m1name, const char* m2name, const char* vname, + const char* cname, int m, int n, int depth); + static bool lin_eval(const char* m1name, const char* m2name, const char* vname, + const char* cname, int m, int n, int depth, + double alpha, double beta1, double beta2); + static bool qua_eval(const char* m1name, const char* m2name, const char* vname, + const char* cname, int m, int n, int depth, + double alpha, double betas, double gamma, + double delta1, double delta2); + static bool tri_sylv(const char* m1name, const char* m2name, const char* vname, + int m, int n, int depth); + static bool gen_sylv(const char* aname, const char* bname, const char* cname, + const char* dname, int m, int n, int order); + static bool eig_bubble(const char* aname, int from, int to); + static bool block_diag(const char* aname, double log10norm = 3.0); + static bool iter_sylv(const char* m1name, const char* m2name, const char* vname, + int m, int n, int depth); +}; + +double TestRunnable::eps_norm = 1.0e-10; + +bool TestRunnable::test() const +{ + printf("Running test <%s>\n",name); + clock_t start = clock(); + bool passed = run(); + clock_t end = clock(); + printf("CPU time %8.4g (CPU seconds)..................", + ((double)(end-start))/CLOCKS_PER_SEC); + if (passed) { + printf("passed\n\n"); + return passed; + } else { + printf("FAILED\n\n"); + return passed; + } +} + +/**********************************************************/ +/* auxiliary methods */ +/**********************************************************/ + +bool TestRunnable::quasi_solve(bool trans, const char* mname, const char* vname) +{ + MMMatrixIn mmt(mname); + MMMatrixIn mmv(vname); + + SylvMemoryDriver memdriver(1, mmt.row(), mmt.row(), 1); + QuasiTriangular* t; + QuasiTriangular* tsave; + if (mmt.row()==mmt.col()) { + t = new QuasiTriangular(mmt.getData(), mmt.row()); + tsave = new QuasiTriangular(*t); + } else if (mmt.row()>mmt.col()) { + t = new QuasiTriangularZero(mmt.row()-mmt.col(), mmt.getData(), mmt.col()); + tsave = new QuasiTriangularZero((const QuasiTriangularZero&)*t); + } else { + printf(" Wrong quasi triangular dimensions, rows must be >= cols.\n"); + return false; + } + ConstVector v(mmv.getData(), mmv.row()); + Vector x(v.length()); + double eig_min = 1.0e20; + if (trans) + t->solveTrans(x, v, eig_min); + else + t->solve(x, v, eig_min); + printf("eig_min = %8.4g\n", eig_min); + Vector xx(v.length()); + if (trans) + tsave->multVecTrans(xx, ConstVector(x)); + else + tsave->multVec(xx, ConstVector(x)); + delete tsave; + delete t; + xx.add(-1.0, v); + xx.add(1.0, x); + double norm = xx.getNorm(); + printf("\terror norm = %8.4g\n",norm); + return (norm < eps_norm); +} + +bool TestRunnable::mult_kron(bool trans, const char* mname, const char* vname, + const char* cname, int m, int n, int depth) +{ + MMMatrixIn mmt(mname); + MMMatrixIn mmv(vname); + MMMatrixIn mmc(cname); + + int length = power(m,depth)*n; + if (mmt.row() != m || + mmv.row() != length || + mmc.row() != length) { + printf(" Incompatible sizes for krom mult action, len=%d, matrow=%d, m=%d, vrow=%d, crow=%d \n",length,mmt.row(), m, mmv.row(), mmc.row()); + return false; + } + + SylvMemoryDriver memdriver(1, m, n, depth); + QuasiTriangular t(mmt.getData(), mmt.row()); + Vector vraw(mmv.getData(), mmv.row()); + KronVector v(vraw, m, n, depth); + Vector craw(mmc.getData(), mmc.row()); + KronVector c(craw, m, n, depth); + if (trans) + t.multKronTrans(v); + else + t.multKron(v); + c.add(-1.0, v); + double norm = c.getNorm(); + printf("\terror norm = %8.4g\n",norm); + return (norm < eps_norm); +} + +bool TestRunnable::level_kron(bool trans, const char* mname, const char* vname, + const char* cname, int level, int m, int n, int depth) +{ + MMMatrixIn mmt(mname); + MMMatrixIn mmv(vname); + MMMatrixIn mmc(cname); + + int length = power(m,depth)*n; + if (level > 0 && mmt.row() != m || + level == 0 && mmt.row() != n || + mmv.row() != length || + mmc.row() != length) { + printf(" Incompatible sizes for krom mult action, len=%d, matrow=%d, m=%d, n=%d, vrow=%d, crow=%d \n",length, mmt.row(), m, n, mmv.row(), mmc.row()); + return false; + } + + SylvMemoryDriver memdriver(1, m, n, depth); + QuasiTriangular t(mmt.getData(), mmt.row()); + Vector vraw(mmv.getData(), mmv.row()); + ConstKronVector v(vraw, m, n, depth); + Vector craw(mmc.getData(), mmc.row()); + KronVector c(craw, m, n, depth); + KronVector x(v); + if (trans) + KronUtils::multAtLevelTrans(level, t, x); + else + KronUtils::multAtLevel(level, t, x); + x.add(-1, c); + double norm = x.getNorm(); + printf("\terror norm = %8.4g\n",norm); + return (norm < eps_norm); +} + +bool TestRunnable::kron_power(const char* m1name, const char* m2name, const char* vname, + const char* cname, int m, int n, int depth) +{ + MMMatrixIn mmt1(m1name); + MMMatrixIn mmt2(m2name); + MMMatrixIn mmv(vname); + MMMatrixIn mmc(cname); + + int length = power(m,depth)*n; + if (mmt1.row() != m || + mmt2.row() != n || + mmv.row() != length || + mmc.row() != length) { + printf(" Incompatible sizes for krom power mult action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d, crow=%d \n",length,mmt1.row(), mmt2.row(), m, n, mmv.row(), mmc.row()); + return false; + } + + SylvMemoryDriver memdriver(2, m, n, depth); + QuasiTriangular t1(mmt1.getData(), mmt1.row()); + QuasiTriangular t2(mmt2.getData(), mmt2.row()); + Vector vraw(mmv.getData(), mmv.row()); + ConstKronVector v(vraw, m, n, depth); + Vector craw(mmc.getData(), mmc.row()); + KronVector c(craw, m, n, depth); + KronVector x(v); + memdriver.setStackMode(true); + KronUtils::multKron(t1, t2, x); + memdriver.setStackMode(false); + x.add(-1, c); + double norm = x.getNorm(); + printf("\terror norm = %8.4g\n",norm); + return (norm < eps_norm); +} + +bool TestRunnable::lin_eval(const char* m1name, const char* m2name, const char* vname, + const char* cname, int m, int n, int depth, + double alpha, double beta1, double beta2) +{ + MMMatrixIn mmt1(m1name); + MMMatrixIn mmt2(m2name); + MMMatrixIn mmv(vname); + MMMatrixIn mmc(cname); + + int length = power(m,depth)*n; + if (mmt1.row() != m || + mmt2.row() != n || + mmv.row() != 2*length || + mmc.row() != 2*length) { + printf(" Incompatible sizes for lin eval action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d, crow=%d \n",length,mmt1.row(), mmt2.row(), m, n, mmv.row(), mmc.row()); + return false; + } + + SylvMemoryDriver memdriver(1, m, n, depth); + QuasiTriangular t1(mmt1.getData(), mmt1.row()); + QuasiTriangular t2(mmt2.getData(), mmt2.row()); + TriangularSylvester ts(t2, t1); + Vector vraw1(mmv.getData(), length); + ConstKronVector v1(vraw1, m, n, depth); + Vector vraw2(mmv.getData()+length, length); + ConstKronVector v2(vraw2, m, n, depth); + Vector craw1(mmc.getData(), length); + KronVector c1(craw1, m, n, depth); + Vector craw2(mmc.getData()+length, length); + KronVector c2(craw2, m, n, depth); + KronVector x1(m, n, depth); + KronVector x2(m, n, depth); + memdriver.setStackMode(true); + ts.linEval(alpha, beta1, beta2, x1, x2, v1, v2); + memdriver.setStackMode(false); + x1.add(-1, c1); + x2.add(-1, c2); + double norm1 = x1.getNorm(); + double norm2 = x2.getNorm(); + printf("\terror norm1 = %8.4g\n\terror norm2 = %8.4g\n",norm1,norm2); + return (norm1*norm1+norm2*norm2 < eps_norm*eps_norm); +} + + +bool TestRunnable::qua_eval(const char* m1name, const char* m2name, const char* vname, + const char* cname, int m, int n, int depth, + double alpha, double betas, double gamma, + double delta1, double delta2) +{ + MMMatrixIn mmt1(m1name); + MMMatrixIn mmt2(m2name); + MMMatrixIn mmv(vname); + MMMatrixIn mmc(cname); + + int length = power(m,depth)*n; + if (mmt1.row() != m || + mmt2.row() != n || + mmv.row() != 2*length || + mmc.row() != 2*length) { + printf(" Incompatible sizes for qua eval action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d, crow=%d \n",length,mmt1.row(), mmt2.row(), m, n, mmv.row(), mmc.row()); + return false; + } + + SylvMemoryDriver memdriver(3, m, n, depth); + QuasiTriangular t1(mmt1.getData(), mmt1.row()); + QuasiTriangular t2(mmt2.getData(), mmt2.row()); + TriangularSylvester ts(t2, t1); + Vector vraw1(mmv.getData(), length); + ConstKronVector v1(vraw1, m, n, depth); + Vector vraw2(mmv.getData()+length, length); + ConstKronVector v2(vraw2, m, n, depth); + Vector craw1(mmc.getData(), length); + KronVector c1(craw1, m, n, depth); + Vector craw2(mmc.getData()+length, length); + KronVector c2(craw2, m, n, depth); + KronVector x1(m, n, depth); + KronVector x2(m, n, depth); + memdriver.setStackMode(true); + ts.quaEval(alpha, betas, gamma, delta1, delta2, x1, x2, v1, v2); + memdriver.setStackMode(false); + x1.add(-1, c1); + x2.add(-1, c2); + double norm1 = x1.getNorm(); + double norm2 = x2.getNorm(); + printf("\terror norm1 = %8.4g\n\terror norm2 = %8.4g\n",norm1,norm2); + return (norm1*norm1+norm2*norm2 < 100*eps_norm*eps_norm); // relax norm +} + +bool TestRunnable::tri_sylv(const char* m1name, const char* m2name, const char* vname, + int m, int n, int depth) +{ + MMMatrixIn mmt1(m1name); + MMMatrixIn mmt2(m2name); + MMMatrixIn mmv(vname); + + int length = power(m,depth)*n; + if (mmt1.row() != m || + mmt2.row() != n || + mmv.row() != length) { + printf(" Incompatible sizes for triangular sylvester action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d\n",length,mmt1.row(), mmt2.row(), m, n, mmv.row()); + return false; + } + + SylvMemoryDriver memdriver(4, m, n, depth); // need extra 2 for checks done via KronUtils::multKron + memdriver.setStackMode(true); + QuasiTriangular t1(mmt1.getData(), mmt1.row()); + QuasiTriangular t2(mmt2.getData(), mmt2.row()); + TriangularSylvester ts(t2, t1); + Vector vraw(mmv.getData(), length); + ConstKronVector v(vraw, m, n, depth); + KronVector d(v); // copy of v + SylvParams pars; + ts.solve(pars, d); + pars.print("\t"); + KronVector dcheck((const KronVector&)d); + KronUtils::multKron(t1, t2, dcheck); + dcheck.add(1.0, d); + dcheck.add(-1.0, v); + double norm = dcheck.getNorm(); + double xnorm = v.getNorm(); + printf("\trel. error norm = %8.4g\n",norm/xnorm); + double max = dcheck.getMax(); + double xmax = v.getMax(); + printf("\trel. error max = %8.4g\n", max/xmax); + memdriver.setStackMode(false); + return (norm < xnorm*eps_norm); +} + +bool TestRunnable::gen_sylv(const char* aname, const char* bname, const char* cname, + const char* dname, int m, int n, int order) +{ + MMMatrixIn mma(aname); + MMMatrixIn mmb(bname); + MMMatrixIn mmc(cname); + MMMatrixIn mmd(dname); + + if (m != mmc.row() || m != mmc.col() || + n != mma.row() || n != mma.col() || + n != mmb.row() || n < mmb.col() || + n != mmd.row() || power(m, order) != mmd.col()) { + printf(" Incompatible sizes for gen_sylv.\n"); + return false; + } + + SylvParams ps(true); + GeneralSylvester gs(order, n, m, n-mmb.col(), + mma.getData(), mmb.getData(), + mmc.getData(), mmd.getData(), + ps); + gs.solve(); + gs.check(mmd.getData()); + const SylvParams& pars = gs.getParams(); + pars.print("\t"); + return (*(pars.mat_err1) < eps_norm && *(pars.mat_errI) < eps_norm && + *(pars.mat_errF) < eps_norm && *(pars.vec_err1) < eps_norm && + *(pars.vec_errI) < eps_norm); +} + +bool TestRunnable::eig_bubble(const char* aname, int from, int to) +{ + MMMatrixIn mma(aname); + + if (mma.row() != mma.col()) { + printf(" Matrix is not square\n"); + return false; + } + + int n = mma.row(); + SylvMemoryDriver memdriver(3, n, n, 2); + QuasiTriangular orig(mma.getData(), n); + SchurDecompEig dec((const QuasiTriangular&)orig); + QuasiTriangular::diag_iter itf = dec.getT().diag_begin(); + QuasiTriangular::diag_iter itt = dec.getT().diag_begin(); + for (int i = 0; i < from; i++) + ++itf; + for (int i = 0; i < to; i++) + ++itt; + itt = dec.bubbleEigen(itf, itt); + SqSylvMatrix check(dec.getQ(), dec.getT()); + check.multRightTrans(dec.getQ()); + check.add(-1, orig); + double norm1 = check.getNorm1(); + double normInf = check.getNormInf(); + double onorm1 = orig.getNorm1(); + double onormInf = orig.getNormInf(); + printf("\tabs. error1 = %8.4g\n", norm1); + printf("\tabs. errorI = %8.4g\n", normInf); + printf("\trel. error1 = %8.4g\n", norm1/onorm1); + printf("\trel. errorI = %8.4g\n", normInf/onormInf); + return (norm1 < eps_norm*onorm1 && normInf < eps_norm*onormInf); +} + +bool TestRunnable::block_diag(const char* aname, double log10norm) +{ + MMMatrixIn mma(aname); + + if (mma.row() != mma.col()) { + printf(" Matrix is not square\n"); + return false; + } + + int n = mma.row(); + SylvMemoryDriver memdriver(3, n, n, 2); + SqSylvMatrix orig(mma.getData(), n); + SimilarityDecomp dec(orig.base(), orig.numRows(), log10norm); + dec.getB().printInfo(); + SqSylvMatrix check(dec.getQ(), dec.getB()); + check.multRight(dec.getInvQ()); + check.add(-1, orig); + double norm1 = check.getNorm1(); + double normInf = check.getNormInf(); + double onorm1 = orig.getNorm1(); + double onormInf = orig.getNormInf(); + printf("\terror Q*B*invQ:\n"); + printf("\tabs. error1 = %8.4g\n", norm1); + printf("\tabs. errorI = %8.4g\n", normInf); + printf("\trel. error1 = %8.4g\n", norm1/onorm1); + printf("\trel. errorI = %8.4g\n", normInf/onormInf); + SqSylvMatrix check2(dec.getQ(), dec.getInvQ()); + SqSylvMatrix in(n); + in.setUnit(); + check2.add(-1, in); + double nor1 = check2.getNorm1(); + double norInf = check2.getNormInf(); + printf("\terror Q*invQ:\n"); + printf("\tabs. error1 = %8.4g\n", nor1); + printf("\tabs. errorI = %8.4g\n", norInf); + return (norm1 < eps_norm*pow(10, log10norm)*onorm1); +} + +bool TestRunnable::iter_sylv(const char* m1name, const char* m2name, const char* vname, + int m, int n, int depth) +{ + MMMatrixIn mmt1(m1name); + MMMatrixIn mmt2(m2name); + MMMatrixIn mmv(vname); + + int length = power(m,depth)*n; + if (mmt1.row() != m || + mmt2.row() != n || + mmv.row() != length) { + printf(" Incompatible sizes for triangular sylvester iteration, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d\n",length,mmt1.row(), mmt2.row(), m, n, mmv.row()); + return false; + } + + SylvMemoryDriver memdriver(4, m, n, depth); // need extra 2 for checks done via KronUtils::multKron + memdriver.setStackMode(true); + QuasiTriangular t1(mmt1.getData(), mmt1.row()); + QuasiTriangular t2(mmt2.getData(), mmt2.row()); + IterativeSylvester is(t2, t1); + Vector vraw(mmv.getData(), length); + ConstKronVector v(vraw, m, n, depth); + KronVector d(v); // copy of v + SylvParams pars; + pars.method = SylvParams::iter; + is.solve(pars, d); + pars.print("\t"); + KronVector dcheck((const KronVector&)d); + KronUtils::multKron(t1, t2, dcheck); + dcheck.add(1.0, d); + dcheck.add(-1.0, v); + double cnorm = dcheck.getNorm(); + double xnorm = v.getNorm(); + printf("\trel. error norm = %8.4g\n",cnorm/xnorm); + double max = dcheck.getMax(); + double xmax = v.getMax(); + printf("\trel. error max = %8.4g\n", max/xmax); + memdriver.setStackMode(false); + return (cnorm < xnorm*eps_norm); +} + +/**********************************************************/ +/* sub classes declarations */ +/**********************************************************/ + +class PureTriangTest : public TestRunnable { +public: + PureTriangTest() : TestRunnable("pure triangular solve (5)") {} + bool run() const; +}; + +class PureTriangTransTest : public TestRunnable { +public: + PureTriangTransTest() : TestRunnable("pure triangular solve trans (5)") {} + bool run() const; +}; + +class PureTrLargeTest : public TestRunnable { +public: + PureTrLargeTest() : TestRunnable("pure triangular large solve (300)") {} + bool run() const; +}; + +class PureTrLargeTransTest : public TestRunnable { +public: + PureTrLargeTransTest() : TestRunnable("pure triangular large solve trans (300)") {} + bool run() const; +}; + +class QuasiTriangTest : public TestRunnable { +public: + QuasiTriangTest() : TestRunnable("quasi triangular solve (7)") {} + bool run() const; +}; + +class QuasiTriangTransTest : public TestRunnable { +public: + QuasiTriangTransTest() : TestRunnable("quasi triangular solve trans (7)") {} + bool run() const; +}; + +class QuasiTrLargeTest : public TestRunnable { +public: + QuasiTrLargeTest() : TestRunnable("quasi triangular solve large (250)") {} + bool run() const; +}; + +class QuasiTrLargeTransTest : public TestRunnable { +public: + QuasiTrLargeTransTest() : TestRunnable("quasi triangular solve large trans (250)") {} + bool run() const; +}; + +class QuasiZeroSmallTest : public TestRunnable { +public: + QuasiZeroSmallTest() : TestRunnable("quasi tr. zero small test (2x1)") {} + bool run() const; +}; + +class MultKronSmallTest : public TestRunnable { +public: + MultKronSmallTest() : TestRunnable("kronecker small mult (2=2x1)") {} + bool run() const; +}; + +class MultKronTest : public TestRunnable { +public: + MultKronTest() : TestRunnable("kronecker mult (245=7x7x5)") {} + bool run() const; +}; + +class MultKronSmallTransTest : public TestRunnable { +public: + MultKronSmallTransTest() : TestRunnable("kronecker small trans mult (2=2x1)") {} + bool run() const; +}; + +class MultKronTransTest : public TestRunnable { +public: + MultKronTransTest() : TestRunnable("kronecker trans mult (245=7x7x5)") {} + bool run() const; +}; + +class LevelKronTest : public TestRunnable { +public: + LevelKronTest() : TestRunnable("kronecker level mult (1715=7x[7]x7x5)") {} + bool run() const; +}; + +class LevelKronTransTest : public TestRunnable { +public: + LevelKronTransTest() : TestRunnable("kronecker level trans mult (1715=7x[7]x7x5)") {} + bool run() const; +}; + +class LevelZeroKronTest : public TestRunnable { +public: + LevelZeroKronTest() : TestRunnable("kronecker level mult (1715=7x7x7x[5])") {} + bool run() const; +}; + +class LevelZeroKronTransTest : public TestRunnable { +public: + LevelZeroKronTransTest() : TestRunnable("kronecker level trans mult (1715=7x7x7x[5])") {} + bool run() const; +}; + +class KronPowerTest : public TestRunnable { +public: + KronPowerTest() : TestRunnable("kronecker power mult (1715=7x7x7x5)") {} + bool run() const; +}; + +class SmallLinEvalTest : public TestRunnable { +public: + SmallLinEvalTest() : TestRunnable("lin eval (24=2 x 2x2x3)") {} + bool run() const; +}; + +class LinEvalTest : public TestRunnable { +public: + LinEvalTest() : TestRunnable("lin eval (490=2 x 7x7x5)") {} + bool run() const; +}; + +class SmallQuaEvalTest : public TestRunnable { +public: + SmallQuaEvalTest() : TestRunnable("qua eval (24=2 x 2x2x3)") {} + bool run() const; +}; + +class QuaEvalTest : public TestRunnable { +public: + QuaEvalTest() : TestRunnable("qua eval (490=2 x 7x7x5)") {} + bool run() const; +}; + +class TriSylvSmallRealTest : public TestRunnable { +public: + TriSylvSmallRealTest() : TestRunnable("triangular sylvester small real solve (12=2x2x3)") {} + bool run() const; +}; + +class TriSylvSmallComplexTest : public TestRunnable { +public: + TriSylvSmallComplexTest() : TestRunnable("triangular sylvester small complx solve (12=2x2x3)") {} + bool run() const; +}; + +class TriSylvTest : public TestRunnable { +public: + TriSylvTest() : TestRunnable("triangular sylvester solve (245=7x7x5)") {} + bool run() const; +}; + +class TriSylvBigTest : public TestRunnable { +public: + TriSylvBigTest() : TestRunnable("triangular sylvester big solve (48000=40x40x30)") {} + bool run() const; +}; + +class TriSylvLargeTest : public TestRunnable { +public: + TriSylvLargeTest() : TestRunnable("triangular sylvester large solve (1920000=40x40x40x30)") {} + bool run() const; +}; + +class IterSylvTest : public TestRunnable { +public: + IterSylvTest() : TestRunnable("iterative sylvester solve (245=7x7x5)") {} + bool run() const; +}; + +class IterSylvLargeTest : public TestRunnable { +public: + IterSylvLargeTest() : TestRunnable("iterative sylvester large solve (1920000=40x40x40x30)") {} + bool run() const; +}; + +class GenSylvSmallTest : public TestRunnable { +public: + GenSylvSmallTest() : TestRunnable("general sylvester small solve (18=3x3x2)") {} + bool run() const; +}; + +class GenSylvTest : public TestRunnable { +public: + GenSylvTest() : TestRunnable("general sylvester solve (12000=20x20x30)") {} + bool run() const; +}; + +class GenSylvSingTest : public TestRunnable { +public: + GenSylvSingTest() : TestRunnable("general sylvester solve for sing. C (2500000=50x50x50x20)") {} + bool run() const; +}; + +class GenSylvLargeTest : public TestRunnable { +public: + GenSylvLargeTest() : TestRunnable("general sylvester solve (2500000=50x50x50x20)") {} + bool run() const; +}; + +class EigBubFrankTest : public TestRunnable { +public: + EigBubFrankTest() : TestRunnable("eig. bubble frank test (12x12)") {} + bool run() const; +}; + +class EigBubSplitTest : public TestRunnable { +// complex eigenvalue is split by swapping it with real +public: + EigBubSplitTest() : TestRunnable("eig. bubble complex split test (3x3)") {} + bool run() const; +}; + +class EigBubSameTest : public TestRunnable { +// complex eigenevalue bypasses the same complex eigenvalue +public: + EigBubSameTest() : TestRunnable("eig. bubble same test (5x5)") {} + bool run() const; +}; + +class BlockDiagSmallTest : public TestRunnable { +public: + BlockDiagSmallTest() : TestRunnable("block diagonalization small test (7x7)") {} + bool run() const; +}; + +class BlockDiagFrankTest : public TestRunnable { +public: + BlockDiagFrankTest() : TestRunnable("block diagonalization of frank (12x12)") {} + bool run() const; +}; + +class BlockDiagIllCondTest : public TestRunnable { +public: + BlockDiagIllCondTest() : TestRunnable("block diagonalization of ill conditioned (15x15)") {} + bool run() const; +}; + +class BlockDiagBigTest : public TestRunnable { +public: + BlockDiagBigTest() : TestRunnable("block diagonalization big test (50x50)") {} + bool run() const; +}; + +/**********************************************************/ +/* run methods of sub classes */ +/**********************************************************/ + +bool PureTriangTest::run() const +{ + return quasi_solve(false, "tr5x5.mm", "v5.mm"); +} + +bool PureTriangTransTest::run() const +{ + return quasi_solve(true, "tr5x5.mm", "v5.mm"); +} + +bool PureTrLargeTest::run() const +{ + return quasi_solve(false, "tr300x300.mm", "v300.mm"); +} + +bool PureTrLargeTransTest::run() const +{ + return quasi_solve(true, "tr300x300.mm", "v300.mm"); +} + +bool QuasiTriangTest::run() const +{ + return quasi_solve(false, "qt7x7.mm", "v7.mm"); +} + +bool QuasiTriangTransTest::run() const +{ + return quasi_solve(true, "qt7x7.mm", "v7.mm"); +} + +bool QuasiTrLargeTest::run() const +{ + return quasi_solve(false, "qt250x250.mm", "v250.mm"); +} + +bool QuasiTrLargeTransTest::run() const +{ + return quasi_solve(true, "qt250x250.mm", "v250.mm"); +} + +bool QuasiZeroSmallTest::run() const +{ + return quasi_solve(false, "b2x1.mm", "v2.mm"); +} + +bool MultKronSmallTest::run() const +{ + return mult_kron(false, "tr2x2.mm", "v2.mm", "vcheck2.mm", 2, 1, 1); +} + +bool MultKronTest::run() const +{ + return mult_kron(false, "qt7x7.mm", "v245.mm", "vcheck245.mm", 7, 5, 2); +} + +bool MultKronSmallTransTest::run() const +{ + return mult_kron(true, "tr2x2.mm", "v2.mm", "vcheck2a.mm", 2, 1, 1); +} + +bool MultKronTransTest::run() const +{ + return mult_kron(true, "qt7x7.mm", "v245.mm", "vcheck245a.mm", 7, 5, 2); +} + +bool LevelKronTest::run() const +{ + return level_kron(false, "qt7x7.mm", "v1715.mm", "vcheck1715.mm", 2, 7, 5, 3); +} + +bool LevelKronTransTest::run() const +{ + return level_kron(true, "qt7x7.mm", "v1715.mm", "vcheck1715a.mm", 2, 7, 5, 3); +} + +bool LevelZeroKronTest::run() const +{ + return level_kron(false, "tr5x5.mm", "v1715.mm", "vcheck1715b.mm", 0, 7, 5, 3); +} + +bool LevelZeroKronTransTest::run() const +{ + return level_kron(true, "tr5x5.mm", "v1715.mm", "vcheck1715c.mm", 0, 7, 5, 3); +} + +bool KronPowerTest::run() const +{ + return kron_power("qt7x7.mm", "tr5x5.mm", "v1715.mm", "vcheck1715d.mm", 7, 5, 3); +} + +bool SmallLinEvalTest::run() const +{ + return lin_eval("qt2x2.mm", "qt3x3.mm", "v24.mm", "vcheck24.mm", 2, 3, 2, + 2, 1, 3); +} + +bool LinEvalTest::run() const +{ + return lin_eval("qt7x7.mm", "tr5x5.mm", "v490.mm", "vcheck490.mm", 7, 5, 2, + 2, 1, 3); +} + +bool SmallQuaEvalTest::run() const +{ + return qua_eval("qt2x2.mm", "qt3x3.mm", "v24.mm", "vcheck24q.mm", 2, 3, 2, + -0.5, 3, 2, 1, 3); +} + +bool QuaEvalTest::run() const +{ + return qua_eval("qt7x7.mm", "tr5x5.mm", "v490.mm", "vcheck490q.mm", 7, 5, 2, + -0.5, 3, 2, 1, 3); +} + +bool TriSylvSmallRealTest::run() const +{ + return tri_sylv("tr2x2.mm", "qt3x3.mm", "v12r.mm", 2, 3, 2); +} + +bool TriSylvSmallComplexTest::run() const +{ + return tri_sylv("qt2x2.mm", "qt3x3.mm", "v12r.mm", 2, 3, 2); +} + +bool TriSylvTest::run() const +{ + return tri_sylv("qt7x7eig06-09.mm", "tr5x5.mm", "v245r.mm", 7, 5, 2); +} + +bool TriSylvBigTest::run() const +{ + return tri_sylv("qt40x40.mm", "qt30x30eig011-095.mm", "v48000.mm", 40, 30, 2); +} + +bool TriSylvLargeTest::run() const +{ + return tri_sylv("qt40x40.mm", "qt30x30eig011-095.mm", "v1920000.mm", 40, 30, 3); +} + +bool IterSylvTest::run() const +{ + return iter_sylv("qt7x7eig06-09.mm", "qt5x5.mm", "v245r.mm", 7, 5, 2); +} + +bool IterSylvLargeTest::run() const +{ + return iter_sylv("qt40x40.mm", "qt30x30eig011-095.mm", "v1920000.mm", 40, 30, 3); +} + +bool GenSylvSmallTest::run() const +{ + return gen_sylv("a2x2.mm", "b2x1.mm", "c3x3.mm", "d2x9.mm", 3, 2, 2); +} + +bool GenSylvTest::run() const +{ + return gen_sylv("a30x30.mm", "b30x25.mm", "c20x20.mm", "d30x400.mm", 20, 30, 2); +} + +bool GenSylvSingTest::run() const +{ + return gen_sylv("a20x20.mm", "b20x4.mm", "c50x50sing.mm", "d20x125000.mm", 50, 20, 3); +} + +bool GenSylvLargeTest::run() const +{ + return gen_sylv("a20x20.mm", "b20x15.mm", "c50x50.mm", "d20x125000.mm", 50, 20, 3); +} + +bool EigBubFrankTest::run() const +{ + return eig_bubble("qt_frank12x12.mm", 8, 0); +} + +bool EigBubSplitTest::run() const +{ + return eig_bubble("qt_eps3x3.mm",1,0); +} + +bool EigBubSameTest::run() const +{ + return eig_bubble("qt5x5.mm",2,0); +} + +bool BlockDiagSmallTest::run() const +{ + return block_diag("qt7x7.mm", 0.1); +} + +bool BlockDiagFrankTest::run() const +{ + return block_diag("qt_frank12x12.mm", 5); +} + +bool BlockDiagIllCondTest::run() const +{ + return block_diag("ill_cond15x15.mm", 4.14); +} + +bool BlockDiagBigTest::run() const +{ + return block_diag("c50x50.mm", 1.3); +} + +/**********************************************************/ +/* main */ +/**********************************************************/ + +int main() +{ + TestRunnable* all_tests[50]; + // fill in vector of all tests + int num_tests = 0; + all_tests[num_tests++] = new PureTriangTest(); + all_tests[num_tests++] = new PureTriangTransTest(); + all_tests[num_tests++] = new PureTrLargeTest(); + all_tests[num_tests++] = new PureTrLargeTransTest(); + all_tests[num_tests++] = new QuasiTriangTest(); + all_tests[num_tests++] = new QuasiTriangTransTest(); + all_tests[num_tests++] = new QuasiTrLargeTest(); + all_tests[num_tests++] = new QuasiTrLargeTransTest(); + all_tests[num_tests++] = new QuasiZeroSmallTest(); + all_tests[num_tests++] = new MultKronSmallTest(); + all_tests[num_tests++] = new MultKronTest(); + all_tests[num_tests++] = new MultKronSmallTransTest(); + all_tests[num_tests++] = new MultKronTransTest(); + all_tests[num_tests++] = new LevelKronTest(); + all_tests[num_tests++] = new LevelKronTransTest(); + all_tests[num_tests++] = new LevelZeroKronTest(); + all_tests[num_tests++] = new LevelZeroKronTransTest(); + all_tests[num_tests++] = new KronPowerTest(); + all_tests[num_tests++] = new SmallLinEvalTest(); + all_tests[num_tests++] = new LinEvalTest(); + all_tests[num_tests++] = new SmallQuaEvalTest(); + all_tests[num_tests++] = new QuaEvalTest(); + all_tests[num_tests++] = new EigBubFrankTest(); + all_tests[num_tests++] = new EigBubSplitTest(); + all_tests[num_tests++] = new EigBubSameTest(); + all_tests[num_tests++] = new BlockDiagSmallTest(); + all_tests[num_tests++] = new BlockDiagFrankTest(); + all_tests[num_tests++] = new BlockDiagIllCondTest(); + all_tests[num_tests++] = new BlockDiagBigTest(); + all_tests[num_tests++] = new TriSylvSmallRealTest(); + all_tests[num_tests++] = new TriSylvSmallComplexTest(); + all_tests[num_tests++] = new TriSylvTest(); + all_tests[num_tests++] = new TriSylvBigTest(); + all_tests[num_tests++] = new TriSylvLargeTest(); + all_tests[num_tests++] = new IterSylvTest(); + all_tests[num_tests++] = new IterSylvLargeTest(); + all_tests[num_tests++] = new GenSylvSmallTest(); + all_tests[num_tests++] = new GenSylvTest(); + all_tests[num_tests++] = new GenSylvSingTest(); + all_tests[num_tests++] = new GenSylvLargeTest(); + + // launch the tests + int success = 0; + for (int i = 0; i < num_tests; i++) { + try { + if (all_tests[i]->test()) + success++; + } catch (const MMException& e) { + printf("Caugth MM exception in <%s>:\n%s", all_tests[i]->getName(), + e.getMessage()); + } catch (SylvException& e) { + printf("Caught Sylv exception in %s:\n", all_tests[i]->getName()); + e.printMessage(); + } + } + + printf("There were %d tests that failed out of %d tests run.\n", + num_tests - success, num_tests); + + // destroy + for (int i = 0; i < num_tests; i++) { + delete all_tests[i]; + } + + return 0; +} + diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/Makefile b/mex/sources/korderpert/Dyn_pp/tl/cc/Makefile new file mode 100644 index 000000000..41e9c8d7d --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/Makefile @@ -0,0 +1,59 @@ +# $Id: Makefile 886 2006-09-01 11:56:07Z kamenik $ +# Copyright 2004, Ondra Kamenik + + +LD_LIBS := -llapack -lcblas -lf77blas -latlas -lg2c +CC_FLAGS := -Wall -I../../sylv/cc \ + $(CC_INCLUDE_PATH) + +ifeq ($(DEBUG),yes) + CC_FLAGS := $(CC_FLAGS) -g -DTL_DEBUG=2 +else + CC_FLAGS := $(CC_FLAGS) -O2 -DPOSIX_THREADS +endif + +ifeq ($(OS),Windows_NT) + CC_FLAGS := -mno-cygwin -mthreads $(CC_FLAGS) + LD_LIBS := -mno-cygwin -mthreads $(LD_LIBS) -lpthreadGC1 +else + LD_LIBS := $(LD_LIBS) -lpthread +endif + + +matrix_interface := GeneralMatrix Vector SylvException +matobjs := $(patsubst %, ../../sylv/cc/%.o, $(matrix_interface)) +cwebsource := $(wildcard *.cweb) +cppsource := $(patsubst %.cweb,%.cpp,$(cwebsource)) +objects := $(patsubst %.cweb,%.o,$(cwebsource)) +hwebsource := $(wildcard *.hweb) +hsource := $(patsubst %.hweb,%.h,$(hwebsource)) + + +dummy.ch: + touch dummy.ch + +%.cpp: %.cweb dummy.ch + ctangle -bhp $*.cweb dummy.ch $*.cpp + +%.h: %.hweb dummy.ch + ctangle -bhp $*.hweb dummy.ch $*.h + +%.o : %.cpp $(hsource) + $(CC) $(CC_FLAGS) $(EXTERN_DEFS) -c $*.cpp + +all: $(objects) $(cppsource) $(hsource) + +tl.pdf: doc + +doc: main.web $(hwebsource) $(cwebsource) + cweave -bhp main.web + pdftex main + mv main.pdf tl.pdf + +clear: + rm -f $(cppsource) + rm -f $(hsource) + rm -f *.o + rm -f main.{dvi,idx,log,pdf,scn,tex,toc} + rm -f dummy.ch + rm -f *~ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/equivalence.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/equivalence.cpp new file mode 100644 index 000000000..bebd284ee --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/equivalence.cpp @@ -0,0 +1,513 @@ +/*1:*/ +#line 6 "./equivalence.cweb" + +#include "equivalence.h" +#include "permutation.h" +#include "tl_exception.h" + +#include + +/*2:*/ +#line 19 "./equivalence.cweb" + +/*6:*/ +#line 57 "./equivalence.cweb" + +int OrdSequence::operator[](int i)const +{ +TL_RAISE_IF((i<0||i>=length()), +"Index out of range in OrdSequence::operator[]"); +return data[i]; +} + +/*:6*/ +#line 20 "./equivalence.cweb" +; +/*7:*/ +#line 69 "./equivalence.cweb" + +bool OrdSequence::operator<(const OrdSequence&s)const +{ +double ta= average(); +double sa= s.average(); +return(ta s[0]))); +} + +/*:7*/ +#line 21 "./equivalence.cweb" +; +/*8:*/ +#line 78 "./equivalence.cweb" + +bool OrdSequence::operator==(const OrdSequence&s)const +{ +if(length()!=s.length()) +return false; + +int i= 0; +while(i ::iterator vit= data.begin(); +while(vit!=data.end()&&*vit ::const_iterator vit= s.data.begin(); +while(vit!=s.data.end()){ +add(*vit); +++vit; +} +} + +/*:9*/ +#line 23 "./equivalence.cweb" +; +/*10:*/ +#line 117 "./equivalence.cweb" + +bool OrdSequence::has(int i)const +{ +vector ::const_iterator vit= data.begin(); +while(vit!=data.end()){ +if(*vit==i) +return true; +++vit; +} +return false; +} + +/*:10*/ +#line 24 "./equivalence.cweb" +; +/*11:*/ +#line 130 "./equivalence.cweb" + +double OrdSequence::average()const +{ +double res= 0; +for(unsigned int i= 0;i=out.size(), +"Wrong size of output sequence in Equivalence::trace"); +out[i]= (*it)[j]; +} +} + +/*:20*/ +#line 37 "./equivalence.cweb" +; +/*21:*/ +#line 307 "./equivalence.cweb" + +void Equivalence::trace(IntSequence&out,const Permutation&per)const +{ +TL_RAISE_IF(out.size()!=n, +"Wrong size of output sequence in Equivalence::trace"); +TL_RAISE_IF(per.size()!=numClasses(), +"Wrong permutation for permuted Equivalence::trace"); +int i= 0; +for(int iclass= 0;iclass added; +Equivalence first(n); +equis.push_back(first); +addParents(first,added); +while(!added.empty()){ +addParents(added.front(),added); +added.pop_front(); +} +if(n> 1){ +Equivalence last(n,""); +equis.push_back(last); +} +} + +/*:23*/ +#line 43 "./equivalence.cweb" +; +/*24:*/ +#line 386 "./equivalence.cweb" + +bool EquivalenceSet::has(const Equivalence&e)const +{ +list ::const_reverse_iterator rit= equis.rbegin(); +while(rit!=equis.rend()&&*rit!=e) +++rit; +if(rit!=equis.rend()) +return true; +return false; +} + +/*:24*/ +#line 44 "./equivalence.cweb" +; +/*25:*/ +#line 404 "./equivalence.cweb" + +void EquivalenceSet::addParents(const Equivalence&e, +list &added) +{ +if(e.numClasses()==2||e.numClasses()==1) +return; + +for(int i1= 0;i1 ::const_iterator it= equis.begin(); +it!=equis.end(); +++it,i++){ +printf("%sequivalence %d:(classes %d)\n",prefix,i,(*it).numClasses()); +(*it).print(tmp); +} +} + +/*:26*/ +#line 46 "./equivalence.cweb" +; + +/*:4*/ +#line 15 "./equivalence.cweb" +; +/*5:*/ +#line 49 "./equivalence.cweb" + +/*27:*/ +#line 438 "./equivalence.cweb" + +EquivalenceBundle::EquivalenceBundle(int nmax) +{ +nmax= max(nmax,1); +generateUpTo(nmax); +} + +/*:27*/ +#line 50 "./equivalence.cweb" +; +/*28:*/ +#line 446 "./equivalence.cweb" + +EquivalenceBundle::~EquivalenceBundle() +{ +for(unsigned int i= 0;i (int)(bundle.size())||n<1){ +TL_RAISE("Equivalence set not found in EquivalenceBundle::get"); +return*(bundle[0]); +}else{ +return*(bundle[n-1]); +} +} + +/*:29*/ +#line 52 "./equivalence.cweb" +; +/*30:*/ +#line 468 "./equivalence.cweb" + +void EquivalenceBundle::generateUpTo(int nmax) +{ +int curmax= bundle.size(); +for(int i= curmax+1;i<=nmax;i++) +bundle.push_back(new EquivalenceSet(i)); +} + + +/*:30*/ +#line 53 "./equivalence.cweb" +; + + +/*:5*/ +#line 16 "./equivalence.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/equivalence.h b/mex/sources/korderpert/Dyn_pp/tl/cc/equivalence.h new file mode 100644 index 000000000..2082debb6 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/equivalence.h @@ -0,0 +1,146 @@ +/*1:*/ +#line 46 "./equivalence.hweb" + +#ifndef EQUIVALENCE_H +#define EQUIVALENCE_H + +#include "int_sequence.h" + +#include +#include + +using namespace std; + +/*2:*/ +#line 72 "./equivalence.hweb" + +class OrdSequence{ +vector data; +public: +OrdSequence():data(){} +OrdSequence(const OrdSequence&s):data(s.data){} +const OrdSequence&operator= (const OrdSequence&s) +{data= s.data;return*this;} +bool operator==(const OrdSequence&s)const; +int operator[](int i)const; +bool operator<(const OrdSequence&s)const; +const vector &getData()const +{return data;} +int length()const{return data.size();} +void add(int i); +void add(const OrdSequence&s); +bool has(int i)const; +void print(const char*prefix)const; +private: +double average()const; +}; + + +/*:2*/ +#line 57 "./equivalence.hweb" +; +/*3:*/ +#line 101 "./equivalence.hweb" + +class Permutation; +class Equivalence{ +private: +int n; +list classes; +public: +typedef list ::const_iterator const_seqit; +typedef list ::iterator seqit; + +/*6:*/ +#line 178 "./equivalence.hweb" + +Equivalence(int num); +Equivalence(int num,const char*dummy); +Equivalence(const Equivalence&e); +Equivalence(const Equivalence&e,int i1,int i2); + +/*:6*/ +#line 111 "./equivalence.hweb" +; +const Equivalence&operator= (const Equivalence&e); +bool operator==(const Equivalence&e)const; +bool operator!=(const Equivalence&e)const +{return!operator==(e);} +int getN()const{return n;} +int numClasses()const{return classes.size();} +void trace(IntSequence&out,int n)const; +void trace(IntSequence&out)const +{trace(out,numClasses());} +void trace(IntSequence&out,const Permutation&per)const; +void print(const char*prefix)const; +/*7:*/ +#line 185 "./equivalence.hweb" + +seqit begin(){return classes.begin();} +const_seqit begin()const{return classes.begin();} +seqit end(){return classes.end();} +const_seqit end()const{return classes.end();} + +/*:7*/ +#line 123 "./equivalence.hweb" +; +const_seqit find(int i)const; +seqit find(int i); +protected: +/*8:*/ +#line 198 "./equivalence.hweb" + +const_seqit findHaving(int i)const; +seqit findHaving(int i); +void insert(const OrdSequence&s); + +/*:8*/ +#line 127 "./equivalence.hweb" +; +}; + +/*:3*/ +#line 58 "./equivalence.hweb" +; +/*4:*/ +#line 137 "./equivalence.hweb" + +class EquivalenceSet{ +int n; +list equis; +public: +typedef list ::const_iterator const_iterator; +EquivalenceSet(int num); +void print(const char*prefix)const; +const_iterator begin()const +{return equis.begin();} +const_iterator end()const +{return equis.end();} +private: +bool has(const Equivalence&e)const; +void addParents(const Equivalence&e,list &added); +}; + +/*:4*/ +#line 59 "./equivalence.hweb" +; +/*5:*/ +#line 161 "./equivalence.hweb" + +class EquivalenceBundle{ +vector bundle; +public: +EquivalenceBundle(int nmax); +~EquivalenceBundle(); +const EquivalenceSet&get(int n)const; +void generateUpTo(int nmax); +}; + +/*:5*/ +#line 60 "./equivalence.hweb" +; + +#endif + + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/fine_container.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/fine_container.cpp new file mode 100644 index 000000000..3efbf0dce --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/fine_container.cpp @@ -0,0 +1,39 @@ +/*1:*/ +#line 6 "./fine_container.cweb" + +#include "fine_container.h" + +#include + +/*2:*/ +#line 16 "./fine_container.cweb" + +SizeRefinement::SizeRefinement(const IntSequence&s,int nc,int max) +{ +new_nc= 0; +for(int i= 0;i 0)?(int)round(((double)s[i])/nr):0; +for(int j= 0;j + +/*2:*/ +#line 54 "./fine_container.hweb" + +class SizeRefinement{ +vector rsizes; +vector ind_map; +int new_nc; +public: +SizeRefinement(const IntSequence&s,int nc,int max); +int getRefSize(int i)const +{return rsizes[i];} +int numRefinements()const +{return rsizes.size();} +int getOldIndex(int i)const +{return ind_map[i];} +int getNC()const +{return new_nc;} +}; + + +/*:2*/ +#line 41 "./fine_container.hweb" +; +/*3:*/ +#line 77 "./fine_container.hweb" + +template +class FineContainer:public SizeRefinement,public StackContainer<_Ttype> { +protected: +typedef StackContainer<_Ttype> _Stype; +typedef typename StackContainerInterface<_Ttype> ::_Ctype _Ctype; +typedef typename StackContainerInterface<_Ttype> ::itype itype; +_Ctype**const ref_conts; +const _Stype&stack_cont; +public: +/*4:*/ +#line 109 "./fine_container.hweb" + +FineContainer(const _Stype&sc,int max) +:SizeRefinement(sc.getStackSizes(),sc.numConts(),max), +StackContainer<_Ttype> (numRefinements(),getNC()), +ref_conts(new _Ctype*[getNC()]), +stack_cont(sc) +{ +for(int i= 0;i ,public FoldedStackContainer{ +public: +FoldedFineContainer(const StackContainer &sc,int max) +:FineContainer (sc,max){} +}; + +/*:6*/ +#line 43 "./fine_container.hweb" +; +/*7:*/ +#line 156 "./fine_container.hweb" + +class UnfoldedFineContainer:public FineContainer ,public UnfoldedStackContainer{ +public: +UnfoldedFineContainer(const StackContainer &sc,int max) +:FineContainer (sc,max){} +}; + + +/*:7*/ +#line 44 "./fine_container.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/fs_tensor.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/fs_tensor.cpp new file mode 100644 index 000000000..ecd52348e --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/fs_tensor.cpp @@ -0,0 +1,321 @@ +/*1:*/ +#line 6 "./fs_tensor.cweb" + +#include "fs_tensor.h" +#include "gs_tensor.h" +#include "sparse_tensor.h" +#include "rfs_tensor.h" +#include "tl_exception.h" + +/*2:*/ +#line 39 "./fs_tensor.cweb" + +FFSTensor::FFSTensor(const FFSTensor&t,const ConstVector&x) +:FTensor(along_col,IntSequence(t.dimen()-1,t.nvar()), +t.nrows(),calcMaxOffset(t.nvar(),t.dimen()-1),t.dimen()-1), +nv(t.nvar()) +{ +TL_RAISE_IF(t.dimen()<1, +"Wrong dimension for tensor contraction of FFSTensor"); +TL_RAISE_IF(t.nvar()!=x.length(), +"Wrong number of variables for tensor contraction of FFSTensor"); + +zeros(); + +for(Tensor::index to= begin();to!=end();++to){ +for(int i= 0;i 0) +return 0; +return noverk(nvar+d-1,d); +} + +/*:3*/ +#line 14 "./fs_tensor.cweb" +; +/*4:*/ +#line 78 "./fs_tensor.cweb" + +FFSTensor::FFSTensor(const FSSparseTensor&t) +:FTensor(along_col,IntSequence(t.dimen(),t.nvar()), +t.nrows(),calcMaxOffset(t.nvar(),t.dimen()),t.dimen()), +nv(t.nvar()) +{ +zeros(); +for(FSSparseTensor::const_iterator it= t.getMap().begin(); +it!=t.getMap().end();++it){ +index ind(this,(*it).first); +get((*it).second.first,*ind)= (*it).second.second; +} +} + + +/*:4*/ +#line 15 "./fs_tensor.cweb" +; +/*5:*/ +#line 98 "./fs_tensor.cweb" + +FFSTensor::FFSTensor(const UFSTensor&ut) +:FTensor(along_col,IntSequence(ut.dimen(),ut.nvar()), +ut.nrows(),calcMaxOffset(ut.nvar(),ut.dimen()),ut.dimen()), +nv(ut.nvar()) +{ +for(index in= begin();in!=end();++in){ +index src(&ut,in.getCoor()); +copyColumn(ut,*src,*in); +} +} + +/*:5*/ +#line 16 "./fs_tensor.cweb" +; +/*6:*/ +#line 111 "./fs_tensor.cweb" + +UTensor&FFSTensor::unfold()const +{ +return*(new UFSTensor(*this)); +} + +/*:6*/ +#line 17 "./fs_tensor.cweb" +; +/*7:*/ +#line 122 "./fs_tensor.cweb" + +void FFSTensor::increment(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input/output vector size in FFSTensor::increment"); + +UTensor::increment(v,nv); +v.monotone(); +} + +/*:7*/ +#line 18 "./fs_tensor.cweb" +; +/*8:*/ +#line 134 "./fs_tensor.cweb" + +void FFSTensor::decrement(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input/output vector size in FFSTensor::decrement"); + +FTensor::decrement(v,nv); +} + +/*:8*/ +#line 19 "./fs_tensor.cweb" +; +/*9:*/ +#line 144 "./fs_tensor.cweb" + +int FFSTensor::getOffset(const IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input vector size in FFSTensor::getOffset"); + +return FTensor::getOffset(v,nv); +} + +/*:9*/ +#line 20 "./fs_tensor.cweb" +; +/*10:*/ +#line 163 "./fs_tensor.cweb" + +void FFSTensor::addSubTensor(const FGSTensor&t) +{ +TL_RAISE_IF(dimen()!=t.getDims().dimen(), +"Wrong dimensions for FFSTensor::addSubTensor"); +TL_RAISE_IF(nvar()!=t.getDims().getNVS().sum(), +"Wrong nvs for FFSTensor::addSubTensor"); + +/*11:*/ +#line 182 "./fs_tensor.cweb" + +IntSequence shift_pre(t.getSym().num(),0); +for(int i= 1;i=ss.size(), +"A coordinate out of stack range in TensorDimens slicing constructor"); + +for(int i= 0;i 0) +return 0; +if(sym[i]> 0) +res*= Tensor::noverk(nvs[i]+sym[i]-1,sym[i]); +} +return res; +} + +/*:4*/ +#line 14 "./gs_tensor.cweb" +; +/*5:*/ +#line 95 "./gs_tensor.cweb" + +int TensorDimens::calcFoldOffset(const IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input vector size in TensorDimens::getFoldOffset"); + +int res= 0; +int pow= 1; +int blstart= v.size(); +for(int ibl= getSym().num()-1;ibl>=0;ibl--){ +int bldim= getSym()[ibl]; +if(bldim> 0){ +blstart-= bldim; +int blnvar= getNVX()[blstart]; +IntSequence subv(v,blstart,blstart+bldim); +res+= FTensor::getOffset(subv,blnvar)*pow; +pow*= FFSTensor::calcMaxOffset(blnvar,bldim); +} +} +TL_RAISE_IF(blstart!=0, +"Error in tracing symmetry in TensorDimens::getFoldOffset"); +return res; +} + +/*:5*/ +#line 15 "./gs_tensor.cweb" +; +/*6:*/ +#line 136 "./gs_tensor.cweb" + +void TensorDimens::decrement(IntSequence&v)const +{ +TL_RAISE_IF(getNVX().size()!=v.size(), +"Wrong size of input/output sequence in TensorDimens::decrement"); + +int iblock= getSym().num()-1; +int block_last= v.size(); +int block_first= block_last-getSym()[iblock]; +/*7:*/ +#line 150 "./gs_tensor.cweb" + +while(iblock> 0&&v[block_last-1]==0){ +for(int i= block_first;i=ncols(), +"Internal error in slicing constructor of FGSTensor"); +get((*run).second.first,*ind)= (*run).second.second; +} +} +} + +/*:10*/ +#line 18 "./gs_tensor.cweb" +; +/*12:*/ +#line 235 "./gs_tensor.cweb" + +FGSTensor::FGSTensor(const FFSTensor&t,const IntSequence&ss, +const IntSequence&coor,const TensorDimens&td) +:FTensor(along_col,td.getNVX(),t.nrows(), +td.calcFoldMaxOffset(),td.dimen()), +tdims(td) +{ +if(ncols()==0) +return; + +/*11:*/ +#line 221 "./gs_tensor.cweb" + +IntSequence s_offsets(ss.size(),0); +for(int i= 1;i=ncols(), +"Internal error in slicing constructor of FGSTensor"); +copyColumn(t,*run,*ind); +} +} +} + +/*:12*/ +#line 19 "./gs_tensor.cweb" +; +/*13:*/ +#line 264 "./gs_tensor.cweb" + +FGSTensor::FGSTensor(const GSSparseTensor&t) +:FTensor(along_col,t.getDims().getNVX(),t.nrows(), +t.getDims().calcFoldMaxOffset(),t.dimen()),tdims(t.getDims()) +{ +zeros(); +for(FSSparseTensor::const_iterator it= t.getMap().begin(); +it!=t.getMap().end();++it){ +index ind(this,(*it).first); +get((*it).second.first,*ind)= (*it).second.second; +} +} + +/*:13*/ +#line 20 "./gs_tensor.cweb" +; +/*14:*/ +#line 281 "./gs_tensor.cweb" + +void FGSTensor::increment(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input/output vector size in FGSTensor::increment"); + +UTensor::increment(v,tdims.getNVX()); +v.pmonotone(tdims.getSym()); +} + + + + +/*:14*/ +#line 21 "./gs_tensor.cweb" +; +/*15:*/ +#line 295 "./gs_tensor.cweb" + +UTensor&FGSTensor::unfold()const +{ +return*(new UGSTensor(*this)); +} + + +/*:15*/ +#line 22 "./gs_tensor.cweb" +; +/*16:*/ +#line 321 "./gs_tensor.cweb" + +void FGSTensor::contractAndAdd(int i,FGSTensor&out, +const FRSingleTensor&col)const +{ +TL_RAISE_IF(i<0||i>=getSym().num(), +"Wrong index for FGSTensor::contractAndAdd"); + +TL_RAISE_IF(getSym()[i]!=col.dimen()||tdims.getNVS()[i]!=col.nvar(), +"Wrong dimensions for FGSTensor::contractAndAdd"); + +/*17:*/ +#line 349 "./gs_tensor.cweb" + +Symmetry sym_left(getSym()); +Symmetry sym_right(getSym()); +for(int j= 0;j=i) +sym_left[j]= 0; +} + + +/*:17*/ +#line 331 "./gs_tensor.cweb" +; +int dleft= TensorDimens(sym_left,tdims.getNVS()).calcFoldMaxOffset(); +int dright= TensorDimens(sym_right,tdims.getNVS()).calcFoldMaxOffset(); +KronProdAll kp(3); +kp.setUnit(0,dleft); +kp.setMat(1,col); +kp.setUnit(2,dright); +FGSTensor tmp(out.nrows(),out.getDims()); +kp.mult(*this,tmp); +out.add(1.0,tmp); +} + +/*:16*/ +#line 23 "./gs_tensor.cweb" +; +/*18:*/ +#line 364 "./gs_tensor.cweb" + +UGSTensor::UGSTensor(const FGSTensor&ft) +:UTensor(along_col,ft.tdims.getNVX(),ft.nrows(), +ft.tdims.calcUnfoldMaxOffset(),ft.dimen()), +tdims(ft.tdims) +{ +for(index fi= ft.begin();fi!=ft.end();++fi){ +index ui(this,fi.getCoor()); +copyColumn(ft,*fi,*ui); +} +unfoldData(); +} + +/*:18*/ +#line 24 "./gs_tensor.cweb" +; +/*19:*/ +#line 378 "./gs_tensor.cweb" + +UGSTensor::UGSTensor(const FSSparseTensor&t,const IntSequence&ss, +const IntSequence&coor,const TensorDimens&td) +:UTensor(along_col,td.getNVX(),t.nrows(), +td.calcUnfoldMaxOffset(),td.dimen()), +tdims(td) +{ +if(ncols()==0) +return; + +FGSTensor ft(t,ss,coor,td); +for(index fi= ft.begin();fi!=ft.end();++fi){ +index ui(this,fi.getCoor()); +copyColumn(ft,*fi,*ui); +} +unfoldData(); +} + +/*:19*/ +#line 25 "./gs_tensor.cweb" +; +/*20:*/ +#line 397 "./gs_tensor.cweb" + +UGSTensor::UGSTensor(const UFSTensor&t,const IntSequence&ss, +const IntSequence&coor,const TensorDimens&td) +:UTensor(along_col,td.getNVX(),t.nrows(), +td.calcUnfoldMaxOffset(),td.dimen()), +tdims(td) +{ +FFSTensor folded(t); +FGSTensor ft(folded,ss,coor,td); +for(index fi= ft.begin();fi!=ft.end();++fi){ +index ui(this,fi.getCoor()); +copyColumn(ft,*fi,*ui); +} +unfoldData(); +} + + +/*:20*/ +#line 26 "./gs_tensor.cweb" +; +/*21:*/ +#line 415 "./gs_tensor.cweb" + +void UGSTensor::increment(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input/output vector size in UGSTensor::increment"); + +UTensor::increment(v,tdims.getNVX()); +} + +void UGSTensor::decrement(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input/output vector size in UGSTensor::decrement"); + +UTensor::decrement(v,tdims.getNVX()); +} + + +/*:21*/ +#line 27 "./gs_tensor.cweb" +; +/*22:*/ +#line 434 "./gs_tensor.cweb" + +FTensor&UGSTensor::fold()const +{ +return*(new FGSTensor(*this)); +} + +/*:22*/ +#line 28 "./gs_tensor.cweb" +; +/*23:*/ +#line 441 "./gs_tensor.cweb" + +int UGSTensor::getOffset(const IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input vector size in UGSTensor::getOffset"); + +return UTensor::getOffset(v,tdims.getNVX()); +} + +/*:23*/ +#line 29 "./gs_tensor.cweb" +; +/*24:*/ +#line 453 "./gs_tensor.cweb" + +void UGSTensor::unfoldData() +{ +for(index in= begin();in!=end();++in) +copyColumn(*(getFirstIndexOf(in)),*in); +} + +/*:24*/ +#line 30 "./gs_tensor.cweb" +; +/*25:*/ +#line 464 "./gs_tensor.cweb" + +Tensor::index UGSTensor::getFirstIndexOf(const index&in)const +{ +IntSequence v(in.getCoor()); +int last= 0; +for(int i= 0;i=getSym().num(), +"Wrong index for UGSTensor::contractAndAdd"); +TL_RAISE_IF(getSym()[i]!=col.dimen()||tdims.getNVS()[i]!=col.nvar(), +"Wrong dimensions for UGSTensor::contractAndAdd"); + +/*17:*/ +#line 349 "./gs_tensor.cweb" + +Symmetry sym_left(getSym()); +Symmetry sym_right(getSym()); +for(int j= 0;j=i) +sym_left[j]= 0; +} + + +/*:17*/ +#line 489 "./gs_tensor.cweb" +; +int dleft= TensorDimens(sym_left,tdims.getNVS()).calcUnfoldMaxOffset(); +int dright= TensorDimens(sym_right,tdims.getNVS()).calcUnfoldMaxOffset(); +KronProdAll kp(3); +kp.setUnit(0,dleft); +kp.setMat(1,col); +kp.setUnit(2,dright); +UGSTensor tmp(out.nrows(),out.getDims()); +kp.mult(*this,tmp); +out.add(1.0,tmp); +} + +/*:26*/ +#line 32 "./gs_tensor.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/gs_tensor.h b/mex/sources/korderpert/Dyn_pp/tl/cc/gs_tensor.h new file mode 100644 index 000000000..a11d843a1 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/gs_tensor.h @@ -0,0 +1,169 @@ +/*1:*/ +#line 20 "./gs_tensor.hweb" + +#ifndef GS_TENSOR_H +#define GS_TENSOR_H + +#include "tensor.h" +#include "fs_tensor.h" +#include "symmetry.h" +#include "rfs_tensor.h" + +class FGSTensor; +class UGSTensor; +class FSSparseTensor; + +/*2:*/ +#line 65 "./gs_tensor.hweb" + +class TensorDimens{ +protected: +IntSequence nvs; +Symmetry sym; +IntSequence nvmax; +public: +TensorDimens(const Symmetry&s,const IntSequence&nvars) +:nvs(nvars),sym(s),nvmax(sym,nvs){} +TensorDimens(int nvar,int dimen) +:nvs(1),sym(dimen),nvmax(dimen,nvar) +{nvs[0]= nvar;} +TensorDimens(const TensorDimens&td) +:nvs(td.nvs),sym(td.sym),nvmax(td.nvmax){} +virtual~TensorDimens(){} +TensorDimens(const IntSequence&ss,const IntSequence&coor); +const TensorDimens&operator= (const TensorDimens&td) +{nvs= td.nvs;sym= td.sym;nvmax= td.nvmax;return*this;} +bool operator==(const TensorDimens&td)const +{return nvs==td.nvs&&sym==td.sym;} +bool operator!=(const TensorDimens&td)const +{return!operator==(td);} + +int dimen()const +{return sym.dimen();} +int getNVX(int i)const +{return nvmax[i];} +const IntSequence&getNVS()const +{return nvs;} +const IntSequence&getNVX()const +{return nvmax;} +const Symmetry&getSym()const +{return sym;} + +int calcUnfoldMaxOffset()const; +int calcFoldMaxOffset()const; +int calcFoldOffset(const IntSequence&v)const; +void decrement(IntSequence&v)const; +}; + +/*:2*/ +#line 33 "./gs_tensor.hweb" +; +/*3:*/ +#line 118 "./gs_tensor.hweb" + +class GSSparseTensor; +class FGSTensor:public FTensor{ +friend class UGSTensor; + +const TensorDimens tdims; +public: +/*4:*/ +#line 149 "./gs_tensor.hweb" + +FGSTensor(int r,const TensorDimens&td) +:FTensor(along_col,td.getNVX(),r, +td.calcFoldMaxOffset(),td.dimen()),tdims(td){} +FGSTensor(const FGSTensor&ft) +:FTensor(ft),tdims(ft.tdims){} +FGSTensor(const UGSTensor&ut); +FGSTensor(int first_row,int num,FGSTensor&t) +:FTensor(first_row,num,t),tdims(t.tdims){} +FGSTensor(const FSSparseTensor&t,const IntSequence&ss, +const IntSequence&coor,const TensorDimens&td); +FGSTensor(const FFSTensor&t,const IntSequence&ss, +const IntSequence&coor,const TensorDimens&td); +FGSTensor(const GSSparseTensor&sp); +FGSTensor(FFSTensor&t) +:FTensor(0,t.nrows(),t),tdims(t.nvar(),t.dimen()){} + + +/*:4*/ +#line 125 "./gs_tensor.hweb" +; +virtual~FGSTensor(){} + +void increment(IntSequence&v)const; +void decrement(IntSequence&v)const +{tdims.decrement(v);} +UTensor&unfold()const; +const TensorDimens&getDims()const +{return tdims;} +const Symmetry&getSym()const +{return getDims().getSym();} + +void contractAndAdd(int i,FGSTensor&out, +const FRSingleTensor&col)const; +int getOffset(const IntSequence&v)const +{return tdims.calcFoldOffset(v);} +}; + +/*:3*/ +#line 34 "./gs_tensor.hweb" +; +/*5:*/ +#line 172 "./gs_tensor.hweb" + +class UGSTensor:public UTensor{ +friend class FGSTensor; + +const TensorDimens tdims; +public: +/*6:*/ +#line 205 "./gs_tensor.hweb" + +UGSTensor(int r,const TensorDimens&td) +:UTensor(along_col,td.getNVX(),r, +td.calcUnfoldMaxOffset(),td.dimen()),tdims(td){} +UGSTensor(const UGSTensor&ut) +:UTensor(ut),tdims(ut.tdims){} +UGSTensor(const FGSTensor&ft); +UGSTensor(int first_row,int num,UGSTensor&t) +:UTensor(first_row,num,t),tdims(t.tdims){} +UGSTensor(const FSSparseTensor&t,const IntSequence&ss, +const IntSequence&coor,const TensorDimens&td); +UGSTensor(const UFSTensor&t,const IntSequence&ss, +const IntSequence&coor,const TensorDimens&td); +UGSTensor(UFSTensor&t) +:UTensor(0,t.nrows(),t),tdims(t.nvar(),t.dimen()){} + + +/*:6*/ +#line 178 "./gs_tensor.hweb" +; +virtual~UGSTensor(){} + +void increment(IntSequence&v)const; +void decrement(IntSequence&v)const; +FTensor&fold()const; +const TensorDimens&getDims()const +{return tdims;} +const Symmetry&getSym()const +{return getDims().getSym();} + +void contractAndAdd(int i,UGSTensor&out, +const URSingleTensor&col)const; +int getOffset(const IntSequence&v)const; +private: +void unfoldData(); +public: +index getFirstIndexOf(const index&in)const; +}; + + +/*:5*/ +#line 35 "./gs_tensor.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/int_sequence.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/int_sequence.cpp new file mode 100644 index 000000000..0819ae86c --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/int_sequence.cpp @@ -0,0 +1,388 @@ +/*1:*/ +#line 6 "./int_sequence.cweb" + +#include "int_sequence.h" +#include "symmetry.h" +#include "tl_exception.h" + +#include +#include + +/*2:*/ +#line 42 "./int_sequence.cweb" + +IntSequence::IntSequence(const Symmetry&sy,const IntSequence&se) +:data(new int[sy.dimen()]),length(sy.dimen()),destroy(true) +{ +int k= 0; +for(int i= 0;i &se) +:data(new int[sy.num()]),length(sy.num()),destroy(true) +{ +TL_RAISE_IF(sy.dimen()<=se[se.size()-1], +"Sequence is not reachable by symmetry in IntSequence()"); +for(int i= 0;i s.size(), +"Wrong position for insertion IntSequence constructor"); +for(int jj= 0;jj data[j+1]){ +int s= data[j+1]; +data[j+1]= data[j]; +data[j]= s; +swaps++; +} +} +if(swaps==0) +return; +} +} + +/*:11*/ +#line 23 "./int_sequence.cweb" +; +/*12:*/ +#line 200 "./int_sequence.cweb" + +void IntSequence::monotone() +{ +for(int i= 1;i data[i]) +data[i]= data[i-1]; +} + +/*:12*/ +#line 24 "./int_sequence.cweb" +; +/*13:*/ +#line 213 "./int_sequence.cweb" + +void IntSequence::pmonotone(const Symmetry&s) +{ +int cum= 0; +for(int i= 0;i data[j]) +data[j]= data[j-1]; +cum+= s[i]; +} +} + +/*:13*/ +#line 25 "./int_sequence.cweb" +; +/*14:*/ +#line 226 "./int_sequence.cweb" + +int IntSequence::sum()const +{ +int res= 0; +for(int i= 0;i 0) +res++; +for(int i= 1;i res) +res= operator[](i); +return res; +} + +/*:18*/ +#line 30 "./int_sequence.cweb" +; +/*19:*/ +#line 286 "./int_sequence.cweb" + +void IntSequence::add(int i) +{ +for(int j= 0;j=0) +i++; +return(i==size()); +} + +/*:21*/ +#line 33 "./int_sequence.cweb" +; +/*22:*/ +#line 314 "./int_sequence.cweb" + +bool IntSequence::isConstant()const +{ +bool res= true; +int i= 1; +while(res&&i +#include + +using namespace std; + +/*2:*/ +#line 46 "./int_sequence.hweb" + +class Symmetry; +class IntSequence{ +int*data; +int length; +bool destroy; +public: +/*3:*/ +#line 83 "./int_sequence.hweb" + +IntSequence(int l) +:data(new int[l]),length(l),destroy(true){} +IntSequence(int l,int n) +:data(new int[l]),length(l),destroy(true) +{for(int i= 0;i &se); +IntSequence(const Symmetry&sy,const IntSequence&se); +IntSequence(int i,const IntSequence&s); +IntSequence(int i,const IntSequence&s,int pos); +IntSequence(int l,const int*d) +:data(new int[l]),length(l),destroy(true) +{memcpy(data,d,sizeof(int)*length);} + + +/*:3*/ +#line 53 "./int_sequence.hweb" +; +/*4:*/ +#line 107 "./int_sequence.hweb" + +const IntSequence&operator= (const IntSequence&s); +virtual~IntSequence() +{if(destroy)delete[]data;} +bool operator==(const IntSequence&s)const; +bool operator!=(const IntSequence&s)const +{return!operator==(s);} +int&operator[](int i) +{return data[i];} +int operator[](int i)const +{return data[i];} +int size()const +{return length;} + +/*:4*/ +#line 54 "./int_sequence.hweb" +; +/*5:*/ +#line 124 "./int_sequence.hweb" + +bool operator<(const IntSequence&s)const; +bool operator<=(const IntSequence&s)const +{return(operator==(s)||operator<(s));} +bool lessEq(const IntSequence&s)const; +bool less(const IntSequence&s)const; + + +/*:5*/ +#line 55 "./int_sequence.hweb" +; +void sort(); +void monotone(); +void pmonotone(const Symmetry&s); +int sum()const; +int mult(int i1,int i2)const; +int mult()const +{return mult(0,length);} +void add(int i); +void add(int f,const IntSequence&s); +int getPrefixLength()const; +int getNumDistinct()const; +int getMax()const; +bool isPositive()const; +bool isConstant()const; +bool isSorted()const; +void print()const; +}; + +/*:2*/ +#line 38 "./int_sequence.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/kron_prod.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/kron_prod.cpp new file mode 100644 index 000000000..1639389a0 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/kron_prod.cpp @@ -0,0 +1,430 @@ +/*1:*/ +#line 5 "./kron_prod.cweb" + +#include "kron_prod.h" +#include "tl_exception.h" + +#include + +/*2:*/ +#line 39 "./kron_prod.cweb" + +KronProdDimens::KronProdDimens(const KronProdDimens&kd,int i) +:rows((i==0||i==kd.dimen()-1)?(2):(3)), +cols((i==0||i==kd.dimen()-1)?(2):(3)) +{ +TL_RAISE_IF(i<0||i>=kd.dimen(), +"Wrong index for pickup in KronProdDimens constructor"); + +int kdim= kd.dimen(); +if(i==0){ +/*3:*/ +#line 61 "./kron_prod.cweb" + +rows[0]= kd.rows[0]; +rows[1]= kd.rows.mult(1,kdim); +cols[0]= kd.cols[0]; +cols[1]= rows[1]; + +/*:3*/ +#line 49 "./kron_prod.cweb" +; +}else if(i==kdim-1){ +/*4:*/ +#line 71 "./kron_prod.cweb" + +rows[0]= kd.cols.mult(0,kdim-1); +rows[1]= kd.rows[kdim-1]; +cols[0]= rows[0]; +cols[1]= kd.cols[kdim-1]; + +/*:4*/ +#line 51 "./kron_prod.cweb" +; +}else{ +/*5:*/ +#line 83 "./kron_prod.cweb" + +rows[0]= kd.cols.mult(0,i); +cols[0]= rows[0]; +rows[1]= kd.rows[i]; +cols[1]= kd.cols[i]; +cols[2]= kd.rows.mult(i+1,kdim); +rows[2]= cols[2]; + + +/*:5*/ +#line 53 "./kron_prod.cweb" +; +} +} + +/*:2*/ +#line 11 "./kron_prod.cweb" +; +/*6:*/ +#line 95 "./kron_prod.cweb" + +void KronProd::checkDimForMult(const ConstTwoDMatrix&in,const TwoDMatrix&out)const +{ +int my_rows; +int my_cols; +kpd.getRC(my_rows,my_cols); +TL_RAISE_IF(in.nrows()!=out.nrows()||in.ncols()!=my_rows, +"Wrong dimensions for KronProd in KronProd::checkDimForMult"); +} + +/*:6*/ +#line 12 "./kron_prod.cweb" +; +/*7:*/ +#line 108 "./kron_prod.cweb" + +void KronProd::kronMult(const ConstVector&v1,const ConstVector&v2, +Vector&res) +{ +TL_RAISE_IF(res.length()!=v1.length()*v2.length(), +"Wrong vector lengths in KronProd::kronMult"); +res.zeros(); +for(int i= 0;i to_delete; +for(int i= 0;izeros(); +(*aux)[irows[j]]= 1.0; +to_delete.push_back(aux); +row= new ConstVector(*aux); +} + +/*:23*/ +#line 370 "./kron_prod.cweb" +; +/*24:*/ +#line 402 "./kron_prod.cweb" + +if(last){ +Vector*newlast; +newlast= new Vector(last->length()*row->length()); +kronMult(*row,ConstVector(*last),*newlast); +delete last; +last= newlast; +}else{ +last= new Vector(*row); +} + + +/*:24*/ +#line 371 "./kron_prod.cweb" +; +delete row; +} + +for(unsigned int i= 0;iisZero(); +if(is_zero||in.isZero()){ +out.zeros(); +return; +} + +/*:17*/ +#line 277 "./kron_prod.cweb" +; +/*18:*/ +#line 307 "./kron_prod.cweb" + +if(dimen()==1){ +if(matlist[0]) +out.mult(in,ConstTwoDMatrix(*(matlist[0]))); +return; +} + +/*:18*/ +#line 278 "./kron_prod.cweb" +; +int c; +TwoDMatrix*last= NULL; +/*19:*/ +#line 317 "./kron_prod.cweb" + +if(matlist[0]){ +KronProdAI akronid(*this); +c= akronid.kpd.ncols(); +last= new TwoDMatrix(in.nrows(),c); +akronid.mult(in,*last); +}else{ +last= new TwoDMatrix(in.nrows(),in.ncols(),in.getData().base()); +} + +/*:19*/ +#line 281 "./kron_prod.cweb" +; +/*20:*/ +#line 331 "./kron_prod.cweb" + +for(int i= 1;i (1) +{ +if(maxdim>=2) +generateMoments(maxdim,v); +} + + +/*:2*/ +#line 12 "./normal_moments.cweb" +; +/*3:*/ +#line 35 "./normal_moments.cweb" + +void UNormalMoments::generateMoments(int maxdim,const TwoDMatrix&v) +{ +TL_RAISE_IF(v.nrows()!=v.ncols(), +"Variance-covariance matrix is not square in UNormalMoments constructor"); + +int nv= v.nrows(); +URSingleTensor*mom2= new URSingleTensor(nv,2); +mom2->getData()= v.getData(); +insert(mom2); +URSingleTensor*kronv= new URSingleTensor(nv,2); +kronv->getData()= v.getData(); +for(int d= 4;d<=maxdim;d+= 2){ +URSingleTensor*newkronv= new URSingleTensor(nv,d); +KronProd::kronMult(ConstVector(v.getData()), +ConstVector(kronv->getData()), +newkronv->getData()); +delete kronv; +kronv= newkronv; +URSingleTensor*mom= new URSingleTensor(nv,d); +/*4:*/ +#line 70 "./normal_moments.cweb" + +mom->zeros(); +const EquivalenceSet eset= ebundle.get(d); +for(EquivalenceSet::const_iterator cit= eset.begin(); +cit!=eset.end();cit++){ +if(selectEquiv(*cit)){ +Permutation per(*cit); +per.inverse(); +for(Tensor::index it= kronv->begin();it!=kronv->end();++it){ +IntSequence ind(kronv->dimen()); +per.apply(it.getCoor(),ind); +Tensor::index it2(mom,ind); +mom->get(*it2,0)+= kronv->get(*it,0); +} +} +} + +/*:4*/ +#line 55 "./normal_moments.cweb" +; +insert(mom); +} +delete kronv; +} + +/*:3*/ +#line 13 "./normal_moments.cweb" +; +/*5:*/ +#line 88 "./normal_moments.cweb" + +bool UNormalMoments::selectEquiv(const Equivalence&e) +{ +if(2*e.numClasses()!=e.getN()) +return false; +for(Equivalence::const_seqit si= e.begin(); +si!=e.end();++si){ +if((*si).length()!=2) +return false; +} +return true; +} + +/*:5*/ +#line 14 "./normal_moments.cweb" +; +/*6:*/ +#line 103 "./normal_moments.cweb" + +FNormalMoments::FNormalMoments(const UNormalMoments&moms) +:TensorContainer (1) +{ +for(UNormalMoments::const_iterator it= moms.begin(); +it!=moms.end();++it){ +FRSingleTensor*fm= new FRSingleTensor(*((*it).second)); +insert(fm); +} +} + + +/*:6*/ +#line 15 "./normal_moments.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/normal_moments.h b/mex/sources/korderpert/Dyn_pp/tl/cc/normal_moments.h new file mode 100644 index 000000000..1f7250f6c --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/normal_moments.h @@ -0,0 +1,38 @@ +/*1:*/ +#line 110 "./normal_moments.hweb" + +#ifndef NORMAL_MOMENTS_H +#define NORMAL_MOMENTS_H + +#include "t_container.h" + +/*2:*/ +#line 122 "./normal_moments.hweb" + +class UNormalMoments:public TensorContainer { +public: +UNormalMoments(int maxdim,const TwoDMatrix&v); +private: +void generateMoments(int maxdim,const TwoDMatrix&v); +static bool selectEquiv(const Equivalence&e); +}; + +/*:2*/ +#line 116 "./normal_moments.hweb" +; +/*3:*/ +#line 132 "./normal_moments.hweb" + +class FNormalMoments:public TensorContainer { +public: +FNormalMoments(const UNormalMoments&moms); +}; + + +/*:3*/ +#line 117 "./normal_moments.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/permutation.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/permutation.cpp new file mode 100644 index 000000000..76be2912d --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/permutation.cpp @@ -0,0 +1,212 @@ +/*1:*/ +#line 5 "./permutation.cweb" + + +#include "permutation.h" +#include "tl_exception.h" + +/*2:*/ +#line 25 "./permutation.cweb" + +void Permutation::apply(const IntSequence&src,IntSequence&tar)const +{ +TL_RAISE_IF(src.size()!=permap.size()||tar.size()!=permap.size(), +"Wrong sizes of input or output in Permutation::apply"); +for(int i= 0;i 0&&permap[i-1]==i-1) +i--; +return permap.size()-i; +} + +/*:4*/ +#line 12 "./permutation.cweb" +; +/*5:*/ +#line 72 "./permutation.cweb" + +void Permutation::computeSortingMap(const IntSequence&s) +{ +IntSequence srt(s); +srt.sort(); +IntSequence flags(s.size(),0); + +for(int i= 0;i PermutationSet::getPreserving(const IntSequence&s)const +{ +TL_RAISE_IF(s.size()!=order, +"Wrong sequence length in PermutationSet::getPreserving"); + +vector res; +IntSequence tmp(s.size()); +for(int i= 0;iapply(s,tmp); +if(s==tmp){ +res.push_back(pers[i]); +} +} + +return res; +} + +/*:9*/ +#line 17 "./permutation.cweb" +; +/*10:*/ +#line 148 "./permutation.cweb" + +PermutationBundle::PermutationBundle(int nmax) +{ +nmax= max(nmax,1); +generateUpTo(nmax); +} + +/*:10*/ +#line 18 "./permutation.cweb" +; +/*11:*/ +#line 156 "./permutation.cweb" + +PermutationBundle::~PermutationBundle() +{ +for(unsigned int i= 0;i (int)(bundle.size())||n<1){ +TL_RAISE("Permutation set not found in PermutationSet::get"); +return*(bundle[0]); +}else{ +return*(bundle[n-1]); +} +} + +/*:12*/ +#line 20 "./permutation.cweb" +; +/*13:*/ +#line 176 "./permutation.cweb" + +void PermutationBundle::generateUpTo(int nmax) +{ +if(bundle.size()==0) +bundle.push_back(new PermutationSet()); + +int curmax= bundle.size(); +for(int n= curmax+1;n<=nmax;n++){ +bundle.push_back(new PermutationSet(*(bundle.back()),n)); +} +} + +/*:13*/ +#line 21 "./permutation.cweb" +; + + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/permutation.h b/mex/sources/korderpert/Dyn_pp/tl/cc/permutation.h new file mode 100644 index 000000000..6db7a2f8b --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/permutation.h @@ -0,0 +1,97 @@ +/*1:*/ +#line 38 "./permutation.hweb" + +#ifndef PERMUTATION_H +#define PERMUTATION_H + +#include "int_sequence.h" +#include "equivalence.h" + +#include + +/*2:*/ +#line 65 "./permutation.hweb" + +class Permutation{ +protected: +IntSequence permap; +public: +Permutation(int len) +:permap(len){for(int i= 0;i getPreserving(const IntSequence&s)const; +}; + + +/*:3*/ +#line 48 "./permutation.hweb" +; +/*4:*/ +#line 137 "./permutation.hweb" + +class PermutationBundle{ +vector bundle; +public: +PermutationBundle(int nmax); +~PermutationBundle(); +const PermutationSet&get(int n)const; +void generateUpTo(int nmax); +}; + +/*:4*/ +#line 49 "./permutation.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/ps_tensor.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/ps_tensor.cpp new file mode 100644 index 000000000..ab295dbc1 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/ps_tensor.cpp @@ -0,0 +1,392 @@ +/*1:*/ +#line 5 "./ps_tensor.cweb" + +#include "ps_tensor.h" +#include "fs_tensor.h" +#include "tl_exception.h" +#include "tl_static.h" +#include "stack_container.h" + +/*2:*/ +#line 38 "./ps_tensor.cweb" + +UPSTensor::fill_method UPSTensor::decideFillMethod(const FSSparseTensor&t) +{ +if(t.getFillFactor()> 0.08) +return first; +else +return second; +} + +/*:2*/ +#line 12 "./ps_tensor.cweb" +; +/*3:*/ +#line 49 "./ps_tensor.cweb" + +UPSTensor::UPSTensor(const FSSparseTensor&t,const IntSequence&ss, +const IntSequence&coor,const PerTensorDimens&ptd) +:UTensor(along_col,ptd.getNVX(), +t.nrows(),ptd.calcUnfoldMaxOffset(),ptd.dimen()), +tdims(ptd) +{ +TL_RAISE_IF(coor.size()!=t.dimen(), +"Wrong coordinates length of stacks for UPSTensor slicing constructor"); +TL_RAISE_IF(ss.sum()!=t.nvar(), +"Wrong length of stacks for UPSTensor slicing constructor"); + +if(first==decideFillMethod(t)) +fillFromSparseOne(t,ss,coor); +else +fillFromSparseTwo(t,ss,coor); +} + + +/*:3*/ +#line 13 "./ps_tensor.cweb" +; +/*4:*/ +#line 69 "./ps_tensor.cweb" + +void UPSTensor::increment(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input/output vector size in UPSTensor::increment"); + +UTensor::increment(v,tdims.getNVX()); +} + +void UPSTensor::decrement(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input/output vector size in UPSTensor::decrement"); + +UTensor::decrement(v,tdims.getNVX()); +} + +/*:4*/ +#line 14 "./ps_tensor.cweb" +; +/*5:*/ +#line 87 "./ps_tensor.cweb" + +FTensor&UPSTensor::fold()const +{ +TL_RAISE("Never should come to this place in UPSTensor::fold"); +FFSTensor*nothing= new FFSTensor(0,0,0); +return*nothing; +} + + +/*:5*/ +#line 15 "./ps_tensor.cweb" +; +/*6:*/ +#line 97 "./ps_tensor.cweb" + +int UPSTensor::getOffset(const IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input vector size in UPSTensor::getOffset"); + +return UTensor::getOffset(v,tdims.getNVX()); +} + +/*:6*/ +#line 16 "./ps_tensor.cweb" +; +/*7:*/ +#line 107 "./ps_tensor.cweb" + +void UPSTensor::addTo(FGSTensor&out)const +{ +TL_RAISE_IF(out.getDims()!=tdims, +"Tensors have incompatible dimens in UPSTensor::addTo"); +for(index in= out.begin();in!=out.end();++in){ +IntSequence vtmp(dimen()); +tdims.getPer().apply(in.getCoor(),vtmp); +index tin(this,vtmp); +out.addColumn(*this,*tin,*in); +} +} + +/*:7*/ +#line 17 "./ps_tensor.cweb" +; +/*8:*/ +#line 143 "./ps_tensor.cweb" + +void UPSTensor::addTo(UGSTensor&out)const +{ +TL_RAISE_IF(out.getDims()!=tdims, +"Tensors have incompatible dimens in UPSTensor::addTo"); +int cols= tailIdentitySize(); +int off= tdims.tailIdentity(); +IntSequence outrun(out.dimen(),0); +IntSequence outrun_part(outrun,0,out.dimen()-off); +IntSequence nvmax_part(out.getDims().getNVX(),0,out.dimen()-off); +for(int out_col= 0;out_colget(coor.size()); +vector pp= pset.getPreserving(coor); + +Permutation unsort(coor); +zeros(); +FSSparseTensor::const_iterator lbi= t.getMap().lower_bound(lb_srt); +FSSparseTensor::const_iterator ubi= t.getMap().upper_bound(ub_srt); +for(FSSparseTensor::const_iterator run= lbi;run!=ubi;++run){ +if(lb_srt.lessEq((*run).first)&&(*run).first.lessEq(ub_srt)){ +IntSequence c((*run).first); +c.add(-1,lb_srt); +unsort.apply(c); +for(unsigned int i= 0;iapply(c,cp); +Tensor::index ind(this,cp); +TL_RAISE_IF(*ind<0||*ind>=ncols(), +"Internal error in slicing constructor of UPSTensor"); +get((*run).second.first,*ind)= (*run).second.second; +} +} +} +} + + +/*:11*/ +#line 21 "./ps_tensor.cweb" +; +/*12:*/ +#line 270 "./ps_tensor.cweb" + +void PerTensorDimens2::setDimensionSizes() +{ +const IntSequence&nvs= getNVS(); +for(int i= 0;i class StackProduct; + +class FPSTensor:public FTensor{ +const PerTensorDimens2 tdims; +public: +/*8:*/ +#line 323 "./ps_tensor.hweb" + +FPSTensor(const TensorDimens&td,const Equivalence&e, +const ConstTwoDMatrix&a,const KronProdAll&kp) +:FTensor(along_col,PerTensorDimens(td,e).getNVX(), +a.nrows(),kp.ncols(),td.dimen()),tdims(td,e) +{kp.mult(a,*this);} +FPSTensor(const TensorDimens&td,const Equivalence&e, +const ConstTwoDMatrix&a,const KronProdAllOptim&kp) +:FTensor(along_col,PerTensorDimens(td,Permutation(e,kp.getPer())).getNVX(), +a.nrows(),kp.ncols(),td.dimen()),tdims(td,e,kp.getPer()) +{kp.mult(a,*this);} +FPSTensor(const TensorDimens&td,const Equivalence&e,const Permutation&p, +const ConstTwoDMatrix&a,const KronProdAll&kp) +:FTensor(along_col,PerTensorDimens(td,Permutation(e,p)).getNVX(), +a.nrows(),kp.ncols(),td.dimen()),tdims(td,e,p) +{kp.mult(a,*this);} +FPSTensor(const TensorDimens&td,const Equivalence&e,const Permutation&p, +const ConstTwoDMatrix&a,const KronProdAllOptim&kp) +:FTensor(along_col,PerTensorDimens(td,Permutation(e,Permutation(p,kp.getPer()))).getNVX(), +a.nrows(),kp.ncols(),td.dimen()),tdims(td,e,Permutation(p,kp.getPer())) +{kp.mult(a,*this);} + +FPSTensor(const TensorDimens&td,const Equivalence&e,const Permutation&p, +const GSSparseTensor&t,const KronProdAll&kp); + +FPSTensor(const FPSTensor&ft) +:FTensor(ft),tdims(ft.tdims){} + +/*:8*/ +#line 304 "./ps_tensor.hweb" +; + +void increment(IntSequence&v)const; +void decrement(IntSequence&v)const; +UTensor&unfold()const; + +int getOffset(const IntSequence&v)const; +void addTo(FGSTensor&out)const; +}; + +/*:7*/ +#line 67 "./ps_tensor.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod.cpp new file mode 100644 index 000000000..953f8bd71 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod.cpp @@ -0,0 +1,66 @@ +/*1:*/ +#line 5 "./pyramid_prod.cweb" + + +#include "pyramid_prod.h" +#include "permutation.h" +#include "tl_exception.h" + +/*2:*/ +#line 27 "./pyramid_prod.cweb" + +USubTensor::USubTensor(const TensorDimens&bdims, +const TensorDimens&hdims, +const FGSContainer&cont, +const vector &lst) +:URTensor(lst.size(),hdims.getNVX()[0],hdims.dimen()) +{ +TL_RAISE_IF(!hdims.getNVX().isConstant(), +"Tensor has not full symmetry in USubTensor()"); +const EquivalenceSet&eset= cont.getEqBundle().get(bdims.dimen()); +zeros(); +for(EquivalenceSet::const_iterator it= eset.begin(); +it!=eset.end();++it){ +if((*it).numClasses()==hdims.dimen()){ +Permutation per(*it); +vector ts= +cont.fetchTensors(bdims.getSym(),*it); +for(int i= 0;i<(int)lst.size();i++){ +IntSequence perindex(lst[i].size()); +per.apply(lst[i],perindex); +addKronColumn(i,ts,perindex); +} +} +} +} + +/*:2*/ +#line 11 "./pyramid_prod.cweb" +; +/*3:*/ +#line 67 "./pyramid_prod.cweb" + +void USubTensor::addKronColumn(int i,const vector &ts, +const IntSequence&pindex) +{ +vector tmpcols; +int lastdim= 0; +for(unsigned int j= 0;jdimen()); +lastdim+= ts[j]->dimen(); +index in(ts[j],ind); +tmpcols.push_back(ConstVector(*(ts[j]),*in)); +} + +URSingleTensor kronmult(tmpcols); +Vector coli(*this,i); +coli.add(1.0,kronmult.getData()); +} + + +/*:3*/ +#line 12 "./pyramid_prod.cweb" +; + + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod.h b/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod.h new file mode 100644 index 000000000..0e553d555 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod.h @@ -0,0 +1,33 @@ +/*1:*/ +#line 48 "./pyramid_prod.hweb" + +#ifndef PYRAMID_PROD_H +#define PYRAMID_PROD_H + +#include "int_sequence.h" +#include "rfs_tensor.h" +#include "gs_tensor.h" +#include "t_container.h" + +#include + +using namespace std; + +/*2:*/ +#line 71 "./pyramid_prod.hweb" + +class USubTensor:public URTensor{ +public: +USubTensor(const TensorDimens&bdims,const TensorDimens&hdims, +const FGSContainer&cont,const vector &lst); +void addKronColumn(int i,const vector &ts, +const IntSequence&pindex); +}; + +/*:2*/ +#line 61 "./pyramid_prod.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod2.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod2.cpp new file mode 100644 index 000000000..e6832262f --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod2.cpp @@ -0,0 +1,146 @@ +/*1:*/ +#line 6 "./pyramid_prod2.cweb" + +#include "pyramid_prod2.h" +#include "rfs_tensor.h" + +/*2:*/ +#line 21 "./pyramid_prod2.cweb" + +IrregTensorHeader::IrregTensorHeader(const StackProduct &sp, +const IntSequence&c) +:nv(sp.getAllSize()), +unit_flag(sp.dimen()), +cols(new Vector*[sp.dimen()]), +end_seq(sp.dimen()) +{ +sp.createPackedColumns(c,cols,unit_flag); +for(int i= 0;ilength(); +if(unit_flag[i]!=-1) +end_seq[i]= unit_flag[i]+1; +} +} + + +/*:2*/ +#line 10 "./pyramid_prod2.cweb" +; +/*3:*/ +#line 42 "./pyramid_prod2.cweb" + +void IrregTensorHeader::increment(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong size of coordinates in IrregTensorHeader::increment"); + +if(v.size()==0) +return; +int i= v.size()-1; +/*4:*/ +#line 63 "./pyramid_prod2.cweb" + +v[i]++; +if(unit_flag[i]!=-1&&v[i]==cols[i]->length()-1) +v[i]= unit_flag[i]; + + +/*:4*/ +#line 51 "./pyramid_prod2.cweb" +; +while(i> 0&&v[i]==end_seq[i]){ +v[i]= 0; +i--; +/*4:*/ +#line 63 "./pyramid_prod2.cweb" + +v[i]++; +if(unit_flag[i]!=-1&&v[i]==cols[i]->length()-1) +v[i]= unit_flag[i]; + + +/*:4*/ +#line 55 "./pyramid_prod2.cweb" +; +} +} + +/*:3*/ +#line 11 "./pyramid_prod2.cweb" +; +/*5:*/ +#line 70 "./pyramid_prod2.cweb" + +IrregTensorHeader::~IrregTensorHeader() +{ +for(int i= 0;ilength(); +return res; +} + + +/*:6*/ +#line 13 "./pyramid_prod2.cweb" +; +/*7:*/ +#line 92 "./pyramid_prod2.cweb" + +IrregTensor::IrregTensor(const IrregTensorHeader&h) +:Tensor(along_row,IntSequence(h.dimen(),0),h.end_seq, +h.calcMaxOffset(),1,h.dimen()), +header(h) +{ +if(header.dimen()==1){ +getData()= *(header.cols[0]); +return; +} + +Vector*last= new Vector(*(header.cols[header.dimen()-1])); +for(int i= header.dimen()-2;i> 0;i--){ +Vector*newlast= new Vector(last->length()*header.cols[i]->length()); +KronProd::kronMult(ConstVector(*(header.cols[i])), +ConstVector(*last),*newlast); +delete last; +last= newlast; +} +KronProd::kronMult(ConstVector(*(header.cols[0])), +ConstVector(*last),getData()); +delete last; +} + +/*:7*/ +#line 14 "./pyramid_prod2.cweb" +; +/*8:*/ +#line 117 "./pyramid_prod2.cweb" + +void IrregTensor::addTo(FRSingleTensor&out)const +{ +for(index it= begin();it!=end();++it){ +IntSequence tmp(it.getCoor()); +tmp.sort(); +Tensor::index ind(&out,tmp); +out.get(*ind,0)+= get(*it,0); +} +} + + +/*:8*/ +#line 15 "./pyramid_prod2.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod2.h b/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod2.h new file mode 100644 index 000000000..f3ef03612 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/pyramid_prod2.h @@ -0,0 +1,62 @@ +/*1:*/ +#line 69 "./pyramid_prod2.hweb" + +#ifndef PYRAMID_PROD2_H +#define PYRAMID_PROD2_H + +#include "permutation.h" +#include "tensor.h" +#include "tl_exception.h" +#include "rfs_tensor.h" +#include "stack_container.h" + +#include "Vector.h" + +/*2:*/ +#line 101 "./pyramid_prod2.hweb" + +class IrregTensor; +class IrregTensorHeader{ +friend class IrregTensor; +int nv; +IntSequence unit_flag; +Vector**const cols; +IntSequence end_seq; +public: +IrregTensorHeader(const StackProduct &sp,const IntSequence&c); +~IrregTensorHeader(); +int dimen()const +{return unit_flag.size();} +void increment(IntSequence&v)const; +int calcMaxOffset()const; +private: +IrregTensorHeader(const IrregTensorHeader&); +}; + + +/*:2*/ +#line 81 "./pyramid_prod2.hweb" +; +/*3:*/ +#line 137 "./pyramid_prod2.hweb" + +class IrregTensor:public Tensor{ +const IrregTensorHeader&header; +public: +IrregTensor(const IrregTensorHeader&h); +void addTo(FRSingleTensor&out)const; +void increment(IntSequence&v)const +{header.increment(v);} +void decrement(IntSequence&v)const +{TL_RAISE("Not implemented error in IrregTensor::decrement");} +int getOffset(const IntSequence&v)const +{TL_RAISE("Not implemented error in IrregTensor::getOffset");return 0;} +}; + +/*:3*/ +#line 82 "./pyramid_prod2.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/rfs_tensor.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/rfs_tensor.cpp new file mode 100644 index 000000000..d0e8297ec --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/rfs_tensor.cpp @@ -0,0 +1,219 @@ +/*1:*/ +#line 6 "./rfs_tensor.cweb" + +#include "rfs_tensor.h" +#include "kron_prod.h" +#include "tl_exception.h" + +/*2:*/ +#line 29 "./rfs_tensor.cweb" + +FRTensor::FRTensor(const URTensor&ut) +:FTensor(along_row,IntSequence(ut.dimen(),ut.nvar()), +FFSTensor::calcMaxOffset(ut.nvar(),ut.dimen()),ut.ncols(), +ut.dimen()), +nv(ut.nvar()) +{ +zeros(); +for(index in= ut.begin();in!=ut.end();++in){ +IntSequence vtmp(in.getCoor()); +vtmp.sort(); +index tar(this,vtmp); +addRow(ut,*in,*tar); +} +} + +/*:2*/ +#line 11 "./rfs_tensor.cweb" +; +/*3:*/ +#line 46 "./rfs_tensor.cweb" + +UTensor&FRTensor::unfold()const +{ +return*(new URTensor(*this)); +} + +/*:3*/ +#line 12 "./rfs_tensor.cweb" +; +/*4:*/ +#line 54 "./rfs_tensor.cweb" + +void FRTensor::increment(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input/output vector size in FRTensor::increment"); + +UTensor::increment(v,nv); +v.monotone(); +} + +/*:4*/ +#line 13 "./rfs_tensor.cweb" +; +/*5:*/ +#line 66 "./rfs_tensor.cweb" + +void FRTensor::decrement(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input/output vector size in FRTensor::decrement"); + +FTensor::decrement(v,nv); +} + + +/*:5*/ +#line 14 "./rfs_tensor.cweb" +; +/*6:*/ +#line 81 "./rfs_tensor.cweb" + +URTensor::URTensor(const FRTensor&ft) +:UTensor(along_row,IntSequence(ft.dimen(),ft.nvar()), +UFSTensor::calcMaxOffset(ft.nvar(),ft.dimen()),ft.ncols(), +ft.dimen()), +nv(ft.nvar()) +{ +zeros(); +for(index src= ft.begin();src!=ft.end();++src){ +index in(this,src.getCoor()); +copyRow(ft,*src,*in); +} +} + +/*:6*/ +#line 15 "./rfs_tensor.cweb" +; +/*7:*/ +#line 96 "./rfs_tensor.cweb" + +FTensor&URTensor::fold()const +{ +return*(new FRTensor(*this)); +} + +/*:7*/ +#line 16 "./rfs_tensor.cweb" +; +/*8:*/ +#line 103 "./rfs_tensor.cweb" + +void URTensor::increment(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input/output vector size in URTensor::increment"); + +UTensor::increment(v,nv); +} + +void URTensor::decrement(IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input/output vector size in URTensor::decrement"); + +UTensor::decrement(v,nv); +} + +/*:8*/ +#line 17 "./rfs_tensor.cweb" +; +/*9:*/ +#line 121 "./rfs_tensor.cweb" + +int URTensor::getOffset(const IntSequence&v)const +{ +TL_RAISE_IF(v.size()!=dimen(), +"Wrong input vector size in URTensor::getOffset"); + +return UTensor::getOffset(v,nv); +} + +/*:9*/ +#line 18 "./rfs_tensor.cweb" +; +/*10:*/ +#line 133 "./rfs_tensor.cweb" + +URSingleTensor::URSingleTensor(const vector &cols) +:URTensor(1,cols[0].length(),cols.size()) +{ +if(dimen()==1){ +getData()= cols[0]; +return; +} + +Vector*last= new Vector(cols[cols.size()-1]); +for(int i= cols.size()-2;i> 0;i--){ +Vector*newlast= new Vector(Tensor::power(nvar(),cols.size()-i)); +KronProd::kronMult(cols[i],ConstVector(*last),*newlast); +delete last; +last= newlast; +} +KronProd::kronMult(cols[0],ConstVector(*last),getData()); +delete last; +} + +/*:10*/ +#line 19 "./rfs_tensor.cweb" +; +/*11:*/ +#line 156 "./rfs_tensor.cweb" + +URSingleTensor::URSingleTensor(const ConstVector&v,int d) +:URTensor(1,v.length(),d) +{ +if(d==1){ +getData()= v; +return; +} + +Vector*last= new Vector(v); +for(int i= d-2;i> 0;i--){ +Vector*newlast= new Vector(last->length()*v.length()); +KronProd::kronMult(v,ConstVector(*last),*newlast); +delete last; +last= newlast; +} +KronProd::kronMult(v,ConstVector(*last),getData()); +delete last; +} + +/*:11*/ +#line 20 "./rfs_tensor.cweb" +; +/*12:*/ +#line 179 "./rfs_tensor.cweb" + +FTensor&URSingleTensor::fold()const +{ +return*(new FRSingleTensor(*this)); +} + + + +/*:12*/ +#line 21 "./rfs_tensor.cweb" +; +/*13:*/ +#line 191 "./rfs_tensor.cweb" + +FRSingleTensor::FRSingleTensor(const URSingleTensor&ut) +:FRTensor(1,ut.nvar(),ut.dimen()) +{ +zeros(); +for(index in= ut.begin();in!=ut.end();++in){ +IntSequence vtmp(in.getCoor()); +vtmp.sort(); +index tar(this,vtmp); +get(*tar,0)+= ut.get(*in,0); +} +} + + +/*:13*/ +#line 22 "./rfs_tensor.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/rfs_tensor.h b/mex/sources/korderpert/Dyn_pp/tl/cc/rfs_tensor.h new file mode 100644 index 000000000..e46271e0b --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/rfs_tensor.h @@ -0,0 +1,121 @@ +/*1:*/ +#line 37 "./rfs_tensor.hweb" + +#ifndef RFS_TENSOR_H +#define RFS_TENSOR_H + +#include "tensor.h" +#include "fs_tensor.h" +#include "symmetry.h" + +/*2:*/ +#line 53 "./rfs_tensor.hweb" + +class FRTensor; +class URTensor:public UTensor{ +int nv; +public: +/*3:*/ +#line 73 "./rfs_tensor.hweb" + +URTensor(int c,int nvar,int d) +:UTensor(along_row,IntSequence(d,nvar), +UFSTensor::calcMaxOffset(nvar,d),c,d),nv(nvar){} +URTensor(const URTensor&ut) +:UTensor(ut),nv(ut.nv){} +URTensor(const FRTensor&ft); + +/*:3*/ +#line 58 "./rfs_tensor.hweb" +; +virtual~URTensor(){} + +void increment(IntSequence&v)const; +void decrement(IntSequence&v)const; +FTensor&fold()const; + +int getOffset(const IntSequence&v)const; +int nvar()const +{return nv;} +Symmetry getSym()const +{return Symmetry(dimen());} +}; + +/*:2*/ +#line 45 "./rfs_tensor.hweb" +; +/*4:*/ +#line 82 "./rfs_tensor.hweb" + +class FRTensor:public FTensor{ +int nv; +public: +/*5:*/ +#line 102 "./rfs_tensor.hweb" + +FRTensor(int c,int nvar,int d) +:FTensor(along_row,IntSequence(d,nvar), +FFSTensor::calcMaxOffset(nvar,d),c,d),nv(nvar){} +FRTensor(const FRTensor&ft) +:FTensor(ft),nv(ft.nv){} +FRTensor(const URTensor&ut); + +/*:5*/ +#line 86 "./rfs_tensor.hweb" +; +virtual~FRTensor(){} + +void increment(IntSequence&v)const; +void decrement(IntSequence&v)const; +UTensor&unfold()const; + +int nvar()const +{return nv;} +int getOffset(const IntSequence&v)const +{return FTensor::getOffset(v,nv);} +Symmetry getSym()const +{return Symmetry(dimen());} +}; + +/*:4*/ +#line 46 "./rfs_tensor.hweb" +; +/*6:*/ +#line 117 "./rfs_tensor.hweb" + +class URSingleTensor:public URTensor{ +public: +URSingleTensor(int nvar,int d) +:URTensor(1,nvar,d){} +URSingleTensor(const vector &cols); +URSingleTensor(const ConstVector&v,int d); +URSingleTensor(const URSingleTensor&ut) +:URTensor(ut){} +virtual~URSingleTensor(){} +FTensor&fold()const; +}; + +/*:6*/ +#line 47 "./rfs_tensor.hweb" +; +/*7:*/ +#line 136 "./rfs_tensor.hweb" + +class FRSingleTensor:public FRTensor{ +public: +FRSingleTensor(int nvar,int d) +:FRTensor(1,nvar,d){} +FRSingleTensor(const URSingleTensor&ut); +FRSingleTensor(const FRSingleTensor&ft) +:FRTensor(ft){} +virtual~FRSingleTensor(){} +}; + + +/*:7*/ +#line 48 "./rfs_tensor.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/sparse_tensor.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/sparse_tensor.cpp new file mode 100644 index 000000000..737ddd290 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/sparse_tensor.cpp @@ -0,0 +1,301 @@ +/*1:*/ +#line 6 "./sparse_tensor.cweb" + +#include "sparse_tensor.h" +#include "fs_tensor.h" +#include "tl_exception.h" + +#include + +/*2:*/ +#line 30 "./sparse_tensor.cweb" + +void SparseTensor::insert(const IntSequence&key,int r,double c) +{ +TL_RAISE_IF(r<0||r>=nr, +"Row number out of dimension of tensor in SparseTensor::insert"); +TL_RAISE_IF(key.size()!=dimen(), +"Wrong length of key in SparseTensor::insert"); +TL_RAISE_IF(!std::isfinite(c), +"Insertion of non-finite value in SparseTensor::insert"); + +iterator first_pos= m.lower_bound(key); +/*3:*/ +#line 50 "./sparse_tensor.cweb" + +iterator last_pos= m.upper_bound(key); +for(iterator it= first_pos;it!=last_pos;++it) +if((*it).second.first==r){ +TL_RAISE("Duplicate insertion in SparseTensor::insert"); +return; +} + +/*:3*/ +#line 41 "./sparse_tensor.cweb" +; +m.insert(first_pos,Map::value_type(key,Item(r,c))); +if(first_nz_row> r) +first_nz_row= r; +if(last_nz_row=nv||key[0]<0, +"Wrong value of the key in FSSparseTensor::insert"); +SparseTensor::insert(key,r,c); +} + +/*:10*/ +#line 20 "./sparse_tensor.cweb" +; +/*11:*/ +#line 171 "./sparse_tensor.cweb" + +void FSSparseTensor::multColumnAndAdd(const Tensor&t,Vector&v)const +{ +/*12:*/ +#line 195 "./sparse_tensor.cweb" + +TL_RAISE_IF(v.length()!=nrows(), +"Wrong size of output vector in FSSparseTensor::multColumnAndAdd"); +TL_RAISE_IF(t.dimen()!=dimen(), +"Wrong dimension of tensor in FSSparseTensor::multColumnAndAdd"); +TL_RAISE_IF(t.ncols()!=1, +"The input tensor is not single-column in FSSparseTensor::multColumnAndAdd"); + + +/*:12*/ +#line 174 "./sparse_tensor.cweb" +; +for(Tensor::index it= t.begin();it!=t.end();++it){ +int ind= *it; +double a= t.get(ind,0); +if(a!=0.0){ +IntSequence key(it.getCoor()); +key.sort(); +/*13:*/ +#line 205 "./sparse_tensor.cweb" + +TL_RAISE_IF(key[0]<0||key[key.size()-1]>=nv, +"Wrong coordinates of index in FSSparseTensor::multColumnAndAdd"); + +/*:13*/ +#line 181 "./sparse_tensor.cweb" +; +const_iterator first_pos= m.lower_bound(key); +const_iterator last_pos= m.upper_bound(key); +for(const_iterator cit= first_pos;cit!=last_pos;++cit){ +int r= (*cit).second.first; +double c= (*cit).second.second; +v[r]+= c*a; +} +} +} +} + + +/*:11*/ +#line 21 "./sparse_tensor.cweb" +; +/*14:*/ +#line 210 "./sparse_tensor.cweb" + +void FSSparseTensor::print()const +{ +printf("FS Sparse tensor: dim=%d, nv=%d, (%dx%d)\n",dim,nv,nr,nc); +SparseTensor::print(); +} + +/*:14*/ +#line 22 "./sparse_tensor.cweb" +; +/*15:*/ +#line 218 "./sparse_tensor.cweb" + +GSSparseTensor::GSSparseTensor(const FSSparseTensor&t,const IntSequence&ss, +const IntSequence&coor,const TensorDimens&td) +:SparseTensor(td.dimen(),t.nrows(),td.calcFoldMaxOffset()), +tdims(td) +{ +/*16:*/ +#line 241 "./sparse_tensor.cweb" + +IntSequence s_offsets(ss.size(),0); +for(int i= 1;i + +using namespace std; + +/*2:*/ +#line 50 "./sparse_tensor.hweb" + +struct ltseq{ +bool operator()(const IntSequence&s1,const IntSequence&s2)const +{return s1 Item; +typedef multimap Map; +typedef Map::const_iterator const_iterator; +protected: +typedef Map::iterator iterator; + +Map m; +const int dim; +const int nr; +const int nc; +int first_nz_row; +int last_nz_row; +public: +SparseTensor(int d,int nnr,int nnc) +:dim(d),nr(nnr),nc(nnc),first_nz_row(nr),last_nz_row(-1){} +SparseTensor(const SparseTensor&t) +:m(t.m),dim(t.dim),nr(t.nr),nc(t.nc){} +virtual~SparseTensor(){} +void insert(const IntSequence&s,int r,double c); +const Map&getMap()const +{return m;} +int dimen()const +{return dim;} +int nrows()const +{return nr;} +int ncols()const +{return nc;} +double getFillFactor()const +{return((double)m.size())/(nrows()*ncols());} +double getFoldIndexFillFactor()const; +double getUnfoldIndexFillFactor()const; +int getNumNonZero()const +{return m.size();} +int getFirstNonZeroRow()const +{return first_nz_row;} +int getLastNonZeroRow()const +{return last_nz_row;} +virtual const Symmetry&getSym()const= 0; +void print()const; +bool isFinite()const; +} + +/*:3*/ +#line 43 "./sparse_tensor.hweb" +; +/*4:*/ +#line 109 "./sparse_tensor.hweb" + +class FSSparseTensor:public SparseTensor{ +public: +typedef SparseTensor::const_iterator const_iterator; +private: +const int nv; +const Symmetry sym; +public: +FSSparseTensor(int d,int nvar,int r); +FSSparseTensor(const FSSparseTensor&t); +void insert(const IntSequence&s,int r,double c); +void multColumnAndAdd(const Tensor&t,Vector&v)const; +const Symmetry&getSym()const +{return sym;} +int nvar()const +{return nv;} +void print()const; +}; + + +/*:4*/ +#line 44 "./sparse_tensor.hweb" +; +/*5:*/ +#line 134 "./sparse_tensor.hweb" + +class GSSparseTensor:public SparseTensor{ +public: +typedef SparseTensor::const_iterator const_iterator; +private: +const TensorDimens tdims; +public: +GSSparseTensor(const FSSparseTensor&t,const IntSequence&ss, +const IntSequence&coor,const TensorDimens&td); +GSSparseTensor(const GSSparseTensor&t) +:SparseTensor(t),tdims(t.tdims){} +void insert(const IntSequence&s,int r,double c); +const Symmetry&getSym()const +{return tdims.getSym();} +const TensorDimens&getDims()const +{return tdims;} +void print()const; + +}; + +/*:5*/ +#line 45 "./sparse_tensor.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/stack_container.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/stack_container.cpp new file mode 100644 index 000000000..d067981fe --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/stack_container.cpp @@ -0,0 +1,570 @@ +/*1:*/ +#line 6 "./stack_container.cweb" + +#include "stack_container.h" +#include "pyramid_prod2.h" +#include "ps_tensor.h" + +double FoldedStackContainer::fill_threshold= 0.00005; +double UnfoldedStackContainer::fill_threshold= 0.00005; +/*2:*/ +#line 59 "./stack_container.cweb" + +void FoldedStackContainer::multAndAdd(const FSSparseTensor&t, +FGSTensor&out)const +{ +TL_RAISE_IF(t.nvar()!=getAllSize(), +"Wrong number of variables of tensor for FoldedStackContainer::multAndAdd"); +multAndAddSparse2(t,out); +} + +/*:2*/ +#line 13 "./stack_container.cweb" +; +/*3:*/ +#line 73 "./stack_container.cweb" + +void FoldedStackContainer::multAndAdd(int dim,const FGSContainer&c,FGSTensor&out)const +{ +TL_RAISE_IF(c.num()!=numStacks(), +"Wrong symmetry length of container for FoldedStackContainer::multAndAdd"); + +THREAD_GROUP gr; +SymmetrySet ss(dim,c.num()); +for(symiterator si(ss);!si.isEnd();++si){ +if(c.check(*si)){ +THREAD*worker= new WorkerFoldMAADense(*this,*si,c,out); +gr.insert(worker); +} +} +gr.run(); +} + +/*:3*/ +#line 14 "./stack_container.cweb" +; +/*4:*/ +#line 93 "./stack_container.cweb" + +void WorkerFoldMAADense::operator()() +{ +Permutation iden(dense_cont.num()); +IntSequence coor(sym,iden.getMap()); +const FGSTensor*g= dense_cont.get(sym); +cont.multAndAddStacks(coor,*g,out,&out); +} + +/*:4*/ +#line 15 "./stack_container.cweb" +; +/*5:*/ +#line 103 "./stack_container.cweb" + +WorkerFoldMAADense::WorkerFoldMAADense(const FoldedStackContainer&container, +const Symmetry&s, +const FGSContainer&dcontainer, +FGSTensor&outten) +:cont(container),sym(s),dense_cont(dcontainer),out(outten) +{} + +/*:5*/ +#line 16 "./stack_container.cweb" +; +/*6:*/ +#line 113 "./stack_container.cweb" + +void FoldedStackContainer::multAndAddSparse1(const FSSparseTensor&t, +FGSTensor&out)const +{ +THREAD_GROUP gr; +UFSTensor dummy(0,numStacks(),t.dimen()); +for(Tensor::index ui= dummy.begin();ui!=dummy.end();++ui){ +THREAD*worker= new WorkerFoldMAASparse1(*this,t,out,ui.getCoor()); +gr.insert(worker); +} +gr.run(); +} + +/*:6*/ +#line 17 "./stack_container.cweb" +; +/*7:*/ +#line 135 "./stack_container.cweb" + +void WorkerFoldMAASparse1::operator()() +{ +const EquivalenceSet&eset= ebundle.get(out.dimen()); +const PermutationSet&pset= tls.pbundle->get(t.dimen()); +Permutation iden(t.dimen()); + +UPSTensor slice(t,cont.getStackSizes(),coor, +PerTensorDimens(cont.getStackSizes(),coor)); +for(int iper= 0;iper sp(cont,*it,out.getSym()); +if(!sp.isZero(percoor)){ +KronProdStack kp(sp,percoor); +kp.optimizeOrder(); +const Permutation&oper= kp.getPer(); +if(Permutation(oper,per)==iden){ +FPSTensor fps(out.getDims(),*it,slice,kp); +{ +SYNCHRO syn(&out,"WorkerUnfoldMAASparse1"); +fps.addTo(out); +} +} +} +} +} +} +} + +/*:7*/ +#line 18 "./stack_container.cweb" +; +/*8:*/ +#line 170 "./stack_container.cweb" + +WorkerFoldMAASparse1::WorkerFoldMAASparse1(const FoldedStackContainer&container, +const FSSparseTensor&ten, +FGSTensor&outten,const IntSequence&c) +:cont(container),t(ten),out(outten),coor(c),ebundle(*(tls.ebundle)){} + + +/*:8*/ +#line 19 "./stack_container.cweb" +; +/*9:*/ +#line 183 "./stack_container.cweb" + +void FoldedStackContainer::multAndAddSparse2(const FSSparseTensor&t, +FGSTensor&out)const +{ +THREAD_GROUP gr; +FFSTensor dummy_f(0,numStacks(),t.dimen()); +for(Tensor::index fi= dummy_f.begin();fi!=dummy_f.end();++fi){ +THREAD*worker= new WorkerFoldMAASparse2(*this,t,out,fi.getCoor()); +gr.insert(worker); +} +gr.run(); +} + +/*:9*/ +#line 20 "./stack_container.cweb" +; +/*10:*/ +#line 207 "./stack_container.cweb" + +void WorkerFoldMAASparse2::operator()() +{ +GSSparseTensor slice(t,cont.getStackSizes(),coor, +TensorDimens(cont.getStackSizes(),coor)); +if(slice.getNumNonZero()){ +if(slice.getUnfoldIndexFillFactor()> FoldedStackContainer::fill_threshold){ +FGSTensor dense_slice(slice); +int r1= slice.getFirstNonZeroRow(); +int r2= slice.getLastNonZeroRow(); +FGSTensor dense_slice1(r1,r2-r1+1,dense_slice); +FGSTensor out1(r1,r2-r1+1,out); +cont.multAndAddStacks(coor,dense_slice1,out1,&out); +}else +cont.multAndAddStacks(coor,slice,out,&out); +} +} + +/*:10*/ +#line 21 "./stack_container.cweb" +; +/*11:*/ +#line 226 "./stack_container.cweb" + +WorkerFoldMAASparse2::WorkerFoldMAASparse2(const FoldedStackContainer&container, +const FSSparseTensor&ten, +FGSTensor&outten,const IntSequence&c) +:cont(container),t(ten),out(outten),coor(c) +{} + + +/*:11*/ +#line 22 "./stack_container.cweb" +; +/*12:*/ +#line 248 "./stack_container.cweb" + +void FoldedStackContainer::multAndAddSparse3(const FSSparseTensor&t, +FGSTensor&out)const +{ +const EquivalenceSet&eset= ebundle.get(out.dimen()); +for(Tensor::index run= out.begin();run!=out.end();++run){ +Vector outcol(out,*run); +FRSingleTensor sumcol(t.nvar(),t.dimen()); +sumcol.zeros(); +for(EquivalenceSet::const_iterator it= eset.begin(); +it!=eset.end();++it){ +if((*it).numClasses()==t.dimen()){ +StackProduct sp(*this,*it,out.getSym()); +IrregTensorHeader header(sp,run.getCoor()); +IrregTensor irten(header); +irten.addTo(sumcol); +} +} +t.multColumnAndAdd(sumcol,outcol); +} +} + +/*:12*/ +#line 23 "./stack_container.cweb" +; +/*13:*/ +#line 278 "./stack_container.cweb" + +void FoldedStackContainer::multAndAddSparse4(const FSSparseTensor&t,FGSTensor&out)const +{ +THREAD_GROUP gr; +FFSTensor dummy_f(0,numStacks(),t.dimen()); +for(Tensor::index fi= dummy_f.begin();fi!=dummy_f.end();++fi){ +THREAD*worker= new WorkerFoldMAASparse4(*this,t,out,fi.getCoor()); +gr.insert(worker); +} +gr.run(); +} + +/*:13*/ +#line 24 "./stack_container.cweb" +; +/*14:*/ +#line 294 "./stack_container.cweb" + +void WorkerFoldMAASparse4::operator()() +{ +GSSparseTensor slice(t,cont.getStackSizes(),coor, +TensorDimens(cont.getStackSizes(),coor)); +if(slice.getNumNonZero()) +cont.multAndAddStacks(coor,slice,out,&out); +} + +/*:14*/ +#line 25 "./stack_container.cweb" +; +/*15:*/ +#line 304 "./stack_container.cweb" + +WorkerFoldMAASparse4::WorkerFoldMAASparse4(const FoldedStackContainer&container, +const FSSparseTensor&ten, +FGSTensor&outten,const IntSequence&c) +:cont(container),t(ten),out(outten),coor(c) +{} + + +/*:15*/ +#line 26 "./stack_container.cweb" +; +/*16:*/ +#line 321 "./stack_container.cweb" + +void FoldedStackContainer::multAndAddStacks(const IntSequence&coor, +const FGSTensor&g, +FGSTensor&out,const void*ad)const +{ +const EquivalenceSet&eset= ebundle.get(out.dimen()); + +UGSTensor ug(g); +UFSTensor dummy_u(0,numStacks(),g.dimen()); +for(Tensor::index ui= dummy_u.begin();ui!=dummy_u.end();++ui){ +IntSequence tmp(ui.getCoor()); +tmp.sort(); +if(tmp==coor){ +Permutation sort_per(ui.getCoor()); +sort_per.inverse(); +for(EquivalenceSet::const_iterator it= eset.begin(); +it!=eset.end();++it){ +if((*it).numClasses()==g.dimen()){ +StackProduct sp(*this,*it,sort_per,out.getSym()); +if(!sp.isZero(coor)){ +KronProdStack kp(sp,coor); +if(ug.getSym().isFull()) +kp.optimizeOrder(); +FPSTensor fps(out.getDims(),*it,sort_per,ug,kp); +{ +SYNCHRO syn(ad,"multAndAddStacks"); +fps.addTo(out); +} +} +} +} +} +} +} + +/*:16*/ +#line 27 "./stack_container.cweb" +; +/*17:*/ +#line 362 "./stack_container.cweb" + +void FoldedStackContainer::multAndAddStacks(const IntSequence&coor, +const GSSparseTensor&g, +FGSTensor&out,const void*ad)const +{ +const EquivalenceSet&eset= ebundle.get(out.dimen()); +UFSTensor dummy_u(0,numStacks(),g.dimen()); +for(Tensor::index ui= dummy_u.begin();ui!=dummy_u.end();++ui){ +IntSequence tmp(ui.getCoor()); +tmp.sort(); +if(tmp==coor){ +Permutation sort_per(ui.getCoor()); +sort_per.inverse(); +for(EquivalenceSet::const_iterator it= eset.begin(); +it!=eset.end();++it){ +if((*it).numClasses()==g.dimen()){ +StackProduct sp(*this,*it,sort_per,out.getSym()); +if(!sp.isZero(coor)){ +KronProdStack kp(sp,coor); +FPSTensor fps(out.getDims(),*it,sort_per,g,kp); +{ +SYNCHRO syn(ad,"multAndAddStacks"); +fps.addTo(out); +} +} +} +} +} +} +} + +/*:17*/ +#line 28 "./stack_container.cweb" +; + +/*18:*/ +#line 397 "./stack_container.cweb" + +void UnfoldedStackContainer::multAndAdd(const FSSparseTensor&t, +UGSTensor&out)const +{ +TL_RAISE_IF(t.nvar()!=getAllSize(), +"Wrong number of variables of tensor for UnfoldedStackContainer::multAndAdd"); +multAndAddSparse2(t,out); +} + +/*:18*/ +#line 30 "./stack_container.cweb" +; +/*19:*/ +#line 419 "./stack_container.cweb" + +void UnfoldedStackContainer::multAndAdd(int dim,const UGSContainer&c, +UGSTensor&out)const +{ +TL_RAISE_IF(c.num()!=numStacks(), +"Wrong symmetry length of container for UnfoldedStackContainer::multAndAdd"); + +THREAD_GROUP gr; +SymmetrySet ss(dim,c.num()); +for(symiterator si(ss);!si.isEnd();++si){ +if(c.check(*si)){ +THREAD*worker= new WorkerUnfoldMAADense(*this,*si,c,out); +gr.insert(worker); +} +} +gr.run(); +} + +/*:19*/ +#line 31 "./stack_container.cweb" +; +/*20:*/ +#line 438 "./stack_container.cweb" + +void WorkerUnfoldMAADense::operator()() +{ +Permutation iden(dense_cont.num()); +IntSequence coor(sym,iden.getMap()); +const UGSTensor*g= dense_cont.get(sym); +cont.multAndAddStacks(coor,*g,out,&out); +} + +/*:20*/ +#line 32 "./stack_container.cweb" +; +/*21:*/ +#line 448 "./stack_container.cweb" + +WorkerUnfoldMAADense::WorkerUnfoldMAADense(const UnfoldedStackContainer&container, +const Symmetry&s, +const UGSContainer&dcontainer, +UGSTensor&outten) +:cont(container),sym(s),dense_cont(dcontainer),out(outten){} + + +/*:21*/ +#line 33 "./stack_container.cweb" +; +/*22:*/ +#line 473 "./stack_container.cweb" + +void UnfoldedStackContainer::multAndAddSparse1(const FSSparseTensor&t, +UGSTensor&out)const +{ +THREAD_GROUP gr; +UFSTensor dummy(0,numStacks(),t.dimen()); +for(Tensor::index ui= dummy.begin();ui!=dummy.end();++ui){ +THREAD*worker= new WorkerUnfoldMAASparse1(*this,t,out,ui.getCoor()); +gr.insert(worker); +} +gr.run(); +} + +/*:22*/ +#line 34 "./stack_container.cweb" +; +/*23:*/ +#line 512 "./stack_container.cweb" + +void WorkerUnfoldMAASparse1::operator()() +{ +const EquivalenceSet&eset= ebundle.get(out.dimen()); +const PermutationSet&pset= tls.pbundle->get(t.dimen()); +Permutation iden(t.dimen()); + +UPSTensor slice(t,cont.getStackSizes(),coor, +PerTensorDimens(cont.getStackSizes(),coor)); +for(int iper= 0;iper sp(cont,*it,out.getSym()); +if(!sp.isZero(percoor)){ +KronProdStack kp(sp,percoor); +kp.optimizeOrder(); +const Permutation&oper= kp.getPer(); +if(Permutation(oper,per)==iden){ +UPSTensor ups(out.getDims(),*it,slice,kp); +{ +SYNCHRO syn(&out,"WorkerUnfoldMAASparse1"); +ups.addTo(out); +} +} +} +} +} +} +} + +/*:23*/ +#line 35 "./stack_container.cweb" +; +/*24:*/ +#line 547 "./stack_container.cweb" + +WorkerUnfoldMAASparse1::WorkerUnfoldMAASparse1(const UnfoldedStackContainer&container, +const FSSparseTensor&ten, +UGSTensor&outten,const IntSequence&c) +:cont(container),t(ten),out(outten),coor(c),ebundle(*(tls.ebundle)){} + + +/*:24*/ +#line 36 "./stack_container.cweb" +; +/*25:*/ +#line 575 "./stack_container.cweb" + +void UnfoldedStackContainer::multAndAddSparse2(const FSSparseTensor&t, +UGSTensor&out)const +{ +THREAD_GROUP gr; +FFSTensor dummy_f(0,numStacks(),t.dimen()); +for(Tensor::index fi= dummy_f.begin();fi!=dummy_f.end();++fi){ +THREAD*worker= new WorkerUnfoldMAASparse2(*this,t,out,fi.getCoor()); +gr.insert(worker); +} +gr.run(); +} + +/*:25*/ +#line 37 "./stack_container.cweb" +; +/*26:*/ +#line 595 "./stack_container.cweb" + +void WorkerUnfoldMAASparse2::operator()() +{ +GSSparseTensor slice(t,cont.getStackSizes(),coor, +TensorDimens(cont.getStackSizes(),coor)); +if(slice.getNumNonZero()){ +FGSTensor fslice(slice); +UGSTensor dense_slice(fslice); +int r1= slice.getFirstNonZeroRow(); +int r2= slice.getLastNonZeroRow(); +UGSTensor dense_slice1(r1,r2-r1+1,dense_slice); +UGSTensor out1(r1,r2-r1+1,out); + +cont.multAndAddStacks(coor,dense_slice1,out1,&out); +} +} + +/*:26*/ +#line 38 "./stack_container.cweb" +; +/*27:*/ +#line 613 "./stack_container.cweb" + +WorkerUnfoldMAASparse2::WorkerUnfoldMAASparse2(const UnfoldedStackContainer&container, +const FSSparseTensor&ten, +UGSTensor&outten,const IntSequence&c) +:cont(container),t(ten),out(outten),coor(c){} + + +/*:27*/ +#line 39 "./stack_container.cweb" +; +/*28:*/ +#line 636 "./stack_container.cweb" + +void UnfoldedStackContainer::multAndAddStacks(const IntSequence&fi, +const UGSTensor&g, +UGSTensor&out,const void*ad)const +{ +const EquivalenceSet&eset= ebundle.get(out.dimen()); + +UFSTensor dummy_u(0,numStacks(),g.dimen()); +for(Tensor::index ui= dummy_u.begin();ui!=dummy_u.end();++ui){ +IntSequence tmp(ui.getCoor()); +tmp.sort(); +if(tmp==fi){ +Permutation sort_per(ui.getCoor()); +sort_per.inverse(); +for(EquivalenceSet::const_iterator it= eset.begin(); +it!=eset.end();++it){ +if((*it).numClasses()==g.dimen()){ +StackProduct sp(*this,*it,sort_per,out.getSym()); +if(!sp.isZero(fi)){ +KronProdStack kp(sp,fi); +if(g.getSym().isFull()) +kp.optimizeOrder(); +UPSTensor ups(out.getDims(),*it,sort_per,g,kp); +{ +SYNCHRO syn(ad,"multAndAddStacks"); +ups.addTo(out); +} +} +} +} +} +} +} + +/*:28*/ +#line 40 "./stack_container.cweb" +; + + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/stack_container.h b/mex/sources/korderpert/Dyn_pp/tl/cc/stack_container.h new file mode 100644 index 000000000..9814a580b --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/stack_container.h @@ -0,0 +1,734 @@ +/*1:*/ +#line 80 "./stack_container.hweb" + +#ifndef STACK_CONTAINER_H +#define STACK_CONTAINER_H + +#include "int_sequence.h" +#include "equivalence.h" +#include "tl_static.h" +#include "t_container.h" +#include "kron_prod.h" +#include "permutation.h" +#include "sthread.h" + +/*2:*/ +#line 135 "./stack_container.hweb" + +template +class StackContainerInterface{ +public: +typedef TensorContainer<_Ttype> _Ctype; +typedef enum{matrix,unit,zero}itype; +protected: +const EquivalenceBundle&ebundle; +public: +StackContainerInterface() +:ebundle(*(tls.ebundle)){} +virtual~StackContainerInterface(){} +virtual const IntSequence&getStackSizes()const= 0; +virtual IntSequence&getStackSizes()= 0; +virtual const IntSequence&getStackOffsets()const= 0; +virtual IntSequence&getStackOffsets()= 0; +virtual int numConts()const= 0; +virtual const _Ctype*getCont(int i)const= 0; +virtual itype getType(int i,const Symmetry&s)const= 0; +virtual int numStacks()const= 0; +virtual bool isZero(int i,const Symmetry&s)const= 0; +virtual const _Ttype*getMatrix(int i,const Symmetry&s)const= 0; +virtual int getLengthOfMatrixStacks(const Symmetry&s)const= 0; +virtual int getUnitPos(const Symmetry&s)const= 0; +virtual Vector*createPackedColumn(const Symmetry&s, +const IntSequence&coor, +int&iu)const= 0; +int getAllSize()const +{return getStackOffsets()[numStacks()-1] ++getStackSizes()[numStacks()-1];} +}; + +/*:2*/ +#line 92 "./stack_container.hweb" +; +/*3:*/ +#line 171 "./stack_container.hweb" + +template +class StackContainer:virtual public StackContainerInterface<_Ttype> { +public: +typedef StackContainerInterface<_Ttype> _Stype; +typedef typename StackContainerInterface<_Ttype> ::_Ctype _Ctype; +typedef typename StackContainerInterface<_Ttype> ::itype itype; +protected: +int num_conts; +IntSequence stack_sizes; +IntSequence stack_offsets; +const _Ctype**const conts; +public: +StackContainer(int ns,int nc) +:num_conts(nc),stack_sizes(ns,0),stack_offsets(ns,0), +conts(new const _Ctype*[nc]){} +virtual~StackContainer(){delete[]conts;} +const IntSequence&getStackSizes()const +{return stack_sizes;} +IntSequence&getStackSizes() +{return stack_sizes;} +const IntSequence&getStackOffsets()const +{return stack_offsets;} +IntSequence&getStackOffsets() +{return stack_offsets;} +int numConts()const +{return num_conts;} +const _Ctype*getCont(int i)const +{return conts[i];} +virtual itype getType(int i,const Symmetry&s)const= 0; +int numStacks()const +{return stack_sizes.size();} +/*4:*/ +#line 213 "./stack_container.hweb" + +bool isZero(int i,const Symmetry&s)const +{ +TL_RAISE_IF(i<0||i>=numStacks(), +"Wrong index to stack in StackContainer::isZero."); +return(getType(i,s)==_Stype::zero|| +(getType(i,s)==_Stype::matrix&&!conts[i]->check(s))); +} + +/*:4*/ +#line 203 "./stack_container.hweb" +; +/*5:*/ +#line 223 "./stack_container.hweb" + +const _Ttype*getMatrix(int i,const Symmetry&s)const +{ +TL_RAISE_IF(isZero(i,s)||getType(i,s)==_Stype::unit, +"Matrix is not returned in StackContainer::getMatrix"); +return conts[i]->get(s); +} + +/*:5*/ +#line 204 "./stack_container.hweb" +; +/*6:*/ +#line 232 "./stack_container.hweb" + +int getLengthOfMatrixStacks(const Symmetry&s)const +{ +int res= 0; +int i= 0; +while(i=0&&getType(i,s)!=_Stype::unit) +i--; +return i; +} + + +/*:7*/ +#line 206 "./stack_container.hweb" +; +/*8:*/ +#line 257 "./stack_container.hweb" + +Vector*createPackedColumn(const Symmetry&s, +const IntSequence&coor,int&iu)const +{ +TL_RAISE_IF(s.dimen()!=coor.size(), +"Incompatible coordinates for symmetry in StackContainer::createPackedColumn"); + +int len= getLengthOfMatrixStacks(s); +iu= -1; +int i= 0; +if(-1!=(i= getUnitPos(s))){ +iu= stack_offsets[i]+coor[0]; +len++; +} + +Vector*res= new Vector(len); +i= 0; +while(i { +friend class WorkerFoldMAADense; +friend class WorkerFoldMAASparse1; +friend class WorkerFoldMAASparse2; +friend class WorkerFoldMAASparse4; +public: +static double fill_threshold; +void multAndAdd(int dim,const TensorContainer &c, +FGSTensor&out)const +{if(c.check(Symmetry(dim)))multAndAdd(*(c.get(Symmetry(dim))),out);} +void multAndAdd(const FSSparseTensor&t,FGSTensor&out)const; +void multAndAdd(int dim,const FGSContainer&c,FGSTensor&out)const; +protected: +void multAndAddSparse1(const FSSparseTensor&t,FGSTensor&out)const; +void multAndAddSparse2(const FSSparseTensor&t,FGSTensor&out)const; +void multAndAddSparse3(const FSSparseTensor&t,FGSTensor&out)const; +void multAndAddSparse4(const FSSparseTensor&t,FGSTensor&out)const; +void multAndAddStacks(const IntSequence&fi,const FGSTensor&g, +FGSTensor&out,const void*ad)const; +void multAndAddStacks(const IntSequence&fi,const GSSparseTensor&g, +FGSTensor&out,const void*ad)const; +}; + + +/*:10*/ +#line 94 "./stack_container.hweb" +; +/*11:*/ +#line 327 "./stack_container.hweb" + +class WorkerUnfoldMAADense; +class WorkerUnfoldMAASparse1; +class WorkerUnfoldMAASparse2; +class UnfoldedStackContainer:virtual public StackContainerInterface { +friend class WorkerUnfoldMAADense; +friend class WorkerUnfoldMAASparse1; +friend class WorkerUnfoldMAASparse2; +public: +static double fill_threshold; +void multAndAdd(int dim,const TensorContainer &c, +UGSTensor&out)const +{if(c.check(Symmetry(dim)))multAndAdd(*(c.get(Symmetry(dim))),out);} +void multAndAdd(const FSSparseTensor&t,UGSTensor&out)const; +void multAndAdd(int dim,const UGSContainer&c,UGSTensor&out)const; +protected: +void multAndAddSparse1(const FSSparseTensor&t,UGSTensor&out)const; +void multAndAddSparse2(const FSSparseTensor&t,UGSTensor&out)const; +void multAndAddStacks(const IntSequence&fi,const UGSTensor&g, +UGSTensor&out,const void*ad)const; +}; + +/*:11*/ +#line 95 "./stack_container.hweb" +; +/*12:*/ +#line 360 "./stack_container.hweb" + +template +class ZContainer:public StackContainer<_Ttype> { +public: +typedef StackContainer<_Ttype> _Tparent; +typedef StackContainerInterface<_Ttype> _Stype; +typedef typename _Tparent::_Ctype _Ctype; +typedef typename _Tparent::itype itype; +ZContainer(const _Ctype*gss,int ngss,const _Ctype*g,int ng, +int ny,int nu) +:_Tparent(4,2) +{ +_Tparent::stack_sizes[0]= ngss;_Tparent::stack_sizes[1]= ng; +_Tparent::stack_sizes[2]= ny;_Tparent::stack_sizes[3]= nu; +_Tparent::conts[0]= gss; +_Tparent::conts[1]= g; +_Tparent::calculateOffsets(); +} + +/*13:*/ +#line 385 "./stack_container.hweb" + +itype getType(int i,const Symmetry&s)const +{ +if(i==0) +return _Stype::matrix; +if(i==1) +if(s[2]> 0) +return _Stype::zero; +else +return _Stype::matrix; +if(i==2) +if(s==Symmetry(1,0,0,0)) +return _Stype::unit; +else +return _Stype::zero; +if(i==3) +if(s==Symmetry(0,1,0,0)) +return _Stype::unit; +else +return _Stype::zero; + +TL_RAISE("Wrong stack index in ZContainer::getType"); +return _Stype::zero; +} + +/*:13*/ +#line 379 "./stack_container.hweb" +; +}; + +/*:12*/ +#line 96 "./stack_container.hweb" +; +/*14:*/ +#line 411 "./stack_container.hweb" + +class FoldedZContainer:public ZContainer , +public FoldedStackContainer{ +public: +typedef TensorContainer _Ctype; +FoldedZContainer(const _Ctype*gss,int ngss,const _Ctype*g,int ng, +int ny,int nu) +:ZContainer (gss,ngss,g,ng,ny,nu){} +}; + +/*:14*/ +#line 97 "./stack_container.hweb" +; +/*15:*/ +#line 422 "./stack_container.hweb" + +class UnfoldedZContainer:public ZContainer , +public UnfoldedStackContainer{ +public: +typedef TensorContainer _Ctype; +UnfoldedZContainer(const _Ctype*gss,int ngss,const _Ctype*g,int ng, +int ny,int nu) +:ZContainer (gss,ngss,g,ng,ny,nu){} +}; + +/*:15*/ +#line 98 "./stack_container.hweb" +; +/*16:*/ +#line 442 "./stack_container.hweb" + +template +class GContainer:public StackContainer<_Ttype> { +public: +typedef StackContainer<_Ttype> _Tparent; +typedef StackContainerInterface<_Ttype> _Stype; +typedef typename StackContainer<_Ttype> ::_Ctype _Ctype; +typedef typename StackContainer<_Ttype> ::itype itype; +GContainer(const _Ctype*gs,int ngs,int nu) +:StackContainer<_Ttype> (4,1) +{ +_Tparent::stack_sizes[0]= ngs;_Tparent::stack_sizes[1]= nu; +_Tparent::stack_sizes[2]= nu;_Tparent::stack_sizes[3]= 1; +_Tparent::conts[0]= gs; +_Tparent::calculateOffsets(); +} + +/*17:*/ +#line 467 "./stack_container.hweb" + +itype getType(int i,const Symmetry&s)const +{ +if(i==0) +if(s[2]> 0||s==Symmetry(0,0,0,1)) +return _Stype::zero; +else +return _Stype::matrix; +if(i==1) +if(s==Symmetry(0,0,1,0)) +return _Stype::unit; +else +return _Stype::zero; +if(i==2) +return _Stype::zero; +if(i==3) +if(s==Symmetry(0,0,0,1)) +return _Stype::unit; +else +return _Stype::zero; + +TL_RAISE("Wrong stack index in GContainer::getType"); +return _Stype::zero; +} + + +/*:17*/ +#line 459 "./stack_container.hweb" +; +}; + +/*:16*/ +#line 99 "./stack_container.hweb" +; +/*18:*/ +#line 494 "./stack_container.hweb" + +class FoldedGContainer:public GContainer , +public FoldedStackContainer{ +public: +typedef TensorContainer _Ctype; +FoldedGContainer(const _Ctype*gs,int ngs,int nu) +:GContainer (gs,ngs,nu){} +}; + +/*:18*/ +#line 100 "./stack_container.hweb" +; +/*19:*/ +#line 504 "./stack_container.hweb" + +class UnfoldedGContainer:public GContainer , +public UnfoldedStackContainer{ +public: +typedef TensorContainer _Ctype; +UnfoldedGContainer(const _Ctype*gs,int ngs,int nu) +:GContainer (gs,ngs,nu){} +}; + + +/*:19*/ +#line 101 "./stack_container.hweb" +; +/*20:*/ +#line 520 "./stack_container.hweb" + +template +class StackProduct{ +public: +typedef StackContainerInterface<_Ttype> _Stype; +typedef typename _Stype::_Ctype _Ctype; +typedef typename _Stype::itype itype; +protected: +const _Stype&stack_cont; +InducedSymmetries syms; +Permutation per; +public: +StackProduct(const _Stype&sc,const Equivalence&e, +const Symmetry&os) +:stack_cont(sc),syms(e,os),per(e){} +StackProduct(const _Stype&sc,const Equivalence&e, +const Permutation&p,const Symmetry&os) +:stack_cont(sc),syms(e,p,os),per(e,p){} +int dimen()const +{return syms.size();} +int getAllSize()const +{return stack_cont.getAllSize();} +const Symmetry&getProdSym(int ip)const +{return syms[ip];} +/*21:*/ +#line 553 "./stack_container.hweb" + +bool isZero(const IntSequence&istacks)const +{ +TL_RAISE_IF(istacks.size()!=dimen(), +"Wrong istacks coordinates for StackProduct::isZero"); + +bool res= false; +int i= 0; +while(i=stack_cont.numStacks(), +"Wrong index to stack in StackProduct::getType"); +TL_RAISE_IF(ip<0||ip>=dimen(), +"Wrong index to stack container in StackProduct::getType"); +return stack_cont.getType(is,syms[ip]); +} + +/*:22*/ +#line 545 "./stack_container.hweb" +; +/*23:*/ +#line 578 "./stack_container.hweb" + +const _Ttype*getMatrix(int is,int ip)const +{ +return stack_cont.getMatrix(is,syms[ip]); +} + +/*:23*/ +#line 546 "./stack_container.hweb" +; +/*24:*/ +#line 585 "./stack_container.hweb" + +void createPackedColumns(const IntSequence&coor, +Vector**vs,IntSequence&iu)const +{ +TL_RAISE_IF(iu.size()!=dimen(), +"Wrong storage length for unit flags in StackProduct::createPackedColumn"); +TL_RAISE_IF(coor.size()!=per.size(), +"Wrong size of index coor in StackProduct::createPackedColumn"); +IntSequence perindex(coor.size()); +per.apply(coor,perindex); +int off= 0; +for(int i= 0;i +class KronProdStack:public KronProdAllOptim{ +public: +typedef StackProduct<_Ttype> _Ptype; +typedef StackContainerInterface<_Ttype> _Stype; +/*28:*/ +#line 646 "./stack_container.hweb" + +KronProdStack(const _Ptype&sp,const IntSequence&istack) +:KronProdAllOptim(sp.dimen()) +{ +TL_RAISE_IF(sp.dimen()!=istack.size(), +"Wrong stack product dimension for KronProdStack constructor"); + +for(int i= 0;inrows()!=sp.getSize(istack[i]), +"Wrong size of returned matrix in KronProdStack constructor"); +setMat(i,*m); +} +} +} + + +/*:28*/ +#line 635 "./stack_container.hweb" +; +}; + +/*:27*/ +#line 103 "./stack_container.hweb" +; +/*29:*/ +#line 669 "./stack_container.hweb" + +class WorkerFoldMAADense:public THREAD{ +const FoldedStackContainer&cont; +Symmetry sym; +const FGSContainer&dense_cont; +FGSTensor&out; +public: +WorkerFoldMAADense(const FoldedStackContainer&container, +const Symmetry&s, +const FGSContainer&dcontainer, +FGSTensor&outten); +void operator()(); +}; + +/*:29*/ +#line 104 "./stack_container.hweb" +; +/*30:*/ +#line 684 "./stack_container.hweb" + +class WorkerFoldMAASparse1:public THREAD{ +const FoldedStackContainer&cont; +const FSSparseTensor&t; +FGSTensor&out; +IntSequence coor; +const EquivalenceBundle&ebundle; +public: +WorkerFoldMAASparse1(const FoldedStackContainer&container, +const FSSparseTensor&ten, +FGSTensor&outten,const IntSequence&c); +void operator()(); +}; + +/*:30*/ +#line 105 "./stack_container.hweb" +; +/*31:*/ +#line 699 "./stack_container.hweb" + +class WorkerFoldMAASparse2:public THREAD{ +const FoldedStackContainer&cont; +const FSSparseTensor&t; +FGSTensor&out; +IntSequence coor; +public: +WorkerFoldMAASparse2(const FoldedStackContainer&container, +const FSSparseTensor&ten, +FGSTensor&outten,const IntSequence&c); +void operator()(); +}; + +/*:31*/ +#line 106 "./stack_container.hweb" +; +/*32:*/ +#line 713 "./stack_container.hweb" + +class WorkerFoldMAASparse4:public THREAD{ +const FoldedStackContainer&cont; +const FSSparseTensor&t; +FGSTensor&out; +IntSequence coor; +public: +WorkerFoldMAASparse4(const FoldedStackContainer&container, +const FSSparseTensor&ten, +FGSTensor&outten,const IntSequence&c); +void operator()(); +}; + +/*:32*/ +#line 107 "./stack_container.hweb" +; +/*33:*/ +#line 727 "./stack_container.hweb" + +class WorkerUnfoldMAADense:public THREAD{ +const UnfoldedStackContainer&cont; +Symmetry sym; +const UGSContainer&dense_cont; +UGSTensor&out; +public: +WorkerUnfoldMAADense(const UnfoldedStackContainer&container, +const Symmetry&s, +const UGSContainer&dcontainer, +UGSTensor&outten); +void operator()(); +}; + +/*:33*/ +#line 108 "./stack_container.hweb" +; +/*34:*/ +#line 742 "./stack_container.hweb" + +class WorkerUnfoldMAASparse1:public THREAD{ +const UnfoldedStackContainer&cont; +const FSSparseTensor&t; +UGSTensor&out; +IntSequence coor; +const EquivalenceBundle&ebundle; +public: +WorkerUnfoldMAASparse1(const UnfoldedStackContainer&container, +const FSSparseTensor&ten, +UGSTensor&outten,const IntSequence&c); +void operator()(); +}; + +/*:34*/ +#line 109 "./stack_container.hweb" +; +/*35:*/ +#line 757 "./stack_container.hweb" + +class WorkerUnfoldMAASparse2:public THREAD{ +const UnfoldedStackContainer&cont; +const FSSparseTensor&t; +UGSTensor&out; +IntSequence coor; +public: +WorkerUnfoldMAASparse2(const UnfoldedStackContainer&container, +const FSSparseTensor&ten, +UGSTensor&outten,const IntSequence&c); +void operator()(); +}; + + +/*:35*/ +#line 110 "./stack_container.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/sthread.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/sthread.cpp new file mode 100644 index 000000000..5a0162801 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/sthread.cpp @@ -0,0 +1,235 @@ +/*1:*/ +#line 9 "./sthread.cweb" + +#include "sthread.h" + +#ifdef POSIX_THREADS +namespace sthread{ +template<> +int thread_group ::max_parallel_threads= 2; +template<> +int detach_thread_group ::max_parallel_threads= 2; +/*2:*/ +#line 31 "./sthread.cweb" + +/*3:*/ +#line 40 "./sthread.cweb" + +void*posix_thread_function(void*c); +template<> +void thread_traits ::run(_Ctype*c) +{ +pthread_create(&(c->getThreadIden()),NULL,posix_thread_function,(void*)c); +} + +void*posix_detach_thread_function(void*c); + +template<> +void thread_traits ::detach_run(_Dtype*c) +{ +pthread_attr_t attr; +pthread_attr_init(&attr); +pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); +pthread_create(&(c->getThreadIden()),&attr,posix_detach_thread_function,(void*)c); +pthread_attr_destroy(&attr); +} + + +template<> +void thread_traits ::exit() +{ +pthread_exit(NULL); +} + +template<> +void thread_traits ::join(_Ctype*c) +{ +pthread_join(c->getThreadIden(),NULL); +} + +/*:3*/ +#line 32 "./sthread.cweb" +; +/*4:*/ +#line 74 "./sthread.cweb" + +template<> +void mutex_traits ::init(pthread_mutex_t&m) +{ +pthread_mutex_init(&m,NULL); +} + +template<> +void mutex_traits ::lock(pthread_mutex_t&m) +{ +pthread_mutex_lock(&m); +} + +template<> +void mutex_traits ::unlock(pthread_mutex_t&m) +{ +pthread_mutex_unlock(&m); +} + +/*:4*/ +#line 33 "./sthread.cweb" +; +/*5:*/ +#line 94 "./sthread.cweb" + +template<> +void cond_traits ::init(_Tcond&cond) +{ +pthread_cond_init(&cond,NULL); +} + +template<> +void cond_traits ::broadcast(_Tcond&cond) +{ +pthread_cond_broadcast(&cond); +} + +template<> +void cond_traits ::wait(_Tcond&cond,_Tmutex&mutex) +{ +pthread_cond_wait(&cond,&mutex); +} + +template<> +void cond_traits ::destroy(_Tcond&cond) +{ +pthread_cond_destroy(&cond); +} + + +/*:5*/ +#line 34 "./sthread.cweb" +; +/*6:*/ +#line 123 "./sthread.cweb" + +static posix_synchro::mutex_map_t posix_mm; + +PosixSynchro::PosixSynchro(const void*c,const char*id) +:posix_synchro(c,id,posix_mm){} + +/*:6*/ +#line 35 "./sthread.cweb" +; +/*7:*/ +#line 131 "./sthread.cweb" + +void*posix_thread_function(void*c) +{ +thread_traits ::_Ctype*ct= +(thread_traits ::_Ctype*)c; +try{ +ct->operator()(); +}catch(...){ +ct->exit(); +} +return NULL; +} + +/*:7*/ +#line 36 "./sthread.cweb" +; +/*8:*/ +#line 145 "./sthread.cweb" + +void*posix_detach_thread_function(void*c) +{ +thread_traits ::_Dtype*ct= +(thread_traits ::_Dtype*)c; +condition_counter *counter= ct->counter; +try{ +ct->operator()(); +}catch(...){ +ct->exit(); +} +if(counter) +counter->decrease(); +return NULL; +} + + +/*:8*/ +#line 37 "./sthread.cweb" +; + +/*:2*/ +#line 18 "./sthread.cweb" +; +} +#else +namespace sthread{ +template<> +int thread_group ::max_parallel_threads= 1; +template<> +int detach_thread_group ::max_parallel_threads= 1; +/*9:*/ +#line 166 "./sthread.cweb" + +template<> +void thread_traits ::run(_Ctype*c) +{ +c->operator()(); +} +template<> +void thread_traits ::detach_run(_Dtype*c) +{ +c->operator()(); +} + +template<> +void thread_traits ::exit() +{ +} + +template<> +void thread_traits ::join(_Ctype*c) +{ +} + +template<> +void mutex_traits ::init(Empty&m) +{ +} + +template<> +void mutex_traits ::lock(Empty&m) +{ +} + +template<> +void mutex_traits ::unlock(Empty&m) +{ +} + +template<> +void cond_traits ::init(_Tcond&cond) +{ +} + +template<> +void cond_traits ::broadcast(_Tcond&cond) +{ +} + +template<> +void cond_traits ::wait(_Tcond&cond,_Tmutex&mutex) +{ +} + +template<> +void cond_traits ::destroy(_Tcond&cond) +{ +} + +/*:9*/ +#line 26 "./sthread.cweb" +; +} +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/sthread.h b/mex/sources/korderpert/Dyn_pp/tl/cc/sthread.h new file mode 100644 index 000000000..6d946bd0f --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/sthread.h @@ -0,0 +1,535 @@ +/*1:*/ +#line 77 "./sthread.hweb" + +#ifndef STHREAD_H +#define STHREAD_H + +#ifdef POSIX_THREADS +#include +#endif + +#include +#include +#include + +namespace sthread{ +using namespace std; + +class Empty{}; +/*2:*/ +#line 117 "./sthread.hweb" + +template +struct IF{ +typedef Then RET; +}; + +template +struct IF { +typedef Else RET; +}; + + + +/*:2*/ +#line 93 "./sthread.hweb" +; +enum{posix,empty}; +template class thread_traits; +template class detach_thread; +/*3:*/ +#line 134 "./sthread.hweb" + +template +class thread{ +typedef thread_traits _Ttraits; +typedef typename _Ttraits::_Tthread _Tthread; +_Tthread th; +public: +virtual~thread(){} +_Tthread&getThreadIden() +{return th;} +const _Tthread&getThreadIden()const +{return th;} +virtual void operator()()= 0; +void run() +{_Ttraits::run(this);} +void detach_run() +{_Ttraits::detach_run(this);} +void exit() +{_Ttraits::exit();} +}; + +/*:3*/ +#line 97 "./sthread.hweb" +; +/*4:*/ +#line 160 "./sthread.hweb" + +template +class thread_group{ +typedef thread_traits _Ttraits; +typedef thread _Ctype; +list<_Ctype*> tlist; +typedef typename list<_Ctype*> ::iterator iterator; +public: +static int max_parallel_threads; +void insert(_Ctype*c) +{tlist.push_back(c);} +/*5:*/ +#line 180 "./sthread.hweb" + +~thread_group() +{ +while(!tlist.empty()){ +delete tlist.front(); +tlist.pop_front(); +} +} + +/*:5*/ +#line 171 "./sthread.hweb" +; +/*7:*/ +#line 216 "./sthread.hweb" + +void run() +{ +int rem= tlist.size(); +iterator pfirst= tlist.begin(); +while(rem> 2*max_parallel_threads){ +pfirst= run_portion(pfirst,max_parallel_threads); +rem-= max_parallel_threads; +} +if(rem> max_parallel_threads){ +pfirst= run_portion(pfirst,rem/2); +rem-= rem/2; +} +run_portion(pfirst,rem); +} + + + + +/*:7*/ +#line 172 "./sthread.hweb" +; +private: +/*6:*/ +#line 192 "./sthread.hweb" + +iterator run_portion(iterator start,int n) +{ +int c= 0; +for(iterator i= start;crun(); +} +iterator ret; +c= 0; +for(ret= start;c +struct thread_traits{ +typedef typename IF ::RET _Tthread; +typedef thread _Ctype; +typedef detach_thread _Dtype; +static void run(_Ctype*c); +static void detach_run(_Dtype*c); +static void exit(); +static void join(_Ctype*c); +}; + +/*:8*/ +#line 99 "./sthread.hweb" +; +/*9:*/ +#line 251 "./sthread.hweb" + +struct ltmmkey; +typedef pair mmkey; + +template +struct mutex_traits{ +typedef typename IF ::RET _Tmutex; +typedef map ,ltmmkey> mutex_int_map; +static void init(_Tmutex&m); +static void lock(_Tmutex&m); +static void unlock(_Tmutex&m); +}; + +/*:9*/ +#line 100 "./sthread.hweb" +; +/*10:*/ +#line 283 "./sthread.hweb" + +struct ltmmkey{ +bool operator()(const mmkey&k1,const mmkey&k2)const +{return k1.first +class mutex_map +:public mutex_traits ::mutex_int_map +{ +typedef typename mutex_traits ::_Tmutex _Tmutex; +typedef mutex_traits _Mtraits; +typedef pair<_Tmutex,int> mmval; +typedef map _Tparent; +typedef typename _Tparent::iterator iterator; +typedef typename _Tparent::value_type _mvtype; +_Tmutex m; +public: +mutex_map() +{_Mtraits::init(m);} +void insert(const void*c,const char*id,const _Tmutex&m) +{_Tparent::insert(_mvtype(mmkey(c,id),mmval(m,0)));} +bool check(const void*c,const char*id)const +{return _Tparent::find(mmkey(c,id))!=_Tparent::end();} +/*11:*/ +#line 318 "./sthread.hweb" + +mmval*get(const void*c,const char*id) +{ +iterator it= _Tparent::find(mmkey(c,id)); +if(it==_Tparent::end()) +return NULL; +return&((*it).second); +} + +/*:11*/ +#line 308 "./sthread.hweb" +; +/*12:*/ +#line 331 "./sthread.hweb" + +void remove(const void*c,const char*id) +{ +iterator it= _Tparent::find(mmkey(c,id)); +if(it!=_Tparent::end()) +erase(it); +} + +/*:12*/ +#line 309 "./sthread.hweb" +; +void lock_map() +{_Mtraits::lock(m);} +void unlock_map() +{_Mtraits::unlock(m);} + +}; + +/*:10*/ +#line 101 "./sthread.hweb" +; +/*13:*/ +#line 346 "./sthread.hweb" + +template +class synchro{ +typedef typename mutex_traits ::_Tmutex _Tmutex; +typedef mutex_traits _Mtraits; +public: +typedef mutex_map mutex_map_t; +private: +const void*caller; +const char*iden; +mutex_map_t&mutmap; +public: +synchro(const void*c,const char*id,mutex_map_t&mmap) +:caller(c),iden(id),mutmap(mmap) +{lock();} +~synchro() +{unlock();} +private: +/*14:*/ +#line 373 "./sthread.hweb" + +void lock(){ +mutmap.lock_map(); +if(!mutmap.check(caller,iden)){ +_Tmutex mut; +_Mtraits::init(mut); +mutmap.insert(caller,iden,mut); +} +mutmap.get(caller,iden)->second++; +mutmap.unlock_map(); +_Mtraits::lock(mutmap.get(caller,iden)->first); +} + +/*:14*/ +#line 364 "./sthread.hweb" +; +/*15:*/ +#line 390 "./sthread.hweb" + +void unlock(){ +mutmap.lock_map(); +if(mutmap.check(caller,iden)){ +_Mtraits::unlock(mutmap.get(caller,iden)->first); +mutmap.get(caller,iden)->second--; +if(mutmap.get(caller,iden)->second==0) +mutmap.remove(caller,iden); +} +mutmap.unlock_map(); +} + +/*:15*/ +#line 365 "./sthread.hweb" +; +}; + +/*:13*/ +#line 102 "./sthread.hweb" +; +/*16:*/ +#line 405 "./sthread.hweb" + +template +struct cond_traits{ +typedef typename IF ::RET _Tcond; +typedef typename mutex_traits ::_Tmutex _Tmutex; +static void init(_Tcond&cond); +static void broadcast(_Tcond&cond); +static void wait(_Tcond&cond,_Tmutex&mutex); +static void destroy(_Tcond&cond); +}; + +/*:16*/ +#line 103 "./sthread.hweb" +; +/*17:*/ +#line 425 "./sthread.hweb" + +template +class condition_counter{ +typedef typename mutex_traits ::_Tmutex _Tmutex; +typedef typename cond_traits ::_Tcond _Tcond; +int counter; +_Tmutex mut; +_Tcond cond; +bool changed; +public: +/*18:*/ +#line 445 "./sthread.hweb" + +condition_counter() +:counter(0),changed(true) +{ +mutex_traits ::init(mut); +cond_traits ::init(cond); +} + +/*:18*/ +#line 435 "./sthread.hweb" +; +/*19:*/ +#line 456 "./sthread.hweb" + +~condition_counter() +{ +cond_traits ::destroy(cond); +} + +/*:19*/ +#line 436 "./sthread.hweb" +; +/*20:*/ +#line 465 "./sthread.hweb" + +void increase() +{ +mutex_traits ::lock(mut); +counter++; +changed= true; +cond_traits ::broadcast(cond); +mutex_traits ::unlock(mut); +} + +/*:20*/ +#line 437 "./sthread.hweb" +; +/*21:*/ +#line 476 "./sthread.hweb" + +void decrease() +{ +mutex_traits ::lock(mut); +counter--; +changed= true; +cond_traits ::broadcast(cond); +mutex_traits ::unlock(mut); +} + +/*:21*/ +#line 438 "./sthread.hweb" +; +/*22:*/ +#line 490 "./sthread.hweb" + +int waitForChange() +{ +mutex_traits ::lock(mut); +if(!changed){ +cond_traits ::wait(cond,mut); +} +changed= false; +int res= counter; +mutex_traits ::unlock(mut); +return res; +} + + +/*:22*/ +#line 439 "./sthread.hweb" +; +}; + +/*:17*/ +#line 104 "./sthread.hweb" +; +/*23:*/ +#line 509 "./sthread.hweb" + +template +class detach_thread:public thread { +public: +condition_counter *counter; +detach_thread():counter(NULL){} +void installCounter(condition_counter *c) +{counter= c;} +void run() +{thread_traits ::detach_run(this);} +}; + +/*:23*/ +#line 105 "./sthread.hweb" +; +/*24:*/ +#line 525 "./sthread.hweb" + +template +class detach_thread_group{ +typedef thread_traits _Ttraits; +typedef cond_traits _Ctraits; +typedef detach_thread _Ctype; +list<_Ctype*> tlist; +typedef typename list<_Ctype*> ::iterator iterator; +condition_counter counter; +public: +static int max_parallel_threads; +/*25:*/ +#line 542 "./sthread.hweb" + +void insert(_Ctype*c) +{ +tlist.push_back(c); +c->installCounter(&counter); +} + +/*:25*/ +#line 536 "./sthread.hweb" +; +/*26:*/ +#line 550 "./sthread.hweb" + +~detach_thread_group() +{ +while(!tlist.empty()){ +delete tlist.front(); +tlist.pop_front(); +} +} + +/*:26*/ +#line 537 "./sthread.hweb" +; +/*27:*/ +#line 566 "./sthread.hweb" + +void run() +{ +int mpt= max_parallel_threads; +iterator it= tlist.begin(); +while(it!=tlist.end()){ +if(counter.waitForChange()run(); +++it; +} +} +while(counter.waitForChange()> 0){} +} + + +/*:27*/ +#line 538 "./sthread.hweb" +; +}; + +/*:24*/ +#line 106 "./sthread.hweb" +; +#ifdef POSIX_THREADS +/*28:*/ +#line 586 "./sthread.hweb" + +typedef detach_thread PosixThread; +typedef detach_thread_group PosixThreadGroup; +typedef synchro posix_synchro; +class PosixSynchro:public posix_synchro{ +public: +PosixSynchro(const void*c,const char*id); +}; + +#define THREAD sthread::PosixThread +#define THREAD_GROUP sthread::PosixThreadGroup +#define SYNCHRO sthread::PosixSynchro + +/*:28*/ +#line 108 "./sthread.hweb" +; +#else +/*29:*/ +#line 604 "./sthread.hweb" + +typedef thread NoThread; +typedef thread_group NoThreadGroup; +typedef synchro no_synchro; +class NoSynchro{ +public: +NoSynchro(const void*c,const char*id){} +~NoSynchro(){} +}; + +#define THREAD sthread::NoThread +#define THREAD_GROUP sthread::NoThreadGroup +#define SYNCHRO sthread::NoSynchro + +/*:29*/ +#line 110 "./sthread.hweb" +; +#endif +}; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/symmetry.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/symmetry.cpp new file mode 100644 index 000000000..547b6de5b --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/symmetry.cpp @@ -0,0 +1,165 @@ +/*1:*/ +#line 6 "./symmetry.cweb" + +#include "symmetry.h" +#include "permutation.h" + +#include + +/*2:*/ +#line 24 "./symmetry.cweb" + +Symmetry::Symmetry(const IntSequence&s) +:IntSequence(s.getNumDistinct(),0) +{ +int p= 0; +if(s.size()> 0) +operator[](p)= 1; +for(int i= 1;iisEnd()){ +delete subit; +delete subs; +s.sym()[0]++; +subs= new SymmetrySet(s,s.dimen()-s.sym()[0]); +subit= new symiterator(*subs); +} +} +if(s.sym()[0]==s.dimen()+1) +end_flag= true; +} +return*this; +} + +/*:7*/ +#line 17 "./symmetry.cweb" +; +/*8:*/ +#line 126 "./symmetry.cweb" + +InducedSymmetries::InducedSymmetries(const Equivalence&e,const Symmetry&s) +{ +for(Equivalence::const_seqit i= e.begin();i!=e.end();++i){ +push_back(Symmetry(s,*i)); +} +} + +/*:8*/ +#line 18 "./symmetry.cweb" +; +/*9:*/ +#line 135 "./symmetry.cweb" + +InducedSymmetries::InducedSymmetries(const Equivalence&e,const Permutation&p, +const Symmetry&s) +{ +for(int i= 0;i +#include + +/*2:*/ +#line 69 "./symmetry.hweb" + +class Symmetry:public IntSequence{ +public: +/*3:*/ +#line 93 "./symmetry.hweb" + +Symmetry(int len,const char*dummy) +:IntSequence(len,0){} +Symmetry(int i1) +:IntSequence(1,i1){} +Symmetry(int i1,int i2) +:IntSequence(2){operator[](0)= i1;operator[](1)= i2;} +Symmetry(int i1,int i2,int i3) +:IntSequence(3) +{ +operator[](0)= i1; +operator[](1)= i2; +operator[](2)= i3; +} +Symmetry(int i1,int i2,int i3,int i4) +:IntSequence(4) +{ +operator[](0)= i1; +operator[](1)= i2; +operator[](2)= i3; +operator[](3)= i4; +} +Symmetry(const Symmetry&s) +:IntSequence(s){} +Symmetry(const Symmetry&s,const OrdSequence&cl) +:IntSequence(s,cl.getData()){} +Symmetry(Symmetry&s,int len) +:IntSequence(s,s.size()-len,s.size()){} +Symmetry(const IntSequence&s); + +/*:3*/ +#line 72 "./symmetry.hweb" +; +int num()const +{return size();} +int dimen()const +{return sum();} +int findClass(int i)const; +bool isFull()const; +}; + +/*:2*/ +#line 59 "./symmetry.hweb" +; +/*4:*/ +#line 148 "./symmetry.hweb" + +class SymmetrySet{ +Symmetry run; +int dim; +public: +SymmetrySet(int d,int length) +:run(length,""),dim(d){} +SymmetrySet(SymmetrySet&s,int d) +:run(s.run,s.size()-1),dim(d){} +int dimen()const +{return dim;} +const Symmetry&sym()const +{return run;} +Symmetry&sym() +{return run;} +int size()const +{return run.size();} +}; + +/*:4*/ +#line 60 "./symmetry.hweb" +; +/*5:*/ +#line 177 "./symmetry.hweb" + +class symiterator{ +SymmetrySet&s; +symiterator*subit; +SymmetrySet*subs; +bool end_flag; +public: +symiterator(SymmetrySet&ss); +~symiterator(); +symiterator&operator++(); +bool isEnd()const +{return end_flag;} +const Symmetry&operator*()const +{return s.sym();} +}; + + +/*:5*/ +#line 61 "./symmetry.hweb" +; +/*6:*/ +#line 198 "./symmetry.hweb" + +class InducedSymmetries:public vector { +public: +InducedSymmetries(const Equivalence&e,const Symmetry&s); +InducedSymmetries(const Equivalence&e,const Permutation&p,const Symmetry&s); +void print()const; +}; + + + +/*:6*/ +#line 62 "./symmetry.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/t_container.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/t_container.cpp new file mode 100644 index 000000000..7db1aafbd --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/t_container.cpp @@ -0,0 +1,134 @@ +/*1:*/ +#line 6 "./t_container.cweb" + +#include "t_container.h" +#include "kron_prod.h" +#include "ps_tensor.h" +#include "pyramid_prod.h" + +const int FGSContainer::num_one_time= 10; +/*2:*/ +#line 21 "./t_container.cweb" + +UGSContainer::UGSContainer(const FGSContainer&c) +:TensorContainer (c.num()) +{ +for(FGSContainer::const_iterator it= c.begin(); +it!=c.end();++it){ +UGSTensor*unfolded= new UGSTensor(*((*it).second)); +insert(unfolded); +} +} + +/*:2*/ +#line 13 "./t_container.cweb" +; +/*3:*/ +#line 44 "./t_container.cweb" + +void UGSContainer::multAndAdd(const UGSTensor&t,UGSTensor&out)const +{ +int l= t.dimen(); +int k= out.dimen(); +const EquivalenceSet&eset= ebundle.get(k); + +for(EquivalenceSet::const_iterator it= eset.begin(); +it!=eset.end();++it){ +if((*it).numClasses()==l){ +vector ts= +fetchTensors(out.getSym(),*it); +KronProdAllOptim kp(l); +for(int i= 0;i (c.num()) +{ +for(UGSContainer::const_iterator it= c.begin(); +it!=c.end();++it){ +FGSTensor*folded= new FGSTensor(*((*it).second)); +insert(folded); +} +} + + +/*:4*/ +#line 15 "./t_container.cweb" +; +/*5:*/ +#line 81 "./t_container.cweb" + +void FGSContainer::multAndAdd(const FGSTensor&t,FGSTensor&out)const +{ +UGSTensor ut(t); +multAndAdd(ut,out); +} + +/*:5*/ +#line 16 "./t_container.cweb" +; +/*6:*/ +#line 92 "./t_container.cweb" + +void FGSContainer::multAndAdd(const UGSTensor&t,FGSTensor&out)const +{ +int l= t.dimen(); +int k= out.dimen(); +const EquivalenceSet&eset= ebundle.get(k); + +for(EquivalenceSet::const_iterator it= eset.begin(); +it!=eset.end();++it){ +if((*it).numClasses()==l){ +vector ts= +fetchTensors(out.getSym(),*it); +KronProdAllOptim kp(l); +for(int i= 0;i &out, +const Tensor::index&start, +const Tensor::index&end) +{ +out.clear(); +int i= 0; +Tensor::index run= start; +while(i + +/*2:*/ +#line 71 "./t_container.hweb" + +struct ltsym{ +bool operator()(const Symmetry&s1,const Symmetry&s2)const +{return s1 class TensorContainer{ +protected: +typedef const _Ttype*_const_ptr; +typedef _Ttype*_ptr; +typedef map _Map; +typedef typename _Map::value_type _mvtype; +public: +typedef typename _Map::iterator iterator; +typedef typename _Map::const_iterator const_iterator; +private: +int n; +_Map m; +protected: +const EquivalenceBundle&ebundle; +public: +TensorContainer(int nn) +:n(nn),ebundle(*(tls.ebundle)){} +/*5:*/ +#line 150 "./t_container.hweb" + +TensorContainer(const TensorContainer<_Ttype> &c) +:n(c.n),m(),ebundle(c.ebundle) +{ +for(const_iterator it= c.m.begin();it!=c.m.end();++it){ +_Ttype*ten= new _Ttype(*((*it).second)); +insert(ten); +} +} + +/*:5*/ +#line 115 "./t_container.hweb" +; +/*6:*/ +#line 163 "./t_container.hweb" + +TensorContainer(int first_row,int num,TensorContainer<_Ttype> &c) +:n(c.n),ebundle(*(tls.ebundle)) +{ +for(iterator it= c.m.begin();it!=c.m.end();++it){ +_Ttype*t= new _Ttype(first_row,num,*((*it).second)); +insert(t); +} +} + + +/*:6*/ +#line 116 "./t_container.hweb" +; +/*7:*/ +#line 175 "./t_container.hweb" + +_const_ptr get(const Symmetry&s)const +{ +TL_RAISE_IF(s.num()!=num(), +"Incompatible symmetry lookup in TensorContainer::get"); +const_iterator it= m.find(s); +if(it==m.end()){ +TL_RAISE("Symmetry not found in TensorContainer::get"); +return NULL; +}else{ +return(*it).second; +} +} + + +_ptr get(const Symmetry&s) +{ +TL_RAISE_IF(s.num()!=num(), +"Incompatible symmetry lookup in TensorContainer::get"); +iterator it= m.find(s); +if(it==m.end()){ +TL_RAISE("Symmetry not found in TensorContainer::get"); +return NULL; +}else{ +return(*it).second; +} +} + +/*:7*/ +#line 117 "./t_container.hweb" +; +/*8:*/ +#line 204 "./t_container.hweb" + +bool check(const Symmetry&s)const +{ +TL_RAISE_IF(s.num()!=num(), +"Incompatible symmetry lookup in TensorContainer::check"); +const_iterator it= m.find(s); +return it!=m.end(); +} + +/*:8*/ +#line 118 "./t_container.hweb" +; +/*9:*/ +#line 214 "./t_container.hweb" + +void insert(_ptr t) +{ +TL_RAISE_IF(t->getSym().num()!=num(), +"Incompatible symmetry insertion in TensorContainer::insert"); +TL_RAISE_IF(check(t->getSym()), +"Tensor already in container in TensorContainer::insert"); +m.insert(_mvtype(t->getSym(),t)); +if(!t->isFinite()){ +throw TLException(__FILE__,__LINE__,"NaN or Inf asserted in TensorContainer::insert"); +} +} + +/*:9*/ +#line 119 "./t_container.hweb" +; +/*10:*/ +#line 228 "./t_container.hweb" + +void remove(const Symmetry&s) +{ +iterator it= m.find(s); +if(it!=m.end()){ +_ptr t= (*it).second; +m.erase(it); +delete t; +} +} + + +/*:10*/ +#line 120 "./t_container.hweb" +; +/*11:*/ +#line 241 "./t_container.hweb" + +void clear() +{ +while(!m.empty()){ +delete(*(m.begin())).second; +m.erase(m.begin()); +} +} + +/*:11*/ +#line 121 "./t_container.hweb" +; +/*15:*/ +#line 299 "./t_container.hweb" + +vector<_const_ptr> +fetchTensors(const Symmetry&rsym,const Equivalence&e)const +{ +vector<_const_ptr> res(e.numClasses()); +int i= 0; +for(Equivalence::const_seqit it= e.begin(); +it!=e.end();++it,i++){ +Symmetry s(rsym,*it); +res[i]= get(s); +} +return res; +} + +/*:15*/ +#line 122 "./t_container.hweb" +; +/*12:*/ +#line 251 "./t_container.hweb" + +int getMaxDim()const +{ +int res= -1; +for(const_iterator run= m.begin();run!=m.end();++run){ +int dim= (*run).first.dimen(); +if(dim> res) +res= dim; +} +return res; +} + + +/*:12*/ +#line 123 "./t_container.hweb" +; +/*13:*/ +#line 265 "./t_container.hweb" + +void print()const +{ +printf("Tensor container: nvars=%d, tensors=%d\n",n,m.size()); +for(const_iterator it= m.begin();it!=m.end();++it){ +printf("Symmetry: "); +(*it).first.print(); +((*it).second)->print(); +} +} + +/*:13*/ +#line 124 "./t_container.hweb" +; +/*14:*/ +#line 277 "./t_container.hweb" + +void writeMat4(FILE*fd,const char*prefix)const +{ +for(const_iterator it= begin();it!=end();++it){ +char lname[100]; +sprintf(lname,"%s_g",prefix); +const Symmetry&sym= (*it).first; +for(int i= 0;i { +public: +UGSContainer(int nn) +:TensorContainer (nn){} +UGSContainer(const UGSContainer&uc) +:TensorContainer (uc){} +UGSContainer(const FGSContainer&c); +void multAndAdd(const UGSTensor&t,UGSTensor&out)const; +}; + + +/*:16*/ +#line 65 "./t_container.hweb" +; +/*17:*/ +#line 342 "./t_container.hweb" + +class FGSContainer:public TensorContainer { +static const int num_one_time; +public: +FGSContainer(int nn) +:TensorContainer (nn){} +FGSContainer(const FGSContainer&fc) +:TensorContainer (fc){} +FGSContainer(const UGSContainer&c); +void multAndAdd(const FGSTensor&t,FGSTensor&out)const; +void multAndAdd(const UGSTensor&t,FGSTensor&out)const; +private: +static Tensor::index +getIndices(int num,vector &out, +const Tensor::index&start, +const Tensor::index&end); +}; + + +/*:17*/ +#line 66 "./t_container.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/t_polynomial.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/t_polynomial.cpp new file mode 100644 index 000000000..2144f6bb3 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/t_polynomial.cpp @@ -0,0 +1,88 @@ +/*1:*/ +#line 6 "./t_polynomial.cweb" + +#include "t_polynomial.h" +#include "kron_prod.h" + +/*2:*/ +#line 20 "./t_polynomial.cweb" + +const URSingleTensor&PowerProvider::getNext(const URSingleTensor*dummy) +{ +if(ut){ +URSingleTensor*ut_new= new URSingleTensor(nv,ut->dimen()+1); +KronProd::kronMult(ConstVector(origv),ConstVector(ut->getData()),ut_new->getData()); +delete ut; +ut= ut_new; +}else{ +ut= new URSingleTensor(nv,1); +ut->getData()= origv; +} +return*ut; +} + +/*:2*/ +#line 10 "./t_polynomial.cweb" +; +/*3:*/ +#line 38 "./t_polynomial.cweb" + +const FRSingleTensor&PowerProvider::getNext(const FRSingleTensor*dummy) +{ +getNext(ut); +if(ft) +delete ft; +ft= new FRSingleTensor(*ut); +return*ft; +} + +/*:3*/ +#line 11 "./t_polynomial.cweb" +; +/*4:*/ +#line 49 "./t_polynomial.cweb" + +PowerProvider::~PowerProvider() +{ +if(ut) +delete ut; +if(ft) +delete ft; +} + +/*:4*/ +#line 12 "./t_polynomial.cweb" +; +/*5:*/ +#line 59 "./t_polynomial.cweb" + +UTensorPolynomial::UTensorPolynomial(const FTensorPolynomial&fp) +:TensorPolynomial (fp.nrows(),fp.nvars()) +{ +for(FTensorPolynomial::const_iterator it= fp.begin(); +it!=fp.end();++it){ +insert(new UFSTensor(*((*it).second))); +} +} + +/*:5*/ +#line 13 "./t_polynomial.cweb" +; +/*6:*/ +#line 70 "./t_polynomial.cweb" + +FTensorPolynomial::FTensorPolynomial(const UTensorPolynomial&up) +:TensorPolynomial (up.nrows(),up.nvars()) +{ +for(UTensorPolynomial::const_iterator it= up.begin(); +it!=up.end();++it){ +insert(new FFSTensor(*((*it).second))); +} +} + +/*:6*/ +#line 14 "./t_polynomial.cweb" +; + + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/t_polynomial.h b/mex/sources/korderpert/Dyn_pp/tl/cc/t_polynomial.h new file mode 100644 index 000000000..73ce41bca --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/t_polynomial.h @@ -0,0 +1,415 @@ +/*1:*/ +#line 47 "./t_polynomial.hweb" + +#include "t_container.h" +#include "fs_tensor.h" +#include "rfs_tensor.h" +#include"tl_static.h" + +/*2:*/ +#line 76 "./t_polynomial.hweb" + +class PowerProvider{ +Vector origv; +URSingleTensor*ut; +FRSingleTensor*ft; +int nv; +public: +PowerProvider(const ConstVector&v) +:origv(v),ut(NULL),ft(NULL),nv(v.length()){} +~PowerProvider(); +const URSingleTensor&getNext(const URSingleTensor*dummy); +const FRSingleTensor&getNext(const FRSingleTensor*dummy); +}; + +/*:2*/ +#line 53 "./t_polynomial.hweb" +; +/*3:*/ +#line 111 "./t_polynomial.hweb" + +template +class TensorPolynomial:public TensorContainer<_Ttype> { +int nr; +int nv; +int maxdim; +typedef TensorContainer<_Ttype> _Tparent; +typedef typename _Tparent::_ptr _ptr; +public: +TensorPolynomial(int rows,int vars) +:TensorContainer<_Ttype> (1), +nr(rows),nv(vars),maxdim(0){} +TensorPolynomial(const TensorPolynomial<_Ttype,_TGStype,_Stype> &tp,int k) +:TensorContainer<_Ttype> (tp), +nr(tp.nr),nv(tp.nv),maxdim(0){derivative(k);} +TensorPolynomial(int first_row,int num,TensorPolynomial<_Ttype,_TGStype,_Stype> &tp) +:TensorContainer<_Ttype> (first_row,num,tp), +nr(num),nv(tp.nv),maxdim(tp.maxdim){} +/*4:*/ +#line 162 "./t_polynomial.hweb" + +TensorPolynomial(const TensorPolynomial<_Ttype,_TGStype,_Stype> &tp,const Vector&xval) +:TensorContainer<_Ttype> (1), +nr(tp.nrows()),nv(tp.nvars()-xval.length()),maxdim(0) +{ +TL_RAISE_IF(nvars()<0, +"Length of xval too big in TensorPolynomial contract constructor"); +IntSequence ss(2);ss[0]= xval.length();ss[1]= nvars(); +IntSequence pp(2);pp[0]= 0;pp[1]= 1; + +/*5:*/ +#line 193 "./t_polynomial.hweb" + +PowerProvider pwp(xval); +for(int i= 1;i<=tp.maxdim;i++){ +const _Stype&xpow= pwp.getNext((const _Stype*)NULL); +for(int j= 0;j<=tp.maxdim-i;j++){ +if(tp.check(Symmetry(i+j))){ +/*7:*/ +#line 227 "./t_polynomial.hweb" + +_Ttype*ten; +if(_Tparent::check(Symmetry(j))){ +ten= _Tparent::get(Symmetry(j)); +}else{ +ten= new _Ttype(nrows(),nvars(),j); +ten->zeros(); +insert(ten); +} + + +/*:7*/ +#line 199 "./t_polynomial.hweb" +; +Symmetry sym(i,j); +IntSequence coor(sym,pp); +_TGStype slice(*(tp.get(Symmetry(i+j))),ss,coor,TensorDimens(sym,ss)); +slice.mult(Tensor::noverk(i+j,j)); +_TGStype tmp(*ten); +slice.contractAndAdd(0,tmp,xpow); +} +} +} + +/*:5*/ +#line 172 "./t_polynomial.hweb" +; +/*6:*/ +#line 214 "./t_polynomial.hweb" + +for(int j= 0;j<=tp.maxdim;j++){ +if(tp.check(Symmetry(j))){ +/*7:*/ +#line 227 "./t_polynomial.hweb" + +_Ttype*ten; +if(_Tparent::check(Symmetry(j))){ +ten= _Tparent::get(Symmetry(j)); +}else{ +ten= new _Ttype(nrows(),nvars(),j); +ten->zeros(); +insert(ten); +} + + +/*:7*/ +#line 217 "./t_polynomial.hweb" +; +Symmetry sym(0,j); +IntSequence coor(sym,pp); +_TGStype slice(*(tp.get(Symmetry(j))),ss,coor,TensorDimens(sym,ss)); +ten->add(1.0,slice); +} +} + + +/*:6*/ +#line 173 "./t_polynomial.hweb" +; +} + +/*:4*/ +#line 129 "./t_polynomial.hweb" +; +TensorPolynomial(const TensorPolynomial&tp) +:TensorContainer<_Ttype> (tp),nr(tp.nr),nv(tp.nv),maxdim(tp.maxdim){} +int nrows()const +{return nr;} +int nvars()const +{return nv;} +/*8:*/ +#line 242 "./t_polynomial.hweb" + +void evalTrad(Vector&out,const ConstVector&v)const +{ +if(_Tparent::check(Symmetry(0))) +out= _Tparent::get(Symmetry(0))->getData(); +else +out.zeros(); + +PowerProvider pp(v); +for(int d= 1;d<=maxdim;d++){ +const _Stype&p= pp.getNext((const _Stype*)NULL); +Symmetry cs(d); +if(_Tparent::check(cs)){ +const _Ttype*t= _Tparent::get(cs); +t->multaVec(out,p.getData()); +} +} +} + +/*:8*/ +#line 136 "./t_polynomial.hweb" +; +/*9:*/ +#line 264 "./t_polynomial.hweb" + +void evalHorner(Vector&out,const ConstVector&v)const +{ +if(_Tparent::check(Symmetry(0))) +out= _Tparent::get(Symmetry(0))->getData(); +else +out.zeros(); + +if(maxdim==0) +return; + +_Ttype*last; +if(maxdim==1) +last= new _Ttype(*(_Tparent::get(Symmetry(1)))); +else +last= new _Ttype(*(_Tparent::get(Symmetry(maxdim))),v); +for(int d= maxdim-1;d>=1;d--){ +Symmetry cs(d); +if(_Tparent::check(cs)){ +const _Ttype*nt= _Tparent::get(cs); +last->add(1.0,ConstTwoDMatrix(*nt)); +} +if(d> 1){ +_Ttype*new_last= new _Ttype(*last,v); +delete last; +last= new_last; +} +} +last->multaVec(out,v); +delete last; +} + +/*:9*/ +#line 137 "./t_polynomial.hweb" +; +/*10:*/ +#line 299 "./t_polynomial.hweb" + +void insert(_ptr t) +{ +TL_RAISE_IF(t->nrows()!=nr, +"Wrong number of rows in TensorPolynomial::insert"); +TL_RAISE_IF(t->nvar()!=nv, +"Wrong number of variables in TensorPolynomial::insert"); +TensorContainer<_Ttype> ::insert(t); +if(maxdimdimen()) +maxdim= t->dimen(); +} + +/*:10*/ +#line 138 "./t_polynomial.hweb" +; +/*11:*/ +#line 323 "./t_polynomial.hweb" + +void derivative(int k) +{ +for(int d= 1;d<=maxdim;d++){ +if(_Tparent::check(Symmetry(d))){ +_Ttype*ten= _Tparent::get(Symmetry(d)); +ten->mult((double)max((d-k),0)); +} +} +} + +/*:11*/ +#line 139 "./t_polynomial.hweb" +; +/*12:*/ +#line 345 "./t_polynomial.hweb" + +_Ttype*evalPartially(int s,const ConstVector&v) +{ +TL_RAISE_IF(v.length()!=nvars(), +"Wrong length of vector for TensorPolynomial::evalPartially"); + +_Ttype*res= new _Ttype(nrows(),nvars(),s); +res->zeros(); + +int sfac= 1; +for(int i= 1;i<=s;i++) +sfac*= i; + +if(_Tparent::check(Symmetry(s))) +res->add(1.0/sfac,*(_Tparent::get(Symmetry(s)))); + +int dfac= sfac*(s+1); +for(int d= s+1;d<=maxdim;d++,dfac*= d){ +if(_Tparent::check(Symmetry(d))){ +const _Ttype<mp= *(_Tparent::get(Symmetry(d))); +_Ttype*last= new _Ttype(ltmp); +for(int j= 0;jadd(1.0/dfac,*last); +delete last; +} +} + +return res; +} + +/*:12*/ +#line 140 "./t_polynomial.hweb" +; +}; + + +/*:3*/ +#line 54 "./t_polynomial.hweb" +; +/*13:*/ +#line 380 "./t_polynomial.hweb" + +class FTensorPolynomial; +class UTensorPolynomial:public TensorPolynomial { +public: +UTensorPolynomial(int rows,int vars) +:TensorPolynomial (rows,vars){} +UTensorPolynomial(const UTensorPolynomial&up,int k) +:TensorPolynomial (up,k){} +UTensorPolynomial(const FTensorPolynomial&fp); +UTensorPolynomial(const UTensorPolynomial&tp,const Vector&xval) +:TensorPolynomial (tp,xval){} +UTensorPolynomial(int first_row,int num,UTensorPolynomial&tp) +:TensorPolynomial (first_row,num,tp){} +}; + +/*:13*/ +#line 55 "./t_polynomial.hweb" +; +/*14:*/ +#line 396 "./t_polynomial.hweb" + +class FTensorPolynomial:public TensorPolynomial { +public: +FTensorPolynomial(int rows,int vars) +:TensorPolynomial (rows,vars){} +FTensorPolynomial(const FTensorPolynomial&fp,int k) +:TensorPolynomial (fp,k){} +FTensorPolynomial(const UTensorPolynomial&up); +FTensorPolynomial(const FTensorPolynomial&tp,const Vector&xval) +:TensorPolynomial (tp,xval){} +FTensorPolynomial(int first_row,int num,FTensorPolynomial&tp) +:TensorPolynomial (first_row,num,tp){} +}; + +/*:14*/ +#line 56 "./t_polynomial.hweb" +; +/*15:*/ +#line 414 "./t_polynomial.hweb" + +template +class CompactPolynomial:public _Ttype{ +public: +/*16:*/ +#line 434 "./t_polynomial.hweb" + +CompactPolynomial(const TensorPolynomial<_Ttype,_TGStype,_Stype> &pol) +:_Ttype(pol.nrows(),pol.nvars()+1,pol.getMaxDim()) +{ +_Ttype::zeros(); + +IntSequence dumnvs(2); +dumnvs[0]= 1; +dumnvs[1]= pol.nvars(); + +int offset= 0; +_Ttype dum(0,2,_Ttype::dimen()); +for(Tensor::index i= dum.begin();i!=dum.end();++i){ +int d= i.getCoor().sum(); +Symmetry symrun(_Ttype::dimen()-d,d); +_TGStype dumgs(0,TensorDimens(symrun,dumnvs)); +if(pol.check(Symmetry(d))){ +TwoDMatrix subt(*this,offset,dumgs.ncols()); +subt.add(1.0,*(pol.get(Symmetry(d)))); +} +offset+= dumgs.ncols(); +} +} + + +/*:16*/ +#line 418 "./t_polynomial.hweb" +; +/*17:*/ +#line 463 "./t_polynomial.hweb" + +void eval(Vector&out,const ConstVector&v)const +{ +TL_RAISE_IF(v.length()+1!=_Ttype::nvar(), +"Wrong input vector length in CompactPolynomial::eval"); +TL_RAISE_IF(out.length()!=_Ttype::nrows(), +"Wrong output vector length in CompactPolynomial::eval"); + +Vector x1(v.length()+1); +Vector x1p(x1,1,v.length()); +x1p= v; +x1[0]= 1.0; + +if(_Ttype::dimen()==0) +out= ConstVector(*this,0); +else{ +PowerProvider pp(x1); +const _Stype&xpow= pp.getNext((const _Stype*)NULL); +for(int i= 1;i<_Ttype::dimen();i++) +xpow= pp.getNext((const _Stype*)NULL); +multVec(0.0,out,1.0,xpow); +} +} + +/*:17*/ +#line 419 "./t_polynomial.hweb" +; +}; + +/*:15*/ +#line 57 "./t_polynomial.hweb" +; +/*18:*/ +#line 488 "./t_polynomial.hweb" + +class UCompactPolynomial:public CompactPolynomial { +public: +UCompactPolynomial(const UTensorPolynomial&upol) +:CompactPolynomial (upol){} +}; + +/*:18*/ +#line 58 "./t_polynomial.hweb" +; +/*19:*/ +#line 496 "./t_polynomial.hweb" + +class FCompactPolynomial:public CompactPolynomial { +public: +FCompactPolynomial(const FTensorPolynomial&fpol) +:CompactPolynomial (fpol){} +}; + + + +/*:19*/ +#line 59 "./t_polynomial.hweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/tensor.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/tensor.cpp new file mode 100644 index 000000000..6fdcb2cad --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/tensor.cpp @@ -0,0 +1,184 @@ +/*1:*/ +#line 6 "./tensor.cweb" + +#include "tensor.h" +#include "tl_exception.h" +#include "tl_static.h" + +/*2:*/ +#line 27 "./tensor.cweb" + +int Tensor::noverk(int n,int k) +{ +return tls.ptriang->noverk(n,k); +} + +int Tensor::power(int a,int b) +{ +int res= 1; +for(int i= 0;i 0&&v[i]==nv){ +v[i]= 0; +v[--i]++; +} +} + +/*:4*/ +#line 13 "./tensor.cweb" +; +/*5:*/ +#line 80 "./tensor.cweb" + +void UTensor::decrement(IntSequence&v,int nv) +{ +if(v.size()==0) +return; +int i= v.size()-1; +v[i]--; +while(i> 0&&v[i]==-1){ +v[i]= nv-1; +v[--i]--; +} +} + +/*:5*/ +#line 14 "./tensor.cweb" +; +/*6:*/ +#line 99 "./tensor.cweb" + +void UTensor::increment(IntSequence&v,const IntSequence&nvmx) +{ +if(v.size()==0) +return; +int i= v.size()-1; +v[i]++; +while(i> 0&&v[i]==nvmx[i]){ +v[i]= 0; +v[--i]++; +} +} + +/*:6*/ +#line 15 "./tensor.cweb" +; +/*7:*/ +#line 115 "./tensor.cweb" + +void UTensor::decrement(IntSequence&v,const IntSequence&nvmx) +{ +if(v.size()==0) +return; +int i= v.size()-1; +v[i]--; +while(i> 0&&v[i]==-1){ +v[i]= nvmx[i]-1; +v[--i]--; +} +} + +/*:7*/ +#line 16 "./tensor.cweb" +; +/*8:*/ +#line 131 "./tensor.cweb" + +int UTensor::getOffset(const IntSequence&v,int nv) +{ +int pow= 1; +int res= 0; +for(int i= v.size()-1;i>=0;i--){ +res+= v[i]*pow; +pow*= nv; +} +return res; +} + +/*:8*/ +#line 17 "./tensor.cweb" +; +/*9:*/ +#line 144 "./tensor.cweb" + +int UTensor::getOffset(const IntSequence&v,const IntSequence&nvmx) +{ +int pow= 1; +int res= 0; +for(int i= v.size()-1;i>=0;i--){ +res+= v[i]*pow; +pow*= nvmx[i]; +} +return res; +} + + +/*:9*/ +#line 18 "./tensor.cweb" +; +/*10:*/ +#line 164 "./tensor.cweb" + +void FTensor::decrement(IntSequence&v,int nv) +{ +int i= v.size()-1; +while(i> 0&&v[i-1]==v[i]) +i--; +v[i]--; +for(int j= i+1;j class _index{ +typedef _index<_Tptr> _Self; +_Tptr tensor; +int offset; +IntSequence coor; +public: +_index(_Tptr t,int n) +:tensor(t),offset(0),coor(n,0){} +_index(_Tptr t,const IntSequence&cr,int c) +:tensor(t),offset(c),coor(cr){} +_index(_Tptr t,const IntSequence&cr) +:tensor(t),offset(tensor->getOffset(cr)),coor(cr){} +_index(const _index&ind) +:tensor(ind.tensor),offset(ind.offset),coor(ind.coor){} +const _Self&operator= (const _Self&in) +{tensor= in.tensor;offset= in.offset;coor= in.coor; +return*this;} +_Self&operator++() +{tensor->increment(coor);offset++;return*this;} +_Self&operator--() +{tensor->decrement(coor);offset--;return*this;} +int operator*()const +{return offset;} +bool operator==(const _index&n)const +{return offset==n.offset;} +bool operator!=(const _index&n)const +{return offset!=n.offset;} +const IntSequence&getCoor()const +{return coor;} +void print()const +{printf("%4d: ",offset);coor.print();} +}; + +/*:2*/ +#line 55 "./tensor.hweb" +; +/*3:*/ +#line 143 "./tensor.hweb" + +class Tensor:public TwoDMatrix{ +public: +enum indor{along_row,along_col}; +typedef _index index; +protected: +const index in_beg; +const index in_end; +int dim; +public: +Tensor(indor io,const IntSequence&last,int r,int c,int d) +:TwoDMatrix(r,c), +in_beg(this,d), +in_end(this,last,(io==along_row)?r:c), +dim(d){} +Tensor(indor io,const IntSequence&first,const IntSequence&last, +int r,int c,int d) +:TwoDMatrix(r,c), +in_beg(this,first,0), +in_end(this,last,(io==along_row)?r:c), +dim(d){} +Tensor(int first_row,int num,Tensor&t) +:TwoDMatrix(first_row,num,t), +in_beg(t.in_beg), +in_end(t.in_end), +dim(t.dim){} +Tensor(const Tensor&t) +:TwoDMatrix(t), +in_beg(this,t.in_beg.getCoor(),*(t.in_beg)), +in_end(this,t.in_end.getCoor(),*(t.in_end)), +dim(t.dim){} +virtual~Tensor(){} +virtual void increment(IntSequence&v)const= 0; +virtual void decrement(IntSequence&v)const= 0; +virtual int getOffset(const IntSequence&v)const= 0; +int dimen()const +{return dim;} + +const index&begin()const +{return in_beg;} +const index&end()const +{return in_end;} + +static int noverk(int n,int k); +static int power(int a,int b); +static int noverseq(const IntSequence&s) +{ +IntSequence seq(s); +return noverseq_ip((IntSequence&)s); +} +private: +static int noverseq_ip(IntSequence&s); +}; + +/*:3*/ +#line 56 "./tensor.hweb" +; +/*4:*/ +#line 203 "./tensor.hweb" + +class FTensor; +class UTensor:public Tensor{ +public: +UTensor(indor io,const IntSequence&last,int r,int c,int d) +:Tensor(io,last,r,c,d){} +UTensor(const UTensor&ut) +:Tensor(ut){} +UTensor(int first_row,int num,UTensor&t) +:Tensor(first_row,num,t){} +virtual~UTensor(){} +virtual FTensor&fold()const= 0; + +static void increment(IntSequence&v,int nv); +static void decrement(IntSequence&v,int nv); +static void increment(IntSequence&v,const IntSequence&nvmx); +static void decrement(IntSequence&v,const IntSequence&nvmx); +static int getOffset(const IntSequence&v,int nv); +static int getOffset(const IntSequence&v,const IntSequence&nvmx); +}; + +/*:4*/ +#line 57 "./tensor.hweb" +; +/*5:*/ +#line 233 "./tensor.hweb" + +class FTensor:public Tensor{ +public: +FTensor(indor io,const IntSequence&last,int r,int c,int d) +:Tensor(io,last,r,c,d){} +FTensor(const FTensor&ft) +:Tensor(ft){} +FTensor(int first_row,int num,FTensor&t) +:Tensor(first_row,num,t){} +virtual~FTensor(){} +virtual UTensor&unfold()const= 0; + +static void decrement(IntSequence&v,int nv); +static int getOffset(const IntSequence&v,int nv) +{IntSequence vtmp(v);return getOffsetRecurse(vtmp,nv);} +private: +static int getOffsetRecurse(IntSequence&v,int nv); +}; + +/*:5*/ +#line 58 "./tensor.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/tl_exception.h b/mex/sources/korderpert/Dyn_pp/tl/cc/tl_exception.h new file mode 100644 index 000000000..69fe4e82e --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/tl_exception.h @@ -0,0 +1,57 @@ +/*1:*/ +#line 14 "./tl_exception.hweb" + +#ifndef TL_EXCEPTION_H +#define TL_EXCEPTION_H + +#include +#include + +/*2:*/ +#line 43 "./tl_exception.hweb" + +#ifndef TL_DEBUG_EXCEPTION +#define TL_DEBUG_EXCEPTION 1 +#endif + +#ifndef TL_DEBUG +#define TL_DEBUG 0 +#endif + +#define TL_RAISE(mes) \ +if (TL_DEBUG >= TL_DEBUG_EXCEPTION) throw TLException(__FILE__, __LINE__, mes); + +#define TL_RAISE_IF(expr, mes) \ +if (TL_DEBUG >= TL_DEBUG_EXCEPTION && (expr)) throw TLException(__FILE__, __LINE__, mes); + +/*3:*/ +#line 61 "./tl_exception.hweb" + +class TLException{ +char fname[50]; +int lnum; +char message[500]; +public: +TLException(const char*f,int l,const char*mes) +{ +strncpy(fname,f,50);fname[49]= '\0'; +strncpy(message,mes,500);message[499]= '\0'; +lnum= l; +} +virtual~TLException(){} +virtual void print()const +{printf("At %s:%d:%s\n",fname,lnum,message);} +}; + + +/*:3*/ +#line 58 "./tl_exception.hweb" +; + +/*:2*/ +#line 21 "./tl_exception.hweb" +; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/tl_static.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/tl_static.cpp new file mode 100644 index 000000000..b4afee32e --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/tl_static.cpp @@ -0,0 +1,88 @@ +/*1:*/ +#line 5 "./tl_static.cweb" + +#include "tl_static.h" +#include "tl_exception.h" + +TLStatic tls; +/*2:*/ +#line 17 "./tl_static.cweb" + +TLStatic::TLStatic() +{ +ebundle= NULL; +pbundle= NULL; +ptriang= NULL; +} + +TLStatic::~TLStatic() +{ +if(ebundle) +delete ebundle; +if(pbundle) +delete pbundle; +if(ptriang) +delete ptriang; +} + +void TLStatic::init(int dim,int nvar) +{ +if(ebundle) +ebundle->generateUpTo(dim); +else +ebundle= new EquivalenceBundle(dim); + +if(pbundle) +pbundle->generateUpTo(dim); +else +pbundle= new PermutationBundle(dim); + +if(ptriang) +delete ptriang; +ptriang= new PascalTriangle(nvar,dim); +} + +/*:2*/ +#line 10 "./tl_static.cweb" +; +/*3:*/ +#line 59 "./tl_static.cweb" + +PascalTriangle::PascalTriangle(int n,int k) +:data(new int[(n+1)*(k+1)]),kmax(k),nmax(n) +{ +for(int i= 0;i<=n;i++) +data[i]= 1; +for(int j= 1;j<=k;j++){ +data[j*(nmax+1)]= 1; +for(int i= 1;i<=n;i++) +data[j*(nmax+1)+i]= noverk(i+j-1,j)+noverk(i+j-1,j-1); +} +} + +/*:3*/ +#line 11 "./tl_static.cweb" +; +/*4:*/ +#line 73 "./tl_static.cweb" + +int PascalTriangle::noverk(int n,int k)const +{ +TL_RAISE_IF(k> n||n<0, +"Wrong arguments for PascalTriangle::noverk"); + +if(k<=kmax&&n-k<=nmax) +return data[k*(nmax+1)+n-k]; + +if(n-k<=kmax&&k<=nmax) +return data[(n-k)*(nmax+1)+k]; + +TL_RAISE("n or k out of range in PascalTriangle::noverk"); +return 0; +} + +/*:4*/ +#line 12 "./tl_static.cweb" +; + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/tl_static.h b/mex/sources/korderpert/Dyn_pp/tl/cc/tl_static.h new file mode 100644 index 000000000..49a9d3bd5 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/tl_static.h @@ -0,0 +1,49 @@ +/*1:*/ +#line 19 "./tl_static.hweb" + +#ifndef TL_STATIC_H +#define TL_STATIC_H + +#include "equivalence.h" +#include "permutation.h" + +/*2:*/ +#line 36 "./tl_static.hweb" + +class PascalTriangle{ +int*data; +int kmax; +int nmax; +public: +PascalTriangle(int n,int k); +~PascalTriangle() +{delete[]data;} +int noverk(int n,int k)const; +}; + + +/*:2*/ +#line 26 "./tl_static.hweb" +; +/*3:*/ +#line 50 "./tl_static.hweb" + +struct TLStatic{ +EquivalenceBundle*ebundle; +PermutationBundle*pbundle; +PascalTriangle*ptriang; + +TLStatic(); +~TLStatic(); +void init(int dim,int nvar); +}; + + +/*:3*/ +#line 27 "./tl_static.hweb" +; +extern TLStatic tls; + +#endif + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/cc/twod_matrix.cpp b/mex/sources/korderpert/Dyn_pp/tl/cc/twod_matrix.cpp new file mode 100644 index 000000000..fed691a44 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/cc/twod_matrix.cpp @@ -0,0 +1,159 @@ +/*1:*/ +#line 5 "./twod_matrix.cweb" + +#include "twod_matrix.h" +#include "tl_exception.h" + + +/*2:*/ +#line 20 "./twod_matrix.cweb" + +ConstTwoDMatrix::ConstTwoDMatrix(const TwoDMatrix&m) +:ConstGeneralMatrix(m){} + +ConstTwoDMatrix::ConstTwoDMatrix(const TwoDMatrix&m,int first_col,int num) +:ConstGeneralMatrix(m,0,first_col,m.nrows(),num){} + +ConstTwoDMatrix::ConstTwoDMatrix(const ConstTwoDMatrix&m,int first_col,int num) +:ConstGeneralMatrix(m,0,first_col,m.nrows(),num){} + +ConstTwoDMatrix::ConstTwoDMatrix(int first_row,int num,const TwoDMatrix&m) +:ConstGeneralMatrix(m,first_row,0,num,m.ncols()){} + +ConstTwoDMatrix::ConstTwoDMatrix(int first_row,int num,const ConstTwoDMatrix&m) +:ConstGeneralMatrix(m,first_row,0,num,m.ncols()){} + +/*:2*/ +#line 10 "./twod_matrix.cweb" +; +/*3:*/ +#line 37 "./twod_matrix.cweb" + +void ConstTwoDMatrix::writeMat4(FILE*fd,const char*vname)const +{ +Mat4Header header(*this,vname); +header.write(fd); +for(int j= 0;j + +class TwoDMatrix; +/*2:*/ +#line 43 "./twod_matrix.hweb" + +class ConstTwoDMatrix:public ConstGeneralMatrix{ +public: +ConstTwoDMatrix(int m,int n,const double*d) +:ConstGeneralMatrix(d,m,n){} +ConstTwoDMatrix(const TwoDMatrix&m); +ConstTwoDMatrix(const TwoDMatrix&m,int first_col,int num); +ConstTwoDMatrix(const ConstTwoDMatrix&m,int first_col,int num); +ConstTwoDMatrix(int first_row,int num,const TwoDMatrix&m); +ConstTwoDMatrix(int first_row,int num,const ConstTwoDMatrix&m); +ConstTwoDMatrix(const ConstTwoDMatrix&m,int first_row,int first_col,int rows,int cols) +:ConstGeneralMatrix(m,first_row,first_col,rows,cols){} +virtual~ConstTwoDMatrix(){} + +int nrows()const +{return numRows();} +int ncols()const +{return numCols();} +void writeMat4(FILE*fd,const char*vname)const; +}; + +/*:2*/ +#line 32 "./twod_matrix.hweb" +; +/*3:*/ +#line 70 "./twod_matrix.hweb" + +class TwoDMatrix:public GeneralMatrix{ +public: +TwoDMatrix(int r,int c) +:GeneralMatrix(r,c){} +TwoDMatrix(int r,int c,double*d) +:GeneralMatrix(d,r,c){} +TwoDMatrix(int r,int c,const double*d) +:GeneralMatrix(d,r,c){} +TwoDMatrix(const GeneralMatrix&m) +:GeneralMatrix(m){} +TwoDMatrix(const GeneralMatrix&m,char*dummy) +:GeneralMatrix(m,dummy){} +TwoDMatrix(const TwoDMatrix&m,int first_col,int num) +:GeneralMatrix(m,0,first_col,m.numRows(),num){} +TwoDMatrix(TwoDMatrix&m,int first_col,int num) +:GeneralMatrix(m,0,first_col,m.numRows(),num){} +TwoDMatrix(int first_row,int num,const TwoDMatrix&m) +:GeneralMatrix(m,first_row,0,num,m.ncols()){} +TwoDMatrix(int first_row,int num,TwoDMatrix&m) +:GeneralMatrix(m,first_row,0,num,m.ncols()){} +TwoDMatrix(TwoDMatrix&m,int first_row,int first_col,int rows,int cols) +:GeneralMatrix(m,first_row,first_col,rows,cols){} +TwoDMatrix(const TwoDMatrix&m,int first_row,int first_col,int rows,int cols) +:GeneralMatrix(m,first_row,first_col,rows,cols){} +TwoDMatrix(const ConstTwoDMatrix&a,const ConstTwoDMatrix&b) +:GeneralMatrix(a,b){} +virtual~TwoDMatrix(){} + +int nrows()const +{return numRows();} +int ncols()const +{return numCols();} + +/*4:*/ +#line 112 "./twod_matrix.hweb" + +void copyRow(int from,int to); +void copyRow(const ConstTwoDMatrix&m,int from,int to); +void copyRow(const TwoDMatrix&m,int from,int to) +{copyRow(ConstTwoDMatrix(m),from,to);} +void addRow(const ConstTwoDMatrix&m,int from,int to) +{addRow(1.0,m,from,to);} +void addRow(const TwoDMatrix&m,int from,int to) +{addRow(1.0,ConstTwoDMatrix(m),from,to);} +void addRow(double d,const ConstTwoDMatrix&m,int from,int to); +void addRow(double d,const TwoDMatrix&m,int from,int to) +{addRow(d,ConstTwoDMatrix(m),from,to);} + + +/*:4*/ +#line 104 "./twod_matrix.hweb" +; +/*5:*/ +#line 127 "./twod_matrix.hweb" + +void copyColumn(int from,int to); +void copyColumn(const ConstTwoDMatrix&m,int from,int to); +void copyColumn(const TwoDMatrix&m,int from,int to) +{copyColumn(ConstTwoDMatrix(m),from,to);} +void addColumn(const ConstTwoDMatrix&m,int from,int to) +{addColumn(1.0,ConstTwoDMatrix(m),from,to);} +void addColumn(const TwoDMatrix&m,int from,int to) +{addColumn(1.0,ConstTwoDMatrix(m),from,to);} +void addColumn(double d,const ConstTwoDMatrix&m,int from,int to); +void addColumn(double d,const TwoDMatrix&m,int from,int to) +{addColumn(d,ConstTwoDMatrix(m),from,to);} + +/*:5*/ +#line 105 "./twod_matrix.hweb" +; +void save(const char*fname)const; +void writeMat4(FILE*fd,const char*vname)const +{ConstTwoDMatrix(*this).writeMat4(fd,vname);} +}; + +/*:3*/ +#line 33 "./twod_matrix.hweb" +; +/*6:*/ +#line 141 "./twod_matrix.hweb" + +class Mat4Header{ +int type; +int rows; +int cols; +int imagf; +int namelen; +const char*vname; +public: +Mat4Header(const ConstTwoDMatrix&m,const char*vname); +Mat4Header(const ConstTwoDMatrix&m,const char*vname,const char*dummy); +void write(FILE*fd)const; +}; + + + +/*:6*/ +#line 34 "./twod_matrix.hweb" +; + +#endif + + +/*:1*/ diff --git a/mex/sources/korderpert/Dyn_pp/tl/testing/Makefile b/mex/sources/korderpert/Dyn_pp/tl/testing/Makefile new file mode 100644 index 000000000..2787b991f --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/testing/Makefile @@ -0,0 +1,44 @@ +# $Id: Makefile 843 2006-07-28 08:54:19Z tamas $ +# Copyright 2004, Ondra Kamenik + + +LD_LIBS := -llapack -lcblas -lf77blas -latlas -lg2c -lpthread +CC_FLAGS := -Wall -I../cc -I../../sylv/cc \ + $(CC_INCLUDE_PATH) +ifeq ($(DEBUG),yes) + CC_FLAGS := $(CC_FLAGS) -g -DTL_DEBUG=2 +else + CC_FLAGS := $(CC_FLAGS) -O2 -DPOSIX_THREADS +endif + +matrix_interface := GeneralMatrix Vector SylvException +matobjs := $(patsubst %, ../../sylv/cc/%.o, $(matrix_interface)) +cwebsource := $(wildcard ../cc/*.cweb) +cppsource := $(patsubst %.cweb,%.cpp,$(cwebsource)) +objects := $(patsubst %.cweb,%.o,$(cwebsource)) +hwebsource := $(wildcard ../cc/*.hweb) +hsource := $(patsubst %.hweb,%.h,$(hwebsource)) + +../cc/dummy.ch: + make -C ../cc dummy.ch + +../cc/%.cpp: ../cc/%.cweb ../cc/dummy.ch + make -C ../cc $*.cpp + +../cc/%.h: ../cc/%.hweb ../cc/dummy.ch + make -C ../cc $*.h + +../cc/%.o: ../cc/%.cpp $(hsource) + make -C ../cc $*.o + +%.o: %.cpp factory.h monoms.h $(hwebsource) $(hsource) + $(CC) $(CC_FLAGS) -c $*.cpp + +tests: $(hwebsource) $(cwebsoure) $(hsource) $(cppsource) \ + tests.o factory.o monoms.o $(objects) + $(CC) $(CC_FLAGS) $(objects) $(matobjs) tests.o factory.o monoms.o -o tests $(LD_LIBS) + +clear: + rm -f *.o + rm -f tests + make -C ../cc clear diff --git a/mex/sources/korderpert/Dyn_pp/tl/testing/factory.cpp b/mex/sources/korderpert/Dyn_pp/tl/testing/factory.cpp new file mode 100644 index 000000000..3eca85bf6 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/testing/factory.cpp @@ -0,0 +1,48 @@ +/* $Id: factory.cpp 148 2005-04-19 15:12:26Z kamenik $ */ +/* Copyright 2004, Ondra Kamenik */ + +#include "factory.h" + +#include + +void Factory::init(const Symmetry& s, const IntSequence& nvs) +{ + IntSequence sym(s); + long int seed = sym[0]; + seed = 256*seed + nvs[0]; + if (sym.size() > 1) + seed = 256*seed + sym[1]; + if (nvs.size() > 1) + seed = 256*seed + nvs[0]; + srand48(seed); +} + +void Factory::init(int dim, int nv) +{ + long int seed = dim; + seed = 256*seed + nv; + srand48(seed); +} + +double Factory::get() const +{ + return 1.0*(drand48()-0.5); +} + +void Factory::fillMatrix(TwoDMatrix& m) const +{ + Vector& d = m.getData(); + for (int i = 0; i < d.length(); i++) + d[i] = get(); +} + +Vector* Factory::makeVector(int n) +{ + init(n, n*n); + + Vector* v = new Vector(n); + for (int i = 0; i < n; i++) + (*v)[i] = get(); + + return v; +} diff --git a/mex/sources/korderpert/Dyn_pp/tl/testing/factory.h b/mex/sources/korderpert/Dyn_pp/tl/testing/factory.h new file mode 100644 index 000000000..fea223011 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/testing/factory.h @@ -0,0 +1,81 @@ +/* $Id: factory.h 148 2005-04-19 15:12:26Z kamenik $ */ +/* Copyright 2004, Ondra Kamenik */ + +#ifndef FACTORY_H +#define FACTORY_H + +#include "symmetry.h" +#include "int_sequence.h" +#include "twod_matrix.h" +#include "equivalence.h" +#include "rfs_tensor.h" +#include "t_container.h" + +class Factory { + void init(const Symmetry& s, const IntSequence& nvs); + void init(int dim, int nv); + void fillMatrix(TwoDMatrix& m) const; +public: + double get() const; + // this can be used with UGSTensor, FGSTensor + template + _Ttype* make(int r, const Symmetry& s, const IntSequence& nvs) + { + _Ttype* res = new _Ttype(r, TensorDimens(s, nvs)); + init(s, nvs); + fillMatrix(*res); + return res; + } + + // this can be used with FFSTensor, UFSTensor, FRTensor, URTensor + template + _Ttype* make(int r, int nv, int dim) + { + _Ttype* res = new _Ttype(r, nv, dim); + init(dim, nv); + fillMatrix(*res); + return res; + } + + template + _Ctype* makeCont(int r, const IntSequence& nvs, int maxdim) + { + int symnum = nvs.size(); + _Ctype* res = new _Ctype(symnum); + for (int dim = 1; dim <= maxdim; dim++) { + if (symnum == 1) { + // full symmetry + Symmetry sym(dim); + _Ttype* t = make<_Ttype>(r, sym, nvs); + res->insert(t); + } else { + // general symmetry + for (int i = 0; i <= dim; i++) { + Symmetry sym(i, dim-i); + _Ttype* t = make<_Ttype>(r, sym, nvs); + res->insert(t); + } + } + } + return res; + } + + template + _Ptype* makePoly(int r, int nv, int maxdim) + { + _Ptype* p = new _Ptype(r, nv); + for (int d = 1; d <= maxdim; d++) { + _Ttype* t = make<_Ttype>(r, nv, d); + p->insert(t); + } + return p; + } + + Vector* makeVector(int n); +}; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/tl/testing/monoms.cpp b/mex/sources/korderpert/Dyn_pp/tl/testing/monoms.cpp new file mode 100644 index 000000000..b0b096156 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/testing/monoms.cpp @@ -0,0 +1,490 @@ +/* $Id: monoms.cpp 148 2005-04-19 15:12:26Z kamenik $ */ +/* Copyright 2004, Ondra Kamenik */ + +#include "monoms.h" +#include "tl_exception.h" +#include "fs_tensor.h" + +#include +#include + +IntGenerator intgen; + +void IntGenerator::init(int nf, int ny, int nv, int nw, int nu, + int mx, double prob) +{ + maxim = mx; + probab = prob; + long int seed = nf; + seed = 256*seed + ny; + seed = 256*seed + nv; + seed = 256*seed + nw; + seed = 256*seed + nu; + srand48(seed); +} + +int IntGenerator::get() const +{ + double d = drand48(); + int num_inter = (int)( ((double)2*maxim)/(1.0-probab)); + int num_zero_inter = num_inter - 2*maxim; + if (d < ((double)num_zero_inter)/num_inter) + return 0; + return (int)(d*num_inter)-num_zero_inter-maxim; +} + +Monom::Monom(int len) + : IntSequence(len) +{ + for (int i = 0; i < len; i++) + operator[](i) = intgen.get(); +} + +Monom::Monom(int len, int item) + : IntSequence(len, item) +{ +} + +double Monom::deriv(const IntSequence& vars) const +{ + double res = 1.0; + int first_same_i = 0; + for (int i = 0; i < vars.size(); i++) { + TL_RAISE_IF(vars[i] < 0 || vars[i] >= size(), + "Wrong variable index in Monom::deriv"); + if (vars[i] != vars[first_same_i]) + first_same_i = i; + int mult = operator[](vars[i]) - (i-first_same_i); + if (mult == 0) + return 0; + res *= mult; + } + return res; +} + +void Monom::multiplyWith(int ex, const Monom& m) +{ + TL_RAISE_IF(size() != m.size(), + "Wrong sizes of monoms in Monom::multiplyWith"); + if (ex == 0) + return; + for (int i = 0; i < size(); i++) + operator[](i) += m[i]*ex; +} + +void Monom::print() const +{ + printf("["); + for (int i = 0; i < size(); i++) + printf("%3d", operator[](i)); + printf("]"); +} + +Monom1Vector::Monom1Vector(int nxx, int l) + : nx(nxx), len(l), x(new (Monom*)[len]) +{ + for (int i = 0; i < len; i++) { + x[i] = new Monom(nx); + } +} + +Monom1Vector::~Monom1Vector() +{ + for (int i = 0; i < len; i++) { + delete x[i]; + } + delete [] x; +} + +void Monom1Vector::deriv(const IntSequence& c, Vector& out) const +{ + TL_RAISE_IF(out.length() != len, + "Wrong length of output vector in Monom1Vector::deriv"); + + for (int i = 0; i < len; i++) { + out[i] = x[i]->deriv(c); + } +} + + +FGSTensor* Monom1Vector::deriv(int dim) const +{ + FGSTensor* res = + new FGSTensor(len, TensorDimens(Symmetry(dim), IntSequence(1, nx))); + for (Tensor::index it = res->begin(); it != res->end(); ++it) { + Vector outcol(*res, *it); + deriv(it.getCoor(), outcol); + } + return res; +} + +void Monom1Vector::print() const +{ + printf("Variables: x(%d)\n", nx); + printf("Rows: %d\n", len); + for (int i = 0; i < len; i++) { + printf("%2d: ", i); + x[i]->print(); + printf("\n"); + } +} + +Monom2Vector::Monom2Vector(int nyy, int nuu, int l) + : ny(nyy), nu(nuu), len(l), y(new (Monom*)[len]), u(new (Monom*)[len]) +{ + for (int i = 0; i < len; i++) { + y[i] = new Monom(ny); + u[i] = new Monom(nu); + } +} + +Monom2Vector::Monom2Vector(const Monom1Vector& g, const Monom2Vector& xmon) + : ny(xmon.ny), nu(xmon.nu), len(g.len), + y(new (Monom*)[len]), u(new (Monom*)[len]) +{ + TL_RAISE_IF(xmon.len != g.nx, + "Wrong number of x's in Monom2Vector constructor"); + + for (int i = 0; i < len; i++) { + y[i] = new Monom(ny, 0); + u[i] = new Monom(nu, 0); + } + + for (int i = 0; i < len; i++) { + // multiply from xmon + for (int j = 0; j < g.nx; j++) { + int ex = g.x[i]->operator[](j); + y[i]->multiplyWith(ex, *(xmon.y[j])); + u[i]->multiplyWith(ex, *(xmon.u[j])); + } + } +} + +Monom2Vector::~Monom2Vector() +{ + for (int i = 0; i < len; i++) { + delete y[i]; + delete u[i]; + } + delete [] y; + delete [] u; +} + +void Monom2Vector::deriv(const Symmetry& s, const IntSequence& c, + Vector& out) const +{ + TL_RAISE_IF(out.length() != len, + "Wrong length of output vector in Monom2Vector::deriv"); + TL_RAISE_IF(s.num() != 2, + "Wrong symmetry for Monom2Vector::deriv"); + TL_RAISE_IF(s.dimen() != c.size(), + "Incompatible symmetry and coordinates in Monom2Vector::deriv"); + IntSequence cy(c, 0, s[0]); + IntSequence cu(c, s[0], s.dimen()); + for (int i = 0; i < len; i++) { + out[i] = y[i]->deriv(cy) * u[i]->deriv(cu); + } +} + +FGSTensor* Monom2Vector::deriv(const Symmetry& s) const +{ + IntSequence nvs(2); nvs[0] = ny; nvs[1] = nu; + FGSTensor* t = new FGSTensor(len, TensorDimens(s, nvs)); + for (Tensor::index it = t->begin(); it != t->end(); ++it) { + Vector col(*t, *it); + deriv(s, it.getCoor(), col); + } + return t; +} + +FGSContainer* Monom2Vector::deriv(int maxdim) const +{ + FGSContainer* res = new FGSContainer(2); + for (int dim = 1; dim <= maxdim; dim++) { + for (int ydim = 0; ydim <= dim; ydim++) { + int udim = dim - ydim; + Symmetry s(ydim, udim); + res->insert(deriv(s)); + } + } + return res; +} + +void Monom2Vector::print() const +{ + printf("Variables: y(%d) u(%d)\n", ny, nu); + printf("Rows: %d\n", len); + for (int i = 0; i < len; i++) { + printf("%2d: ", i); + y[i]->print(); + printf(" "); + u[i]->print(); + printf("\n"); + } +} + +Monom4Vector::~Monom4Vector() +{ + for (int i = 0; i < len; i++) { + delete x1[i]; + delete x2[i]; + delete x3[i]; + delete x4[i]; + } + delete [] x1; + delete [] x2; + delete [] x3; + delete [] x4; +} + +void Monom4Vector::init_random() +{ + for (int i = 0; i < len; i++) { + x1[i] = new Monom(nx1); + x2[i] = new Monom(nx2); + x3[i] = new Monom(nx3); + x4[i] = new Monom(nx4); + } +} + +Monom4Vector::Monom4Vector(int l, int ny, int nu) + : len(l), nx1(ny), nx2(nu), nx3(0), nx4(1), + x1(new (Monom*)[len]), + x2(new (Monom*)[len]), + x3(new (Monom*)[len]), + x4(new (Monom*)[len]) +{ + init_random(); +} + +Monom4Vector::Monom4Vector(int l, int ny, int nu, int nup) + : len(l), nx1(ny), nx2(nu), nx3(nup), nx4(1), + x1(new (Monom*)[len]), + x2(new (Monom*)[len]), + x3(new (Monom*)[len]), + x4(new (Monom*)[len]) +{ + init_random(); +} + +Monom4Vector::Monom4Vector(int l, int nbigg, int ng, int ny, int nu) + : len(l), nx1(nbigg), nx2(ng), nx3(ny), nx4(nu), + x1(new (Monom*)[len]), + x2(new (Monom*)[len]), + x3(new (Monom*)[len]), + x4(new (Monom*)[len]) +{ + init_random(); +} + +Monom4Vector::Monom4Vector(const Monom4Vector& f, const Monom4Vector& bigg, + const Monom4Vector& g) + : len(f.len), nx1(bigg.nx1), nx2(bigg.nx2), nx3(bigg.nx3), nx4(1), + x1(new (Monom*)[len]), + x2(new (Monom*)[len]), + x3(new (Monom*)[len]), + x4(new (Monom*)[len]) +{ + TL_RAISE_IF(!(bigg.nx1 == g.nx1 && bigg.nx2 == g.nx2 && g.nx3 == 0 && + bigg.nx4 == 1 && g.nx4 == 1), + "Incompatible g with G"); + TL_RAISE_IF(!(bigg.len == f.nx1 && g.len == f.nx2 && + bigg.nx1 == f.nx3 && bigg.nx2 == f.nx4), + "Incompatible g or G with f"); + + for (int i = 0; i < len; i++) { + x1[i] = new Monom(nx1, 0); + x2[i] = new Monom(nx2, 0); + x3[i] = new Monom(nx3, 0); + x4[i] = new Monom(nx4, 0); + } + + for (int i = 0; i < len; i++) { + // multiply from G (first argument) + for (int j = 0; j < f.nx1; j++) { + int ex = f.x1[i]->operator[](j); + x1[i]->multiplyWith(ex, *(bigg.x1[j])); + x2[i]->multiplyWith(ex, *(bigg.x2[j])); + x3[i]->multiplyWith(ex, *(bigg.x3[j])); + x4[i]->multiplyWith(ex, *(bigg.x4[j])); + } + // multiply from g (second argument) + for (int j = 0; j < f.nx2; j++) { + int ex = f.x2[i]->operator[](j); + x1[i]->multiplyWith(ex, *(g.x1[j])); + x2[i]->multiplyWith(ex, *(g.x2[j])); + x4[i]->multiplyWith(ex, *(g.x4[j])); + } + // add y as third argument of f + x1[i]->add(1, *(f.x3[i])); + // add u as fourth argument of f + x2[i]->add(1, *(f.x4[i])); + } +} + +void Monom4Vector::deriv(const Symmetry& s, const IntSequence& coor, + Vector& out) const +{ + TL_RAISE_IF(out.length() != len, + "Wrong length of output vector in Monom4Vector::deriv"); + TL_RAISE_IF(s.num() != 4, + "Wrong symmetry for Monom4Vector::deriv"); + TL_RAISE_IF(s.dimen() != coor.size(), + "Incompatible symmetry and coordinates in Monom4Vector::deriv"); + + for (int i = 0; i < len; i++) { + out[i] = 1; + int off = 0; + out[i] *= x1[i]->deriv(IntSequence(coor, off, off+s[0])); + off += s[0]; + out[i] *= x2[i]->deriv(IntSequence(coor, off, off+s[1])); + off += s[1]; + out[i] *= x3[i]->deriv(IntSequence(coor, off, off+s[2])); + off += s[2]; + out[i] *= x4[i]->deriv(IntSequence(coor, off, off+s[3])); + } +} + +FGSTensor* Monom4Vector::deriv(const Symmetry& s) const +{ + IntSequence nvs(4); + nvs[0] = nx1; nvs[1] = nx2; + nvs[2] = nx3; nvs[3] = nx4; + + FGSTensor* res = new FGSTensor(len, TensorDimens(s, nvs)); + for (Tensor::index run = res->begin(); run != res->end(); ++run) { + Vector col(*res, *run); + deriv(s, run.getCoor(), col); + } + return res; +} + +FSSparseTensor* Monom4Vector::deriv(int dim) const +{ + IntSequence cum(4); + cum[0] = 0; cum[1] = nx1; cum[2] = nx1+nx2; cum[3] = nx1+nx2+nx3; + + FSSparseTensor* res = new FSSparseTensor(dim, nx1+nx2+nx3+nx4, len); + + FFSTensor dummy(0, nx1+nx2+nx3+nx4, dim); + for (Tensor::index run = dummy.begin(); run != dummy.end(); ++run) { + Symmetry ind_sym(0,0,0,0); + IntSequence ind(run.getCoor()); + for (int i = 0; i < ind.size(); i++) { + int j = 3; + while (j >= 0 && ind[i] < cum[j]) j--; + ind_sym[j]++; + ind[i] -= cum[j]; + } + + Vector col(len); + deriv(ind_sym, ind, col); + for (int i = 0; i < len; i++) { + if (col[i] != 0.0) { + res->insert(run.getCoor(), i, col[i]); + } + } + } + + return res; +} + +void Monom4Vector::print() const +{ + printf("Variables: x1(%d) x2(%d) x3(%d) x4(%d)\n", + nx1, nx2, nx3, nx4); + printf("Rows: %d\n", len); + for (int i = 0; i < len; i++) { + printf("%2d: ", i); + x1[i]->print(); + printf(" "); + x2[i]->print(); + printf(" "); + x3[i]->print(); + printf(" "); + x4[i]->print(); + printf("\n"); + } +} + +SparseDerivGenerator::SparseDerivGenerator( + int nf, int ny, int nu, int nup, int nbigg, int ng, + int mx, double prob, int maxdim) + : maxdimen(maxdim), ts(new (FSSparseTensor*)[maxdimen]) +{ + intgen.init(nf, ny, nu, nup, nbigg, mx, prob); + + Monom4Vector bigg_m(nbigg, ny, nu, nup); + Monom4Vector g_m(ng, ny, nu); + Monom4Vector f(nf, nbigg, ng, ny, nu); + Monom4Vector r(f, bigg_m, g_m); + bigg = new FGSContainer(4); + g = new FGSContainer(4); + rcont = new FGSContainer(4); + + for (int dim = 1; dim <= maxdimen; dim++) { + SymmetrySet ss(dim, 4); + for (symiterator si(ss); !si.isEnd(); ++si) { + bigg->insert(bigg_m.deriv(*si)); + rcont->insert(r.deriv(*si)); + if ((*si)[2] == 0) + g->insert(g_m.deriv(*si)); + } + + ts[dim-1] = f.deriv(dim); + } +} + +SparseDerivGenerator::~SparseDerivGenerator() +{ + delete bigg; + delete g; + delete rcont; + for(int i = 0; i < maxdimen; i++) + delete ts[i]; + delete [] ts; +} + + +DenseDerivGenerator::DenseDerivGenerator(int ng, int nx, int ny, int nu, + int mx, double prob, int maxdim) + : maxdimen(maxdim), ts(new (FGSTensor*)[maxdimen]), + uts(new (UGSTensor*)[maxdimen]) +{ + intgen.init(ng, nx, ny, nu, nu, mx, prob); + Monom1Vector g(nx, ng); + Monom2Vector x(ny, nu, nx); + Monom2Vector r(g, x); + xcont = x.deriv(maxdimen); + rcont = r.deriv(maxdimen); + uxcont = NULL; + for (int d = 1; d <= maxdimen; d++) { + ts[d-1] = g.deriv(d); + uts[d-1] = NULL; + } +} + +void DenseDerivGenerator::unfold() +{ + uxcont = new UGSContainer(*xcont); + for (int i = 0; i < maxdimen; i++) { + uts[i] = new UGSTensor(*(ts[i])); + } +} + +DenseDerivGenerator::~DenseDerivGenerator() +{ + delete xcont; + delete rcont; + for (int i = 0; i < maxdimen; i++) { + delete ts[i]; + if (uts[i]) + delete uts[i]; + } + delete [] ts; + delete [] uts; +} + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/tl/testing/monoms.h b/mex/sources/korderpert/Dyn_pp/tl/testing/monoms.h new file mode 100644 index 000000000..94b34a3da --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/testing/monoms.h @@ -0,0 +1,128 @@ +/* $Id: monoms.h 148 2005-04-19 15:12:26Z kamenik $ */ +/* Copyright 2004, Ondra Kamenik */ + +#ifndef MONOMS_H +#define MONOMS_H + +#include "int_sequence.h" +#include "gs_tensor.h" +#include "t_container.h" +#include "sparse_tensor.h" +#include "Vector.h" + +class IntGenerator { + int maxim; + double probab; +public: + IntGenerator() + : maxim(5), probab(0.3) {} + void init(int nf, int ny, int nv, int nw, int nu, int mx, double prob); + int get() const; +}; + +extern IntGenerator intgen; + + +class Monom : public IntSequence { +public: + Monom(int len); // generate a random monom + Monom(int len, int item); // generate monom whose items are the given item + double deriv(const IntSequence& vars) const; + // this = this*m^ex (in monomial sense) + void multiplyWith(int ex, const Monom& m); + void print() const; +}; + +class Monom2Vector; +class Monom1Vector { + friend class Monom2Vector; + int nx; + int len; + Monom** const x; +public: + Monom1Vector(int nxx, int l); + ~Monom1Vector(); + void deriv(const IntSequence& c, Vector& out) const; + FGSTensor* deriv(int dim) const; + void print() const; +}; + +//class Monom3Vector; +class Monom2Vector { + int ny; + int nu; + int len; + Monom** const y; + Monom** const u; +public: + // generate random vector of monom two vector + Monom2Vector(int nyy, int nuu, int l); + // calculate g(x(y,u)) + Monom2Vector(const Monom1Vector& g, const Monom2Vector& xmon); + ~Monom2Vector(); + void deriv(const Symmetry& s, const IntSequence& c, Vector& out) const; + FGSTensor* deriv(const Symmetry& s) const; + FGSContainer* deriv(int maxdim) const; + void print() const; +}; + +class Monom4Vector { + int len; + int nx1; + int nx2; + int nx3; + int nx4; + Monom** const x1; + Monom** const x2; + Monom** const x3; + Monom** const x4; +public: + /* random for g(y,u,sigma) */ + Monom4Vector(int l, int ny, int nu); + /* random for G(y,u,u',sigma) */ + Monom4Vector(int l, int ny, int nu, int nup); + /* random for f(y+,y,y-,u) */ + Monom4Vector(int l, int nbigg, int ng, int ny, int nu); + /* substitution f(G(y,u,u',sigma),g(y,u,sigma),y,u) */ + Monom4Vector(const Monom4Vector& f, const Monom4Vector& bigg, + const Monom4Vector& g); + ~Monom4Vector(); + FSSparseTensor* deriv(int dim) const; + FGSTensor* deriv(const Symmetry& s) const; + void deriv(const Symmetry& s, const IntSequence& coor, Vector& out) const; + void print() const; +protected: + void init_random(); +}; + + +struct SparseDerivGenerator { + int maxdimen; + FGSContainer* bigg; + FGSContainer* g; + FGSContainer* rcont; + FSSparseTensor** const ts; + SparseDerivGenerator(int nf, int ny, int nu, int nup, int nbigg, int ng, + int mx, double prob, int maxdim); + ~SparseDerivGenerator(); +}; + + +struct DenseDerivGenerator { + int maxdimen; + FGSContainer* xcont; + FGSContainer* rcont; + FGSTensor** const ts; + UGSContainer* uxcont; + UGSTensor** const uts; + DenseDerivGenerator(int ng, int nx, int ny, int nu, + int mx, double prob, int maxdim); + void unfold(); + ~DenseDerivGenerator(); +}; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/Dyn_pp/tl/testing/tests.cpp b/mex/sources/korderpert/Dyn_pp/tl/testing/tests.cpp new file mode 100644 index 000000000..c05dfb856 --- /dev/null +++ b/mex/sources/korderpert/Dyn_pp/tl/testing/tests.cpp @@ -0,0 +1,1019 @@ +/* $Id: tests.cpp 148 2005-04-19 15:12:26Z kamenik $ */ +/* Copyright 2004, Ondra Kamenik */ + +#include "SylvException.h" +#include "tl_exception.h" +#include "gs_tensor.h" +#include "factory.h" +#include "monoms.h" +#include "t_container.h" +#include "stack_container.h" +#include "t_polynomial.h" +#include "rfs_tensor.h" +#include "ps_tensor.h" +#include "tl_static.h" + +#include +#include +#include + + +class TestRunnable { + char name[100]; +public: + int dim; // dimension of the solved problem + int nvar; // number of variable of the solved problem + TestRunnable(const char* n, int d, int nv) + : dim(d), nvar(nv) + {strncpy(name, n, 100);} + bool test() const; + virtual bool run() const =0; + const char* getName() const + {return name;} +protected: + template + static bool index_forward(const Symmetry& s, const IntSequence& nvs); + + template + static bool index_backward(const Symmetry& s, const IntSequence& nvs); + + template + static bool index_offset(const Symmetry& s, const IntSequence& nvs); + + static bool fold_unfold(const FTensor* folded); + static bool fs_fold_unfold(int r, int nv, int dim) + { + Factory f; + FTensor* folded = f.make(r, nv, dim); + return fold_unfold(folded); // folded deallocated in fold_unfold + } + static bool r_fold_unfold(int r, int nv, int dim) + { + Factory f; + FTensor* folded = f.make(r, nv, dim); + return fold_unfold(folded); // folded deallocated in fold_unfold + } + static bool gs_fold_unfold(int r, const Symmetry& s, const IntSequence& nvs) + { + Factory f; + FTensor* folded = f.make(r, s, nvs); + return fold_unfold(folded); // folded deallocated in fold_unfold + } + + static bool dense_prod(const Symmetry& bsym, const IntSequence& bnvs, + int hdim, int hnv, int rows); + + static bool folded_monomial(int ng, int nx, int ny, int nu, int dim); + + static bool unfolded_monomial(int ng, int nx, int ny, int nu, int dim); + + static bool fold_zcont(int nf, int ny, int nu, int nup, int nbigg, + int ng, int dim); + + static bool unfold_zcont(int nf, int ny, int nu, int nup, int nbigg, + int ng, int dim); + + static bool folded_contraction(int r, int nv, int dim); + + static bool unfolded_contraction(int r, int nv, int dim); + + static bool poly_eval(int r, int nv, int maxdim); + + +}; + +bool TestRunnable::test() const +{ + printf("Running test <%s>\n",name); + clock_t start = clock(); + bool passed = run(); + clock_t end = clock(); + printf("CPU time %8.4g (CPU seconds)..................", + ((double)(end-start))/CLOCKS_PER_SEC); + if (passed) { + printf("passed\n\n"); + return passed; + } else { + printf("FAILED\n\n"); + return passed; + } +} + + +/****************************************************/ +/* definition of TestRunnable static methods */ +/****************************************************/ +template +bool TestRunnable::index_forward(const Symmetry& s, const IntSequence& nvs) +{ + int fails = 0; + int ndecr = 0; + int nincr = 0; + _Ttype dummy(0, TensorDimens(s, nvs)); + typename _Ttype::index run = dummy.end(); + do { + --run; + ndecr++; + typename _Ttype::index run2 = dummy.begin(); + for (int i = 0; i < *run; i++) { + ++run2; + nincr++; + } + if (! (run == run2)) + fails++; + } while (run != dummy.begin()); + + printf("\tnumber of columns = %d\n",dummy.ncols()); + printf("\tnumber of increments = %d\n",nincr); + printf("\tnumber of decrements = %d\n",ndecr); + printf("\tnumber of failures = %d\n",fails); + + return fails == 0; +} + +template +bool TestRunnable::index_backward(const Symmetry& s, const IntSequence& nvs) +{ + int fails = 0; + int ndecr = 0; + int nincr = 0; + _Ttype dummy(0, TensorDimens(s, nvs)); + typename _Ttype::index run = dummy.begin(); + while (run != dummy.end()) { + typename _Ttype::index run2 = dummy.end(); + for (int i = 0; i < dummy.ncols() - *run; i++) { + --run2; + ndecr++; + } + if (! (run == run2)) + fails++; + ++run; + nincr++; + } + + printf("\tnumber of columns = %d\n",dummy.ncols()); + printf("\tnumber of increments = %d\n",nincr); + printf("\tnumber of decrements = %d\n",ndecr); + printf("\tnumber of failures = %d\n",fails); + + return fails == 0; +} + +template +bool TestRunnable::index_offset(const Symmetry& s, const IntSequence& nvs) +{ + int fails = 0; + int nincr = 0; + _Ttype dummy(0, TensorDimens(s, nvs)); + for (typename _Ttype::index run = dummy.begin(); + run != dummy.end(); ++run, nincr++) { + typename _Ttype::index run2(&dummy, run.getCoor()); + if (! (run == run2)) + fails++; + } + + printf("\tnumber of columns = %d\n",dummy.ncols()); + printf("\tnumber of increments = %d\n",nincr); + printf("\tnumber of failures = %d\n",fails); + + return fails == 0; +} + +bool TestRunnable::fold_unfold(const FTensor* folded) +{ + UTensor* unfolded = &(folded->unfold()); + FTensor* folded2 = &(unfolded->fold()); + folded2->add(-1.0, *folded); + double normInf = folded2->getNormInf(); + double norm1 = folded2->getNorm1(); + printf("\tfolded size: (%d, %d)\n",folded->nrows(), folded->ncols()); + printf("\tunfolded size: (%d, %d)\n",unfolded->nrows(), unfolded->ncols()); + printf("\tdifference normInf: %8.4g\n", normInf); + printf("\tdifference norm1: %8.4g\n", norm1); + + delete folded; + delete unfolded; + delete folded2; + + return normInf < 1.0e-15; +} + +bool TestRunnable::dense_prod(const Symmetry& bsym, const IntSequence& bnvs, + int hdim, int hnv, int rows) +{ + Factory f; + FGSContainer* cont = + f.makeCont(hnv, bnvs, bsym.dimen()-hdim+1); + FGSTensor* fh = + f.make(rows, Symmetry(hdim), IntSequence(1, hnv)); + UGSTensor uh(*fh); + FGSTensor fb(rows, TensorDimens(bsym, bnvs)); + fb.getData().zeros(); + clock_t s1 = clock(); + cont->multAndAdd(uh, fb); + clock_t s2 = clock(); + UGSContainer ucont(*cont); + clock_t s3 = clock(); + UGSTensor ub(rows, fb.getDims()); + ub.getData().zeros(); + clock_t s4 = clock(); + ucont.multAndAdd(uh, ub); + clock_t s5 = clock(); + + UGSTensor btmp(fb); + btmp.add(-1, ub); + double norm = btmp.getData().getMax(); + double norm1 = btmp.getNorm1(); + double normInf = btmp.getNormInf(); + + printf("\ttime for folded product: %8.4g\n", + ((double)(s2-s1))/CLOCKS_PER_SEC); + printf("\ttime for unfolded product: %8.4g\n", + ((double)(s5-s4))/CLOCKS_PER_SEC); + printf("\ttime for container convert: %8.4g\n", + ((double)(s3-s2))/CLOCKS_PER_SEC); + printf("\tunfolded difference normMax: %10.6g\n", norm); + printf("\tunfolded difference norm1: %10.6g\n", norm1); + printf("\tunfolded difference normInf: %10.6g\n", normInf); + + delete cont; + delete fh; + + return norm < 1.e-13; +} + +bool TestRunnable::folded_monomial(int ng, int nx, int ny, int nu, int dim) +{ + clock_t gen_time = clock(); + DenseDerivGenerator gen(ng, nx, ny, nu, 5, 0.3, dim); + gen_time = clock()-gen_time; + printf("\ttime for monom generation: %8.4g\n", + ((double)gen_time)/CLOCKS_PER_SEC); + IntSequence nvs(2); nvs[0] = ny; nvs[1] = nu; + double maxnorm = 0; + for (int ydim = 0; ydim <= dim; ydim++) { + Symmetry s(ydim, dim-ydim); + printf("\tSymmetry: ");s.print(); + FGSTensor res(ng, TensorDimens(s, nvs)); + res.getData().zeros(); + clock_t stime = clock(); + for (int d = 1; d <= dim; d++) { + gen.xcont->multAndAdd(*(gen.ts[d-1]), res); + } + stime = clock() - stime; + printf("\t\ttime for symmetry: %8.4g\n", + ((double)stime)/CLOCKS_PER_SEC); + const FGSTensor* mres = gen.rcont->get(s); + res.add(-1.0, *mres); + double normtmp = res.getData().getMax(); + printf("\t\terror normMax: %10.6g\n", normtmp); + if (normtmp > maxnorm) + maxnorm = normtmp; + } + return maxnorm < 1.0e-10; +} + +bool TestRunnable::unfolded_monomial(int ng, int nx, int ny, int nu, int dim) +{ + clock_t gen_time = clock(); + DenseDerivGenerator gen(ng, nx, ny, nu, 5, 0.3, dim); + gen_time = clock()-gen_time; + printf("\ttime for monom generation: %8.4g\n", + ((double)gen_time)/CLOCKS_PER_SEC); + clock_t u_time = clock(); + gen.unfold(); + u_time = clock() - u_time; + printf("\ttime for monom unfolding: %8.4g\n", + ((double)u_time)/CLOCKS_PER_SEC); + IntSequence nvs(2); nvs[0] = ny; nvs[1] = nu; + double maxnorm = 0; + for (int ydim = 0; ydim <= dim; ydim++) { + Symmetry s(ydim, dim-ydim); + printf("\tSymmetry: ");s.print(); + UGSTensor res(ng, TensorDimens(s, nvs)); + res.getData().zeros(); + clock_t stime = clock(); + for (int d = 1; d <= dim; d++) { + gen.uxcont->multAndAdd(*(gen.uts[d-1]), res); + } + stime = clock() - stime; + printf("\t\ttime for symmetry: %8.4g\n", + ((double)stime)/CLOCKS_PER_SEC); + const FGSTensor* mres = gen.rcont->get(s); + FGSTensor foldres(res); + foldres.add(-1.0, *mres); + double normtmp = foldres.getData().getMax(); + printf("\t\terror normMax: %10.6g\n", normtmp); + if (normtmp > maxnorm) + maxnorm = normtmp; + } + return maxnorm < 1.0e-10; +} + +bool TestRunnable::fold_zcont(int nf, int ny, int nu, int nup, int nbigg, + int ng, int dim) +{ + clock_t gen_time = clock(); + SparseDerivGenerator dg(nf, ny, nu, nup, nbigg, ng, + 5, 0.55, dim); + gen_time = clock()-gen_time; + for (int d = 1; d <= dim; d++) { + printf("\tfill of dim=%d tensor: %3.2f %%\n", + d, 100*dg.ts[d-1]->getFillFactor()); + } + printf("\ttime for monom generation: %8.4g\n", + ((double)gen_time)/CLOCKS_PER_SEC); + + IntSequence nvs(4); + nvs[0] = ny; nvs[1] = nu; nvs[2] = nup; nvs[3] = 1; + double maxnorm = 0.0; + + // form ZContainer + FoldedZContainer zc(dg.bigg, nbigg, dg.g, ng, ny, nu); + + for (int d = 2; d <= dim; d++) { + SymmetrySet ss(d, 4); + for (symiterator si(ss); !si.isEnd(); ++si) { + printf("\tSymmetry: ");(*si).print(); + FGSTensor res(nf, TensorDimens(*si, nvs)); + res.getData().zeros(); + clock_t stime = clock(); + for (int l = 1; l <= (*si).dimen(); l++) { + zc.multAndAdd(*(dg.ts[l-1]), res); + } + stime = clock() - stime; + printf("\t\ttime for symmetry: %8.4g\n", + ((double)stime)/CLOCKS_PER_SEC); + const FGSTensor* mres = dg.rcont->get(*si); + res.add(-1.0, *mres); + double normtmp = res.getData().getMax(); + printf("\t\terror normMax: %10.6g\n", normtmp); + if (normtmp > maxnorm) + maxnorm = normtmp; + } + } + return maxnorm < 1.0e-10; +} + +bool TestRunnable::unfold_zcont(int nf, int ny, int nu, int nup, int nbigg, + int ng, int dim) +{ + clock_t gen_time = clock(); + SparseDerivGenerator dg(nf, ny, nu, nup, nbigg, ng, + 5, 0.55, dim); + gen_time = clock()-gen_time; + for (int d = 1; d <= dim; d++) { + printf("\tfill of dim=%d tensor: %3.2f %%\n", + d, 100*dg.ts[d-1]->getFillFactor()); + } + printf("\ttime for monom generation: %8.4g\n", + ((double)gen_time)/CLOCKS_PER_SEC); + + clock_t con_time = clock(); + UGSContainer uG_cont(*(dg.bigg)); + UGSContainer ug_cont(*(dg.g)); + con_time = clock()-con_time; + printf("\ttime for container unfold: %8.4g\n", + ((double)con_time)/CLOCKS_PER_SEC); + + IntSequence nvs(4); + nvs[0] = ny; nvs[1] = nu; nvs[2] = nup; nvs[3] = 1; + double maxnorm = 0.0; + + // form ZContainer + UnfoldedZContainer zc(&uG_cont, nbigg, &ug_cont, ng, ny, nu); + + for (int d = 2; d <= dim; d++) { + SymmetrySet ss(d, 4); + for (symiterator si(ss); !si.isEnd(); ++si) { + printf("\tSymmetry: ");(*si).print(); + UGSTensor res(nf, TensorDimens(*si, nvs)); + res.getData().zeros(); + clock_t stime = clock(); + for (int l = 1; l <= (*si).dimen(); l++) { + zc.multAndAdd(*(dg.ts[l-1]), res); + } + stime = clock() - stime; + printf("\t\ttime for symmetry: %8.4g\n", + ((double)stime)/CLOCKS_PER_SEC); + FGSTensor fold_res(res); + const FGSTensor* mres = dg.rcont->get(*si); + fold_res.add(-1.0, *mres); + double normtmp = fold_res.getData().getMax(); + printf("\t\terror normMax: %10.6g\n", normtmp); + if (normtmp > maxnorm) + maxnorm = normtmp; + } + } + return maxnorm < 1.0e-10; +} + +bool TestRunnable::folded_contraction(int r, int nv, int dim) +{ + Factory fact; + Vector* x = fact.makeVector(nv); + + FFSTensor* forig = fact.make(r, nv, dim); + FFSTensor* f = new FFSTensor(*forig); + clock_t ctime = clock(); + for (int d = dim-1; d > 0; d--) { + FFSTensor* fnew = new FFSTensor(*f, ConstVector(*x)); + delete f; + f = fnew; + } + ctime = clock() - ctime; + Vector res(forig->nrows()); + res.zeros(); + f->multaVec(res, *x); + + UFSTensor u(*forig); + clock_t utime = clock(); + URSingleTensor ux(*x, dim); + Vector v(u.nrows()); + v.zeros(); + u.multaVec(v, ux.getData()); + utime = clock() - utime; + + v.add(-1.0, res); + printf("\ttime for folded contraction: %8.4g\n", + ((double)ctime)/CLOCKS_PER_SEC); + printf("\ttime for unfolded power: %8.4g\n", + ((double)utime)/CLOCKS_PER_SEC); + printf("\terror normMax: %10.6g\n", v.getMax()); + printf("\terror norm1: %10.6g\n", v.getNorm1()); + + delete f; + delete x; + + return (v.getMax() < 1.e-10); +} + +bool TestRunnable::unfolded_contraction(int r, int nv, int dim) +{ + Factory fact; + Vector* x = fact.makeVector(nv); + + FFSTensor* forig = fact.make(r, nv, dim); + UFSTensor uorig(*forig); + delete forig; + UFSTensor* u = new UFSTensor(uorig); + clock_t ctime = clock(); + for (int d = dim-1; d > 0; d--) { + UFSTensor* unew = new UFSTensor(*u, ConstVector(*x)); + delete u; + u = unew; + } + ctime = clock() - ctime; + Vector res(uorig.nrows()); + res.zeros(); + u->multaVec(res, *x); + + clock_t utime = clock(); + URSingleTensor ux(*x, dim); + Vector v(uorig.nrows()); + v.zeros(); + uorig.multaVec(v, ux.getData()); + utime = clock() - utime; + + v.add(-1.0, res); + printf("\ttime for unfolded contraction: %8.4g\n", + ((double)ctime)/CLOCKS_PER_SEC); + printf("\ttime for unfolded power: %8.4g\n", + ((double)utime)/CLOCKS_PER_SEC); + printf("\terror normMax: %10.6g\n", v.getMax()); + printf("\terror norm1: %10.6g\n", v.getNorm1()); + + delete u; + delete x; + + return (v.getMax() < 1.e-10); +} + +bool TestRunnable::poly_eval(int r, int nv, int maxdim) +{ + Factory fact; + Vector* x = fact.makeVector(nv); + + Vector out_ft(r); out_ft.zeros(); + Vector out_fh(r); out_fh.zeros(); + Vector out_ut(r); out_ut.zeros(); + Vector out_uh(r); out_uh.zeros(); + + UTensorPolynomial* up; + { + FTensorPolynomial* fp = fact.makePoly(r, nv, maxdim); + + clock_t ft_cl = clock(); + fp->evalTrad(out_ft, *x); + ft_cl = clock() - ft_cl; + printf("\ttime for folded power eval: %8.4g\n", + ((double)ft_cl)/CLOCKS_PER_SEC); + + clock_t fh_cl = clock(); + fp->evalHorner(out_fh, *x); + fh_cl = clock() - fh_cl; + printf("\ttime for folded horner eval: %8.4g\n", + ((double)fh_cl)/CLOCKS_PER_SEC); + + up = new UTensorPolynomial(*fp); + delete fp; + } + + clock_t ut_cl = clock(); + up->evalTrad(out_ut, *x); + ut_cl = clock() - ut_cl; + printf("\ttime for unfolded power eval: %8.4g\n", + ((double)ut_cl)/CLOCKS_PER_SEC); + + clock_t uh_cl = clock(); + up->evalHorner(out_uh, *x); + uh_cl = clock() - uh_cl; + printf("\ttime for unfolded horner eval: %8.4g\n", + ((double)uh_cl)/CLOCKS_PER_SEC); + + out_ft.add(-1.0, out_ut); + double max_ft = out_ft.getMax(); + out_fh.add(-1.0, out_ut); + double max_fh = out_fh.getMax(); + out_uh.add(-1.0, out_ut); + double max_uh = out_uh.getMax(); + + printf("\tfolded power error norm max: %10.6g\n", max_ft); + printf("\tfolded horner error norm max: %10.6g\n", max_fh); + printf("\tunfolded horner error norm max: %10.6g\n", max_uh); + + delete up; + delete x; + return (max_ft+max_fh+max_uh < 1.0e-10); +} + + +/****************************************************/ +/* definition of TestRunnable subclasses */ +/****************************************************/ +class SmallIndexForwardFold : public TestRunnable { +public: + SmallIndexForwardFold() + : TestRunnable("small index forward for fold (44)(222)", 5, 4) {} + bool run() const + { + Symmetry s(2,3); + IntSequence nvs(2); nvs[0] = 4; nvs[1] = 2; + return index_forward(s, nvs); + } +}; + +class SmallIndexForwardUnfold : public TestRunnable { +public: + SmallIndexForwardUnfold() + : TestRunnable("small index forward for unfold (44)(222)", 5, 4) {} + bool run() const + { + Symmetry s(2,3); + IntSequence nvs(2); nvs[0] = 4; nvs[1] = 2; + return index_forward(s, nvs); + } +}; + +class IndexForwardFold : public TestRunnable { +public: + IndexForwardFold() + : TestRunnable("index forward for fold (55)(222)(22)", 7, 5) {} + bool run() const + { + Symmetry s(2,3,2); + IntSequence nvs(3); nvs[0] = 5; nvs[1] = 2; nvs[2] = 2; + return index_forward(s, nvs); + } +}; + +class IndexForwardUnfold : public TestRunnable { +public: + IndexForwardUnfold() + : TestRunnable("index forward for unfold (55)(222)(22)", 7, 5) {} + bool run() const + { + Symmetry s(2,3,2); + IntSequence nvs(3); nvs[0] = 5; nvs[1] = 2; nvs[2] = 2; + return index_forward(s, nvs); + } +}; + +class SmallIndexBackwardFold : public TestRunnable { +public: + SmallIndexBackwardFold() + : TestRunnable("small index backward for fold (3)(3)(222)", 5, 3) {} + bool run() const + { + Symmetry s(1,1,3); + IntSequence nvs(3); nvs[0] = 3; nvs[1] = 3; nvs[2] = 2; + return index_backward(s, nvs); + } +}; + +class IndexBackwardFold : public TestRunnable { +public: + IndexBackwardFold() + : TestRunnable("index backward for fold (44)(222)(44)", 7, 4) {} + bool run() const + { + Symmetry s(2,3,2); + IntSequence nvs(3); nvs[0] = 4; nvs[1] = 2; nvs[2] = 4; + return index_backward(s, nvs); + } +}; + +class SmallIndexBackwardUnfold : public TestRunnable { +public: + SmallIndexBackwardUnfold() + : TestRunnable("small index backward for unfold (3)(3)(222)", 5, 3) {} + bool run() const + { + Symmetry s(1,1,3); + IntSequence nvs(3); nvs[0] = 3; nvs[1] = 3; nvs[2] = 2; + return index_backward(s, nvs); + } +}; + +class IndexBackwardUnfold : public TestRunnable { +public: + IndexBackwardUnfold() + : TestRunnable("index backward for unfold (44)(222)(44)", 7, 4) {} + bool run() const + { + Symmetry s(2,3,2); + IntSequence nvs(3); nvs[0] = 4; nvs[1] = 2; nvs[2] = 4; + return index_backward(s, nvs); + } +}; + +class SmallIndexOffsetFold : public TestRunnable { +public: + SmallIndexOffsetFold() + : TestRunnable("small index offset for fold (44)(222)", 5, 4) {} + bool run() const + { + Symmetry s(2,3); + IntSequence nvs(2); nvs[0] = 4; nvs[1] = 2; + return index_offset(s, nvs); + } +}; + +class SmallIndexOffsetUnfold : public TestRunnable { +public: + SmallIndexOffsetUnfold() + : TestRunnable("small index offset for unfold (44)(222)", 5, 4) {} + bool run() const + { + Symmetry s(2,3); + IntSequence nvs(2); nvs[0] = 4; nvs[1] = 2; + return index_offset(s, nvs); + } +}; + +class IndexOffsetFold : public TestRunnable { +public: + IndexOffsetFold() + : TestRunnable("index offset for fold (55)(222)(22)", 5, 5) {} + bool run() const + { + Symmetry s(2,3,2); + IntSequence nvs(3); nvs[0] = 5; nvs[1] = 2; nvs[2] = 2; + return index_offset(s, nvs); + } +}; + +class IndexOffsetUnfold : public TestRunnable { +public: + IndexOffsetUnfold() + : TestRunnable("index offset for unfold (55)(222)(22)", 7, 5) {} + bool run() const + { + Symmetry s(2,3,2); + IntSequence nvs(3); nvs[0] = 5; nvs[1] = 2; nvs[2] = 2; + return index_offset(s, nvs); + } +}; + +class SmallFoldUnfoldFS : public TestRunnable { +public: + SmallFoldUnfoldFS() + : TestRunnable("small fold-unfold for full symmetry (444)", 3, 4) {} + bool run() const + { + return fs_fold_unfold(5, 4, 3); + } +}; + + +class SmallFoldUnfoldGS : public TestRunnable { +public: + SmallFoldUnfoldGS() + : TestRunnable("small fold-unfold for gen symmetry (3)(33)(22)", 5, 3) {} + bool run() const + { + Symmetry s(1,2,2); + IntSequence nvs(3); nvs[0] = 3; nvs[1] = 3; nvs[2] = 2; + return gs_fold_unfold(5, s, nvs); + } +}; + +class FoldUnfoldFS : public TestRunnable { +public: + FoldUnfoldFS() + : TestRunnable("fold-unfold for full symmetry (9999)", 4, 9) {} + bool run() const + { + return fs_fold_unfold(5, 9, 4); + } +}; + + +class FoldUnfoldGS : public TestRunnable { +public: + FoldUnfoldGS() + : TestRunnable("fold-unfold for gen symmetry (66)(2)(66)", 5, 6) {} + bool run() const + { + Symmetry s(2,1,2); + IntSequence nvs(3); nvs[0] = 6; nvs[1] = 2; nvs[2] = 6; + return gs_fold_unfold(5, s, nvs); + } +}; + +class SmallFoldUnfoldR : public TestRunnable { +public: + SmallFoldUnfoldR() + : TestRunnable("small fold-unfold for row full symmetry (333)", 3, 3) {} + bool run() const + { + return r_fold_unfold(5, 3, 3); + } +}; + +class FoldUnfoldR : public TestRunnable { +public: + FoldUnfoldR() + : TestRunnable("fold-unfold for row full symmetry (66666)", 5, 6) {} + bool run() const + { + return r_fold_unfold(5, 6, 5); + } +}; + +class SmallDenseProd : public TestRunnable { +public: + SmallDenseProd() + : TestRunnable("small dense prod bsym=1-2,nvs=3-2,h=2-3,r=2",3,3) {} + bool run() const + { + IntSequence bnvs(2); bnvs[0]=3; bnvs[1]=2; + return dense_prod(Symmetry(1,2), bnvs, 2, 3, 2); + } +}; + +class DenseProd : public TestRunnable { +public: + DenseProd() + : TestRunnable("dense prod bsym=2-3,nvs=10-7,h=3-15,r=10",5,15) {} + bool run() const + { + IntSequence bnvs(2); bnvs[0]=10; bnvs[1]=7; + return dense_prod(Symmetry(2,3), bnvs, 3, 15, 10); + } +}; + +class BigDenseProd : public TestRunnable { +public: + BigDenseProd() + : TestRunnable("dense prod bsym=3-2,nvs=13-11,h=3-20,r=20",6,20) {} + bool run() const + { + IntSequence bnvs(2); bnvs[0]=13; bnvs[1]=11; + return dense_prod(Symmetry(3,2), bnvs, 3, 20, 20); + } +}; + +class SmallFoldedMonomial : public TestRunnable { +public: + SmallFoldedMonomial() + : TestRunnable("folded vrs. monoms (g,x,y,u)=(10,4,5,3), dim=4", 4, 8) {} + bool run() const + { + return folded_monomial(10, 4, 5, 3, 4); + } +}; + +class FoldedMonomial : public TestRunnable { +public: + FoldedMonomial() + : TestRunnable("folded vrs. monoms (g,x,y,u)=(20,12,10,5), dim=4", 4, 15) {} + bool run() const + { + return folded_monomial(20, 12, 10, 5, 4); + } +}; + +class SmallUnfoldedMonomial : public TestRunnable { +public: + SmallUnfoldedMonomial() + : TestRunnable("unfolded vrs. monoms (g,x,y,u)=(10,4,5,3), dim=4", 4, 8) {} + bool run() const + { + return unfolded_monomial(10, 4, 5, 3, 4); + } +}; + +class UnfoldedMonomial : public TestRunnable { +public: + UnfoldedMonomial() + : TestRunnable("unfolded vrs. monoms (g,x,y,u)=(20,12,10,5), dim=4", 4, 15) {} + bool run() const + { + return unfolded_monomial(20, 12, 10, 5, 4); + } +}; + +class FoldedContractionSmall : public TestRunnable { +public: + FoldedContractionSmall() + : TestRunnable("folded contraction small (r=5, nv=4, dim=3)", 3, 4) {} + bool run() const + { + return folded_contraction(5, 4, 3); + } +}; + +class FoldedContractionBig : public TestRunnable { +public: + FoldedContractionBig() + : TestRunnable("folded contraction big (r=20, nv=12, dim=5)", 5, 12) {} + bool run() const + { + return folded_contraction(20, 12, 5); + } +}; + +class UnfoldedContractionSmall : public TestRunnable { +public: + UnfoldedContractionSmall() + : TestRunnable("unfolded contraction small (r=5, nv=4, dim=3)", 3, 4) {} + bool run() const + { + return unfolded_contraction(5, 4, 3); + } +}; + +class UnfoldedContractionBig : public TestRunnable { +public: + UnfoldedContractionBig() + : TestRunnable("unfolded contraction big (r=20, nv=12, dim=5)", 5, 12) {} + bool run() const + { + return unfolded_contraction(20, 12, 5); + } +}; + +class PolyEvalSmall : public TestRunnable { +public: + PolyEvalSmall() + : TestRunnable("polynomial evaluation small (r=4, nv=5, maxdim=4)", 4, 5) {} + bool run() const + { + return poly_eval(4, 5, 4); + } +}; + +class PolyEvalBig : public TestRunnable { +public: + PolyEvalBig() + : TestRunnable("polynomial evaluation big (r=244, nv=97, maxdim=2)", 2, 97) {} + bool run() const + { + return poly_eval(244, 97, 2); + } +}; + +class FoldZContSmall : public TestRunnable { +public: + FoldZContSmall() + : TestRunnable("folded Z container (r=3,ny=2,nu=2,nup=1,G=2,g=2,dim=3)", + 3, 8) {} + bool run() const + { + return fold_zcont(3, 2, 2, 1, 2, 2, 3); + } +}; + +class FoldZCont : public TestRunnable { +public: + FoldZCont() + : TestRunnable("folded Z container (r=13,ny=5,nu=7,nup=4,G=6,g=7,dim=4)", + 4, 25) {} + bool run() const + { + return fold_zcont(13, 5, 7, 4, 6, 7, 4); + } +}; + +class UnfoldZContSmall : public TestRunnable { +public: + UnfoldZContSmall() + : TestRunnable("unfolded Z container (r=3,ny=2,nu=2,nup=1,G=2,g=2,dim=3)", + 3, 8) {} + bool run() const + { + return unfold_zcont(3, 2, 2, 1, 2, 2, 3); + } +}; + +class UnfoldZCont : public TestRunnable { +public: + UnfoldZCont() + : TestRunnable("unfolded Z container (r=13,ny=5,nu=7,nup=4,G=6,g=7,dim=4", + 4, 25) {} + bool run() const + { + return unfold_zcont(13, 5, 7, 4, 6, 7, 4); + } +}; + + + +int main() +{ + TestRunnable* all_tests[50]; + // fill in vector of all tests + int num_tests = 0; + all_tests[num_tests++] = new SmallIndexForwardFold(); + all_tests[num_tests++] = new SmallIndexForwardUnfold(); + all_tests[num_tests++] = new IndexForwardFold(); + all_tests[num_tests++] = new IndexForwardUnfold(); + all_tests[num_tests++] = new SmallIndexBackwardFold(); + all_tests[num_tests++] = new IndexBackwardFold(); + all_tests[num_tests++] = new SmallIndexBackwardUnfold(); + all_tests[num_tests++] = new IndexBackwardUnfold(); + all_tests[num_tests++] = new SmallIndexOffsetFold(); + all_tests[num_tests++] = new SmallIndexOffsetUnfold(); + all_tests[num_tests++] = new IndexOffsetFold(); + all_tests[num_tests++] = new IndexOffsetUnfold(); + all_tests[num_tests++] = new SmallFoldUnfoldFS(); + all_tests[num_tests++] = new SmallFoldUnfoldGS(); + all_tests[num_tests++] = new FoldUnfoldFS(); + all_tests[num_tests++] = new FoldUnfoldGS(); + all_tests[num_tests++] = new SmallFoldUnfoldR(); + all_tests[num_tests++] = new FoldUnfoldR(); + all_tests[num_tests++] = new SmallDenseProd(); + all_tests[num_tests++] = new DenseProd(); + all_tests[num_tests++] = new BigDenseProd(); + all_tests[num_tests++] = new SmallFoldedMonomial(); + all_tests[num_tests++] = new FoldedMonomial(); + all_tests[num_tests++] = new SmallUnfoldedMonomial(); + all_tests[num_tests++] = new UnfoldedMonomial(); + all_tests[num_tests++] = new FoldedContractionSmall(); + all_tests[num_tests++] = new FoldedContractionBig(); + all_tests[num_tests++] = new UnfoldedContractionSmall(); + all_tests[num_tests++] = new UnfoldedContractionBig(); + all_tests[num_tests++] = new PolyEvalSmall(); + all_tests[num_tests++] = new PolyEvalBig(); + all_tests[num_tests++] = new FoldZContSmall(); + all_tests[num_tests++] = new FoldZCont(); + all_tests[num_tests++] = new UnfoldZContSmall(); + all_tests[num_tests++] = new UnfoldZCont(); + + // find maximum dimension and maximum nvar + int dmax=0; + int nvmax = 0; + for (int i = 0; i < num_tests; i++) { + if (dmax < all_tests[i]->dim) + dmax = all_tests[i]->dim; + if (nvmax < all_tests[i]->nvar) + nvmax = all_tests[i]->nvar; + } + tls.init(dmax, nvmax); // initialize library + + // launch the tests + int success = 0; + for (int i = 0; i < num_tests; i++) { + try { + if (all_tests[i]->test()) + success++; + } catch (const TLException& e) { + printf("Caugth TL exception in <%s>:\n", all_tests[i]->getName()); + e.print(); + } catch (SylvException& e) { + printf("Caught Sylv exception in <%s>:\n", all_tests[i]->getName()); + e.printMessage(); + } + } + + printf("There were %d tests that failed out of %d tests run.\n", + num_tests - success, num_tests); + + // destroy + for (int i = 0; i < num_tests; i++) { + delete all_tests[i]; + } + + return 0; +} diff --git a/mex/sources/korderpert/src/k_ord_dynare.cpp b/mex/sources/korderpert/src/k_ord_dynare.cpp new file mode 100644 index 000000000..794786cdb --- /dev/null +++ b/mex/sources/korderpert/src/k_ord_dynare.cpp @@ -0,0 +1,353 @@ +/* Dynare is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Dynare 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 Dynare. If not, see . + */ +// based on: work by O.Kamenik + +#include "k_ord_dynare.h" +#include "dynare_exception.h" +///#include "planner_builder.h" +///#include "forw_subst_builder.h" + +#include "Dynare_pp/utils/cc/memory_file.h" +#include "Dynare_pp/utils/cc/exception.h" +///#include "parser/cc/parser_exception.h" +///#include "parser/cc/atom_substitutions.h" +#include "Dynare_pp/tl/cc/tl_exception.h" +#include "Dynare_pp/kord/kord_exception.h" + +#ifndef DYNVERSION +#define DYNVERSION "unknown" +#endif + + +/**************************************************************************************/ +/* DynareNameList class */ +/************************************************************************************** +vector DynareNameList::selectIndices(const vector& ns) const +{ + vector res; + for (unsigned int i = 0; i < ns.size(); i++) { + int j = 0; + while (j < getNum() && strcmp(getName(j), ns[i]) != 0) + j++; + if (j == getNum()) + throw DynareException(__FILE__, __LINE__, + string("Couldn't find name for ") + ns[i] + + " in DynareNameList::selectIndices"); + res.push_back(j); + } + return res; +} +*///////////////////////// +/**************************************************************************************/ +/* Dynare DynamicModel class */ +/**************************************************************************************/ + + +KordpDynare::KordpDynare(const char** endo, int nstat,int npred, int nforw, int nboth + const char** exo, int nexog, + const char** par, int npar, Vector* ysteady, + const char* modName, int len, int order, + double sstol, Journal& jr) + : journal(jr), md(1) +{ + + try{ + + } else { + throw DynareException(__FILE__, __LINE__, string("Could not open model file ")+modName); + } + +/// May need these later, GP, Oct. 08 +/// dnl = new DynareNameList(*this); +/// denl = new DynareExogNameList(*this); +// dsnl = new DynareStateNameList(*this, *dnl, *denl); +/// fe = new ogp::FormulaEvaluator(model->getParser()); +/// fde = new ogp::FormulaDerEvaluator(model->getParser()); +/// writeModelInfo(journal); +} + +KordpDynare::KordpDynare(const KordpDynare& dynare) + : ///journal(dynare.journal)///, model(NULL), + ysteady(NULL), md(dynare.md), +/// dnl(NULL), denl(NULL), dsnl(NULL), + ss_tol(dynare.ss_tol), nStat(dynare.nStat), nBoth(dynare.nBoth), + nPred(dynare.nPred), nForw(dynare.nForw), nExo(dynare.nExo), + nYs(dynare.nYs), nYss(dynare.nYss),nY(dynare.nY), nOrder(dynare.nOrder) +{ +/// model = dynare.model->clone(); + ysteady = new Vector(*(dynare.ysteady)); + params = new Vector(*(dynare.params)); + Vcov = new TwoDMatrix(*(dynare.Vcov)); + if (dynare.md) + md = new TensorContainer (*(dynare.getModelDerivatives)); +/// dnl = new DynareNameList(*this); +/// denl = new DynareExogNameList(*this); +/// dsnl = new DynareStateNameList(*this, *dnl, *denl); +} + +KordpDynare::~KordpDynare() +{ + if (ysteady) + delete ysteady; +// if (params) +// delete params; +// if (Vcov) +// delete Vcov; +/*************** May be needed + if (dnl) + delete dnl; + if (dsnl) + delete dsnl; + if (denl) + delete denl; + if (fe) + delete fe; + if (fde) + delete fde; +***********/// + +} + +void KordpDynare::solveDeterministicSteady(Vector& steady) +{ + JournalRecordPair pa(journal); + pa << "Non-linear solver for deterministic steady state" << endrec; + steady = (const Vector&) model->getInit(); + KordpDynareVectorFunction dvf(*this); + KordpDynareJacobian dj(*this); + ogu::NLSolver nls(dvf, dj, 500, ss_tol, journal); + int iter; + if (! nls.solve(steady, iter)) + throw DynareException(__FILE__, __LINE__, + "Could not obtain convergence in non-linear solver"); +} + +// evaluate system at given y_t=y_{t+1}=y_{t-1}, and given shocks x_t +void KordpDynare::evaluateSystem(Vector& out, const Vector& yy, const Vector& xx) +{ + ConstVector yym(yy, nstat(), nys()); + ConstVector yyp(yy, nstat()+npred(), nyss()); + evaluateSystem(out, yym, yy, yyp, xx); +} + +// evaluate system at given y^*_{t-1}, y_t, y^{**}_{t+1} and at +// exogenous x_t, all three vectors yym, yy, and yyp have the +// respective lengths of y^*_{t-1}, y_t, y^{**}_{t+1} + +void KordpDynare::evaluateSystem(Vector& out, const Vector& yym, const Vector& yy, + const Vector& yyp, const Vector& xx) +{ +/*////////////////////////// + ogdyn::DynareAtomValues dav(model->getAtoms(), model->getParams(), yym, yy, yyp, xx); + DynareEvalLoader del(model->getAtoms(), out); + fe->eval(dav, del); +///////////////////////*/ + +} + +void KordpDynare::calcDerivatives(const Vector& yy, const Vector& xx) +{ + ConstVector yym(yy, nstat(), nys()); + ConstVector yyp(yy, nstat()+npred(), nyss()); + ogdyn::DynareAtomValues dav(model->getAtoms(), model->getParams(), yym, yy, yyp, xx); + DynareDerEvalLoader ddel(model->getAtoms(), md, model->getOrder()); + for (int iord = 1; iord <= model->getOrder(); iord++) + fde->eval(dav, ddel, iord); +} + +void KordpDynare::calcDerivativesAtSteady() +{ + Vector xx(nexog()); + xx.zeros(); + calcDerivatives(*ysteady, xx); +} + +void KordpDynare::writeModelInfo(Journal& jr) const +{ + // write info on variables + { + JournalRecordPair rp(journal); + rp << "Information on variables" << endrec; + JournalRecord rec1(journal); + rec1 << "Number of endogenous: " << ny() << endrec; + JournalRecord rec2(journal); + rec2 << "Number of exogenous: " << nexog() << endrec; + JournalRecord rec3(journal); + rec3 << "Number of static: " << nstat() << endrec; + JournalRecord rec4(journal); + rec4 << "Number of predetermined: " << npred()+nboth() << endrec; + JournalRecord rec5(journal); + rec5 << "Number of forward looking: " << nforw()+nboth() << endrec; + JournalRecord rec6(journal); + rec6 << "Number of both: " << nboth() << endrec; + } + + + // write info on forward substitutions + const ogdyn::ForwSubstInfo* finfo = model->get_forw_subst_info(); + if (finfo) { + JournalRecordPair rp(journal); + rp << "Information on forward substitutions" << endrec; + JournalRecord rec1(journal); + rec1 << "Number of affected equations: " << finfo->num_affected_equations << endrec; + JournalRecord rec2(journal); + rec2 << "Number of substituted terms: " << finfo->num_subst_terms << endrec; + JournalRecord rec3(journal); + rec3 << "Number of auxiliary variables: " << finfo->num_aux_variables << endrec; + JournalRecord rec4(journal); + rec4 << "Number of new terms in the tree: " << finfo->num_new_terms << endrec; + } + + // write info on substitutions + const ogp::SubstInfo* sinfo = model->get_subst_info(); + if (sinfo) { + JournalRecordPair rp(journal); + rp << "Information on substitutions" << endrec; + JournalRecord rec1(journal); + rec1 << "Number of substitutions: " << sinfo->num_substs << endrec; + } +} +/********** +DynareNameList::DynareNameList(const KordpDynare& dynare) +{ + for (int i = 0; i < dynare.ny(); i++) { + int j = dynare.model->getAtoms().y2outer_endo()[i]; + const char* name = dynare.model->getAtoms().get_endovars()[j]; + names.push_back(name); + } +} + +DynareStateNameList::DynareStateNameList(const KordpDynare& dynare, const DynareNameList& dnl, + const DynareExogNameList& denl) +{ + for (int i = 0; i < dynare.nys(); i++) + names.push_back(dnl.getName(i+dynare.nstat())); + for (int i = 0; i < dynare.nexog(); i++) + names.push_back(denl.getName(i)); +} + +DynareExogNameList::DynareExogNameList(const KordpDynare& dynare) +{ + for (int i = 0; i < dynare.nexog(); i++) { + int j = dynare.model->getAtoms().y2outer_exo()[i]; + const char* name = dynare.model->getAtoms().get_exovars()[j]; + names.push_back(name); + } +} +*****************/// +/***************** +DynareEvalLoader::DynareEvalLoader(const ogp::FineAtoms& a, Vector& out) + : Vector(out) +{ + if (a.ny() != out.length()) + throw DynareException(__FILE__, __LINE__, "Wrong length of out vector in DynareEvalLoader constructor"); +} +**********/ +/** This clears the container of model derivatives and initializes it + * inserting empty sparse tensors up to the given order. */ + /* +DynareDerEvalLoader::DynareDerEvalLoader(const ogp::FineAtoms& a, + TensorContainer& mod_ders, + int order) + : atoms(a), md(mod_ders) +{ + md.clear(); + for (int iord = 1; iord <= order; iord++) { + FSSparseTensor* t = new FSSparseTensor(iord, atoms.ny()+atoms.nys()+atoms.nyss()+atoms.nexo(), atoms.ny()); + md.insert(t); + } +} +void DynareDerEvalLoader::load(int i, int iord, const int* vars, double res) +{ + FSSparseTensor* t = md.get(Symmetry(iord)); + IntSequence s(iord, 0); + for (int j = 0; j < iord; j++) + s[j] = atoms.get_pos_of_all(vars[j]); + t->insert(s, i, res); +} + +DynareJacobian::DynareJacobian(Dynare& dyn) + : Jacobian(dyn.ny()), d(dyn) +{ + zeros(); +} + +void DynareJacobian::eval(const Vector& yy) +{ + ogdyn::DynareSteadyAtomValues + dav(d.getModel().getAtoms(), d.getModel().getParams(), yy); + zeros(); + d.fde->eval(dav, *this, 1); +} + +void DynareJacobian::load(int i, int iord, const int* vars, double res) +{ + if (iord != 1) + throw DynareException(__FILE__, __LINE__, + "Derivative order different from order=1 in DynareJacobian::load"); + + int t = vars[0]; + int j = d.getModel().getAtoms().get_pos_of_all(t); + if (j < d.nyss()) + get(i, j+d.nstat()+d.npred()) += res; + else if (j < d.nyss()+d.ny()) + get(i, j-d.nyss()) += res; + else if (j < d.nyss()+d.ny()+d.nys()) + get(i, j-d.nyss()-d.ny()+d.nstat()) += res; +} +*///////////////// + +/**************************** +* K-Order Perturbation instance of Jacobian: +************************************/ +KordpJacobian::KordpJacobian(KordpDynare& dyn) + : Jacobian(dyn.ny()), kdyn(dyn) +{ + zeros(); +} + +void KordpJacobian::eval(const Vector& yy) +{ +/// ogdyn::DynareSteadyAtomValues + dav(kdyn.getModel().getAtoms(), kdyn.getParams(), yy); + zeros(); + d.fde->eval(dav, *this, 1); +} + +void KordpJacobian::load(int i, int iord, const int* vars, double res) +{ + if (iord != 1) + throw DynareException(__FILE__, __LINE__, + "Derivative order different from order=1 in KordpDynareJacobian::load"); + + int t = vars[0]; + int j = d.getModel().getAtoms().get_pos_of_all(t); + if (j < d.nyss()) + get(i, j+d.nstat()+d.npred()) += res; + else if (j < d.nyss()+d.ny()) + get(i, j-d.nyss()) += res; + else if (j < d.nyss()+d.ny()+d.nys()) + get(i, j-d.nyss()-d.ny()+d.nstat()) += res; +} +///////////////// + + +void KordpDynareVectorFunction::eval(const ConstVector& in, Vector& out) +{ + check_for_eval(in, out); + Vector xx(d.nexog()); + xx.zeros(); + d.evaluateSystem(out, in, xx); +} + diff --git a/mex/sources/korderpert/src/k_ord_dynare.h b/mex/sources/korderpert/src/k_ord_dynare.h new file mode 100644 index 000000000..4a48d6ac5 --- /dev/null +++ b/mex/sources/korderpert/src/k_ord_dynare.h @@ -0,0 +1,241 @@ +/* Dynare is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Dynare 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 Dynare. If not, see . + */ +// based on: $Id: dynare3.h 1764 2008-03-31 14:30:55Z kamenik $ +// Copyright 2005, Ondra Kamenik + +#ifndef K_ORD_DYNARE3_H +#define K_ORD_DYNARE3_H + +#include "Dynare_pp/tl/cc/t_container.h" +#include "Dynare_pp/tl/cc/sparse_tensor.h" +#include "Dynare_pp/kord/decision_rule.h" +#include "Dynare_pp/kord/dynamic_model.h" + +#include "nlsolve.h" + +#include "k_ord_dynare_model.h" + +#include + +class Dynare; + + +// instantiations of pure abstract class NameList in dynamic_model.h: +/*//////////////////////////////////////////// +class DynareNameList : public NameList { + vector names; +public: + DynareNameList(const Dynare& dynare); + int getNum() const + {return (int)names.size();} + const char* getName(int i) const + {return names[i];} + /** This for each string of the input vector calculates its index + * in the names. And returns the resulting vector of indices. If + * the name cannot be found, then an exception is raised. * + vector selectIndices(const vector& ns) const; +}; + +class DynareExogNameList : public NameList { + vector names; +public: + DynareExogNameList(const Dynare& dynare); + int getNum() const + {return (int)names.size();} + const char* getName(int i) const + {return names[i];} +}; + +class DynareStateNameList : public NameList { + vector names; +public: + DynareStateNameList(const Dynare& dynare, const DynareNameList& dnl, + const DynareExogNameList& denl); + int getNum() const + {return (int)names.size();} + const char* getName(int i) const + {return names[i];} +}; +*********************************************/ +// The following only implements DynamicModel with help of ogdyn::DynareModel +// instantiation of pure abstract DynamicModel decl. in dynamic_model.h +class DynareJacobian; +class Dynare : public DynamicModel { +/* friend class DynareNameList; + friend class DynareExogNameList; + friend class DynareStateNameList; + friend class DynareJacobian; +*////////// + const int nStat; + const int nBoth; + const int nPred; + const int nForw; + const int nExog; + const int nPar; + const int nYs; + const int nYss; + const int nY; + const int nOrder; +/// Journal& journal; +/// ogdyn::DynareModel* model; +/// DynamicModel* model; + const char* modName; + Vector* ysteady; + Vector* params; + TensorContainer md; +/// DynareNameList* dnl; +/// DynareExogNameList* denl; +/// DynareStateNameList* dsnl; + + TwoDMatrix* Vcov; + TensorContainer* ModelDerivatives; + +/// ogp::FormulaEvaluator* fe; +/// ogp::FormulaDerEvaluator* fde; + const double ss_tol; +public: + /** Parses the given model file and uses the given order to + * override order from the model file (if it is != -1). */ +/// Dynare(const char* modname, int ord, double sstol, Journal& jr); + /** Parses the given equations with explicitly given names. */ +/*///Dynare(const char** endo, int num_endo, + const char** exo, int num_exo, + const char** par, int num_par, + const char* equations, int len, int ord, + double sstol, Journal& jr); +*/ Dynare(const char** endo, int num_endo, + const char** exo, int num_exo, + const char** par, int num_par, + const char** modName, int len, int ord, + double sstol, Journal& jr); + /** Makes a deep copy of the object. */ + Dynare(const Dynare& dyn); + DynamicModel* clone() const + {return new Dynare(*this);} + virtual ~Dynare(); + int nstat() const + {return nStat;} + int nboth() const + {return nBoth;} + int npred() const + {return nPred;} + int nforw() const + {return nForw;} + int nexog() const + {return nExo;} + int nys() const + {return nYs;} + int nyss() const + {return nYss;} + int ny() const + {return nY;} + int order() const + {return nOrder;} +/**** + const NameList& getAllEndoNames() const + {return *dnl;} + const NameList& getStateNames() const + {return *dsnl;} + const NameList& getExogNames() const + {return *denl;} +********/ + TwoDMatrix& getVcov() + {return Vcov;} +/// const TwoDMatrix& getVcov() const +/// {return model->getVcov();} + Vector& getParams() + {return params;} +/// const Vector& getParams() const +/// {return model->getParams();} +// void setInitOuter(const Vector& x) +// {model->setInitOuter(x);} + + const TensorContainer& getModelDerivatives() const + {return md;} + const Vector& getSteady() const + {return *ysteady;} + Vector& getSteady() + {return *ysteady;} +/// const ogdyn::DynareModel& getModel() const +/// {return *model;} + + // here is true public interface + void solveDeterministicSteady(Vector& steady); + void solveDeterministicSteady() + {solveDeterministicSteady(*ysteady);} + void evaluateSystem(Vector& out, const Vector& yy, const Vector& xx); + void evaluateSystem(Vector& out, const Vector& yym, const Vector& yy, + const Vector& yyp, const Vector& xx); + void calcDerivatives(const Vector& yy, const Vector& xx); + void calcDerivativesAtSteady(); + +/// void writeMat4(FILE* fd, const char* prefix) const; +/// void writeDump(const std::string& basename) const; +private: + void writeModelInfo(Journal& jr) const; +}; + +/********************* + +class DynareJacobian : public ogu::Jacobian ///, public ogp::FormulaDerEvalLoader +{ +protected: + Dynare& d; +public: + DynareJacobian(Dynare& dyn); + virtual ~DynareJacobian() {} + void load(int i, int iord, const int* vars, double res); + void eval(const Vector& in); +}; +************////////// +/**************************** +* K-Order Perturbation instance of Jacobian: +************************************/ + +class KordpJacobian : public ogu::Jacobian ///, public ogp::FormulaDerEvalLoader +{ +protected: + KordpDynare& kdyn; +public: + KordpJacobian( KordpDynare& dyn); + virtual ~KordpJacobian() {} + // Load _dynamic.DLL + void load(const char** modName); + void eval(const Vector& in); +}; + + +/**************************** +* K-Order Perturbation instance of VectorFunction: +************************************/ + +class KordpVectorFunction : public ogu::VectorFunction { +protected: + KordpDynare& d; +public: + KordpVectorFunction( KordpDynare& dyn) + : d(dyn) {} + virtual ~KordpVectorFunction() {} + int inDim() const + {return d.ny();} + int outDim() const + {return d.ny();} + void eval(const ConstVector& in, Vector& out); +}; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/mex/sources/korderpert/src/k_order_perturbation.cpp b/mex/sources/korderpert/src/k_order_perturbation.cpp new file mode 100644 index 000000000..1be0771d5 --- /dev/null +++ b/mex/sources/korderpert/src/k_order_perturbation.cpp @@ -0,0 +1,247 @@ +/* Dynare is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Dynare 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 Dynare. If not, see . + */ + +// k_order_perturbation.cpp : Defines the entry point for the DLL application. +// + +#include "stdafx.h" + +#include "k_order_perturbation.h" +#include "k_order_dynare.h" +#include "math.h" +#include "mex.h" + +//#include "kord/approximation.h" + +/* +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + + +// This is an example of an exported variable +K_ORDER_PERTURBATION_API int nK_order_perturbation=0; + +// This is an example of an exported function. +K_ORDER_PERTURBATION_API int fnK_order_perturbation(void) +{ + return 42; +} + +// This is the constructor of a class that has been exported. +// see k_order_perturbation.h for the class definition +CK_order_perturbation::CK_order_perturbation() +{ + return; +} + +*/ + +extern "C" { + void mexFunction(int nlhs, mxArray* plhs[], + int nrhs, const mxArray* prhs[]) + { + if (nrhs < 3) + mexErrMsgTxt("Must have at least 3 input parameters.\n"); + if (nlhs == 0) + mexErrMsgTxt("Must have at least 1 output parameter.\n"); + +/* int order = (int)mxGetScalar(prhs[0]); + if (nrhs != 12 + order) { + mexErrMsgTxt("Must have exactly 11+order input parameters.\n"); +// return; + } +*/ +// const mxArray* const aa = prhs[0]; +/* const mxArray* rhs1in = (prhs[0]); + mxArray* rhs1[1];// = rhs1in; + rhs1[0] = const_cast (rhs1in); +*/ +// const mxArray* const mFname = prhs[1]; +// const char* mFname = mxArrayToString(prhs[nrhs-1]); + + char* mFname = mxArrayToString(prhs[nrhs-1]); + + + double *y, *x, *params; + double *residual, *g1, *g2; + int nb_row_x, it_; + + /* Create a pointer to the input matrix y. */ + y = mxGetPr(prhs[0]); + + /* Create a pointer to the input matrix x. */ + x = mxGetPr(prhs[1]); + + /* Create a pointer to the input matrix params. */ + params = mxGetPr(prhs[2]); + + /* Fetch time index */ + it_ = (int) mxGetScalar(prhs[3]) - 1; + + /* Gets number of rows of matrix x. */ + nb_row_x = mxGetM(prhs[1]); + + residual = NULL; + if (nlhs >= 1) + { + /* Set the output pointer to the output matrix residual. */ + plhs[0] = mxCreateDoubleMatrix(16,1, mxREAL); + /* Create a C pointer to a copy of the output matrix residual. */ + residual = mxGetPr(plhs[0]); + } + + g1 = NULL; + if (nlhs >= 2) + { + /* Set the output pointer to the output matrix g1. */ + plhs[1] = mxCreateDoubleMatrix(16, 31, mxREAL); + /* Create a C pointer to a copy of the output matrix g1. */ + g1 = mxGetPr(plhs[1]); + } + + g2 = NULL; + if (nlhs >= 3) + { + /* Set the output pointer to the output matrix g2. */ + plhs[2] = mxCreateDoubleMatrix(16, 961, mxREAL); + /* Create a C pointer to a copy of the output matrix g1. */ + g2 = mxGetPr(plhs[2]); + } + + /* Call the C subroutines. */ + + + +/* + int nstat = (int)mxGetScalar(prhs[1]); + int npred = (int)mxGetScalar(prhs[2]); + int nboth = (int)mxGetScalar(prhs[3]); + int nforw = (int)mxGetScalar(prhs[4]); + int nexog = (int)mxGetScalar(prhs[5]); + + const mxArray* const ystart = prhs[6]; + const mxArray* const shocks = prhs[7]; + const mxArray* const vcov = prhs[8]; + int seed = (int)mxGetScalar(prhs[9]); + const mxArray* const ysteady = prhs[10]; + const int* const ystart_dim = mxGetDimensions(ystart); + const int* const shocks_dim = mxGetDimensions(shocks); + const int* const vcov_dim = mxGetDimensions(vcov); + const int* const ysteady_dim = mxGetDimensions(ysteady); + + int ny = nstat + npred + nboth + nforw; + if (ny != ystart_dim[0]) + mexErrMsgTxt("ystart has wrong number of rows.\n"); + if (1 != ystart_dim[1]) + mexErrMsgTxt("ystart has wrong number of cols.\n"); + int nper = shocks_dim[1]; + if (nexog != shocks_dim[0]) + mexErrMsgTxt("shocks has a wrong number of rows.\n"); + if (nexog != vcov_dim[0]) + mexErrMsgTxt("vcov has a wrong number of rows.\n"); + if (nexog != vcov_dim[1]) + mexErrMsgTxt("vcov has a wrong number of cols.\n"); + if (ny != ysteady_dim[0]) + mexErrMsgTxt("ysteady has wrong number of rows.\n"); + if (1 != ysteady_dim[1]) + mexErrMsgTxt("ysteady has wrong number of cols.\n"); +*/ +// mxArray* res = mxCreateDoubleMatrix(ny, nper, mxREAL); +/* + try { + + // Call int mexCallMATLAB(int nlhs, mxArray *plhs[], int nrhs, + // mxArray *prhs[], const char *name); + int success = mexCallMATLAB( nlhs, plhs, nrhs-1, rhs1 , mFname); +// int success = mexCallMATLAB( nlhs, plhs, nrhs-1, (struct mxArray *[]) &aa , mFname); + //plhs[0] = res; + + + + + } catch (...) { + mexErrMsgTxt("Err: Unknown error in Call MATLAB function .\n"); + mexPrintf("MexPrintf: Unknown error in Call MATLAB function %s.\n", mFname); + return; + } +*/ +// basic_string sFname(mFname); + using namespace std; + string sFname(mFname); + string sExt("_.dll"); + mexPrintf("MexPrintf: Call exp %d.\n", y[0]); + double dd = exp(y[0]); + mexPrintf("MexPrintf: exp (%d)= %d .\n", y[0],dd); + + try { +// typedef void * (__stdcall *DynamicFn)(); + typedef void * (DynamicFn) + (double *y, double *x, int nb_row_x, double *params, + int it_, double *residual, double *g1, double *g2); + HINSTANCE DynamicHinstance; + //DynamicFn * pDynamicFn; + mexPrintf("MexPrintf: Call Load run DLL %s .\n", mFname); +// DynamicHinstance=::LoadLibraryEx(strcat(mFname,"_.dll"),NULL,DONT_RESOLVE_DLL_REFERENCES);//sExt); //"_.dll"); + DynamicHinstance=::LoadLibrary(strcat(mFname,"_.dll"));//sExt); //"_.dll"); + if (DynamicHinstance==NULL) + //return; + throw 1; +// typedef void * (__stdcall *DynamicFn)(); + mexPrintf("MexPrintf: 2nd Call exp %d.\n", y[1]); + double dd = exp(y[1]); + mexPrintf("MexPrintf: exp (%d)= %d .\n", y[1],dd); + + mexPrintf("MexPrintf: Call GetProcAddress %s .\n", mFname); + DynamicFn * pDynamicFn = + (DynamicFn*) ::GetProcAddress(DynamicHinstance,"Dynamic"); + if (pDynamicFn == NULL) + //return; + throw 2; + mexPrintf("MexPrintf: Call Dynamic %s .\n", mFname); +// void * objptr = (*pDynamicFn)(y, x, nb_row_x, params, it_, residual, g1, g2); + try{ + (*pDynamicFn)(y, x, nb_row_x, params, it_, residual, g1, g2); +// if (objptr == NULL) + //return; + }catch (...){ + DWORD dw = GetLastError(); + mexPrintf("MexPrintf: error in Call Dynamic DLL %s, %d\n", mFname, dw); + throw 3; + } + + } catch (int i) { + mexPrintf("MexPrintf: error in Load and run DLL %s , %d.\n", mFname, i); + mexErrMsgTxt("Err: An error in Load and run DLL .\n"); + return; + + } catch (...) { + mexPrintf("MexPrintf: Unknown error in Call MATLAB function %s.\n", mFname); + mexErrMsgTxt("Err: Unknown error in Load and run DLL .\n"); + return; + } + } +} \ No newline at end of file diff --git a/mex/sources/korderpert/src/k_order_perturbation.h b/mex/sources/korderpert/src/k_order_perturbation.h new file mode 100644 index 000000000..909b2ef48 --- /dev/null +++ b/mex/sources/korderpert/src/k_order_perturbation.h @@ -0,0 +1,47 @@ +/* Dynare is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Dynare 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 Dynare. If not, see . + */ + +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the K_ORDER_PERTURBATION_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// K_ORDER_PERTURBATION_API functions as being imported from a DLL, wheras this DLL sees symbols +// defined with this macro as being exported. + + +#ifdef K_ORDER_PERTURBATION_EXPORTS +#define K_ORDER_PERTURBATION_API __declspec(dllexport) +#else +#define K_ORDER_PERTURBATION_API __declspec(dllimport) +#endif + + +#include + +// This class is exported from the k_order_perturbation.dll +//class K_ORDER_PERTURBATION_API CK_order_perturbation { +//public: +// CK_order_perturbation(void); + // TODO: add your methods here. + +//extern void Dynamic(double *y, double *x, int nb_row_x, double *params, int it_, double *residual, double *g1, double *g2); + + + +//}; + +//extern K_ORDER_PERTURBATION_API int nK_order_perturbation; + +//K_ORDER_PERTURBATION_API int fnK_order_perturbation(void); +