text:
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Conversion Utility for ASCII, UTF8 and USC2 (Unicode) character sets
//
// See RFC2279 for reference
//
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#include "gsCommon.h"
#include "gsStringUtil.h"

#ifdef __cplusplus
extern "C" {
#endif

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Reads UCS2 character from UTF8String
//
// [in]		theUTF8String	:	UTF8String, doesn't need to be null terminated
// [out]	theUCS2Char		:	The 2 byte UCS2 equivalent
// [in]     theMaxLength    :   Maximum number of *bytes* to read (not UTF8 characters)
//
// return value				:	The number of bytes read from theUTF8String
//                              0 = error when parsing
//
//  Remarks:
//		If theUTF8String is invalid, theUnicodeChar will be set to '?'
//		Function is designed for convenient parsing of UTF8 data streams
//
//	Security Concern:
//		Because data is routed through an ASCII stream prior to this function being
//		called, embedded NULLs are stripped and hence, this function does not check for them
//		For example, the UTF-8 byte :1000 0000, would convert to a UCS2 NULL character
//		If this appeared in the middle of a stream, it could cause undesired operation
int _ReadUCS2CharFromUTF8String(const UTF8String theUTF8String,  UCS2Char* theUnicodeChar, int theMaxLength)
{
#ifndef _PS2
	assert(theUnicodeChar != NULL);
#endif

	if (theMaxLength == 0)
	{
		// assert?
		*theUnicodeChar = (UCS2Char)REPLACE_INVALID_CHAR;
		return 0; // not enough data
	}

	// Check for normal ascii range (includes NULL terminator)
	if (UTF8_IS_SINGLE_BYTE(theUTF8String[0]))
	{
		// ASCII, just copy the value
		*theUnicodeChar = (UCS2Char)theUTF8String[0];
		return 1;
	}

	// Check for 2 byte UTF8
	else if (UTF8_IS_TWO_BYTE(theUTF8String[0]))
	{
		if (theMaxLength < 2)
		{
			*theUnicodeChar = (UCS2Char)REPLACE_INVALID_CHAR;
			return 0; // not enough data
		}

		// Make sure the second byte is valid
		if (UTF8_IS_FOLLOW_BYTE(theUTF8String[1]))
		{
			// Construct 11 bit unicode character
			//		5 value bits from first UTF8Byte			(:000ABCDE)
			//		plus 6 value bits from the second UTF8Byte	(:00FGHIJK)
			//	Store as (:0000 0ABC DEFG HIJK)
			*theUnicodeChar  =	(unsigned short)(((theUTF8String[0] & UTF8_TWO_BYTE_MASK) << 6) +
								((theUTF8String[1] & UTF8_FOLLOW_BYTE_MASK)));
			return 2;
		}
	}

	// Check for 3 byte UTF8
	else if (UTF8_IS_THREE_BYTE(theUTF8String[0]))
	{
		if (theMaxLength < 3)
		{
			*theUnicodeChar = (UCS2Char)REPLACE_INVALID_CHAR;
			return 0; // not enough data
		}

		// Make sure the second and third bytes are valid
		if (UTF8_IS_FOLLOW_BYTE(theUTF8String[1]) &&
			UTF8_IS_FOLLOW_BYTE(theUTF8String[2]))
		{
			// Construct 16 bit unicode character
			//		4 value bits from first UTF8Byte			(:0000ABCD)
			//		plus 6 value bits from the second UTF8Byte	(:00EFGHIJ)
			//		plus 6 value bits from the third  UTF8Byte	(:00KLMNOP)
			//	Store as (:ABCD EFGH IJKL MNOP)
			*theUnicodeChar  =	(unsigned short)(((theUTF8String[0] & UTF8_THREE_BYTE_MASK) << 12) +
								((theUTF8String[1] & UTF8_FOLLOW_BYTE_MASK) << 6) +
								((theUTF8String[2] & UTF8_FOLLOW_BYTE_MASK)));
			return 3;
		}
	}

	// Invalid character, replace with '?' and return false
	*theUnicodeChar = (UCS2Char)REPLACE_INVALID_CHAR;

	// The second byte on could have been the start of a new valid UTF8 character
	// so we can only safely discard one invalid character
	return 1;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Converts UCS2 (Unicode) character into UTF8String
//
// [in]		theUCS2Char		:	The 2 byte character to convert
// [out]	theUTF8String	:	The 1-3 byte UTF8 equivalent
//
// return value				:	The length of theUTF8String in bytes
//
//  Remarks:
//		theUTF8String may be up to 3 bytes, caller is responsible for allocating memory
//		theUTF8String is NOT NULL terminated,
int _UCS2CharToUTF8String(UCS2Char theUCS2Char, UTF8String theUTF8String)
{
#ifndef _PS2
	assert(theUTF8String != NULL);
#endif

	// Screen out simple ascii (includes NULL terminator)
	if (theUCS2Char <= 0x7F)
	{
		// 0-7 bit unicode, copy stright over
		theUTF8String[0] = (char)(UTF8ByteType)theUCS2Char;
		return 1;
	}
	else if (theUCS2Char <= 0x07FF)
	{
		// 8-11 bits unicode, store as two byte UTF8
		// :00000ABC DEFGHIJK
		// :110ABCDE 10FGHIJK
		theUTF8String[0] = (char)(UTF8ByteType)(UTF8_TWO_BYTE_TAG | (theUCS2Char >> 6));				// Store the upper 5/11 bits as 0x110xxxxx
		theUTF8String[1] = (char)(UTF8ByteType)(UTF8_FOLLOW_BYTE_TAG | (theUCS2Char & UTF8_FOLLOW_BYTE_MASK));	// Store the lower 6 bits as 0x10xxxxxx
		return 2;
	}
	else
	{
		// 12-16 bits unicode, store as three byte UTF8
		// :ABCDEFGH IJKLMNOP
		// :1110ABCD 10EFGHIJ 10KLMNOP
		theUTF8String[0] = (char)(UTF8ByteType)(UTF8_THREE_BYTE_TAG |  (theUCS2Char >> 12));					// Store the upper 4/16 bits as 0x1110xxxx
		theUTF8String[1] = (char)(UTF8ByteType)(UTF8_FOLLOW_BYTE_TAG | ((theUCS2Char >> 6) & UTF8_FOLLOW_BYTE_MASK));	// Store the 5th-10th bits as 0x10xxxxxx
		theUTF8String[2] = (char)(UTF8ByteType)(UTF8_FOLLOW_BYTE_TAG | ((theUCS2Char) & UTF8_FOLLOW_BYTE_MASK));			// Store the last 6 bits as 0x10xxxxxx
		return 3;
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert an ASCII string to UTF8
//
//  Since an ASCII string IS a valid UTF8 string, just copy and return
//
//  [in]	theAsciiString, NULL terminated c-string
//  [out]	theUTF8String, NULL terminated UTF8String
//
//  returns the length of theUTF8String
int AsciiToUTF8String(const char* theAsciiString, UTF8String theUTF8String)
{
	// Allow for NULL here since SDKs allow for NULL string arrays
	if (theAsciiString == NULL)
	{
		*theUTF8String = 0x00;
		return 1;
	}
	else
	{
		// Copy the string, keeping track of length
		unsigned int aLength = 0;
		while (*theAsciiString != '\0')
		{
			*(theUTF8String++) = *(theAsciiString++);
			aLength++;
		}

		// Append the null
		*theUTF8String = '\0';
		aLength++;

		return (int)aLength;
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert a UTF8String to it's ASCII equivalent
//
//  [in]	theUTF8String, NULL terminated UTF8String
//	[out]	theAsciiString, NULL terminated c-string
//
//  returns the length of theAsciiString
//
//	  Remarks:
//		Unvalid ASCII characters are replaced with '?'
//		Memory allocated for theAsciiString may need to be as large as the UTF8String
//		UTF8String will be NULL terminated
int UTF8ToAsciiString(const UTF8String theUTF8String, char* theAsciiString)
{
	// Strip non-ascii characters and replace with REPLACE_INVALID_CHAR
	const unsigned char* anInStream = (const unsigned char*)theUTF8String;
	unsigned int   aNumBytesWritten = 0;

	// Allow for NULL here since SDKs allow for NULL string arrays
	if (theUTF8String == NULL)
	{
		*theAsciiString = 0x00;
		return 1;
	}

	// Keep extracting characters until we get a '\0'
	while (*anInStream != '\0')
	{
		if (UTF8_IS_SINGLE_BYTE(*anInStream))
			theAsciiString[aNumBytesWritten++] = (char)*anInStream;
		else
			theAsciiString[aNumBytesWritten++] = REPLACE_INVALID_CHAR;

		// move to next character
		anInStream++;
	}

	// Append the '\0'
	theAsciiString[aNumBytesWritten++] = '\0';
	return (int)aNumBytesWritten;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert a UCS2 (Unicode) string to it's UTF8 equivalent
//
//  [in]	theUCS2String, double NULL terminated UTF8String
//	[out]	theUTF8String, NULL terminated c-string
//
//  returns the length of theUTF8String
//
//	  Remarks:
//		Memory allocated for theUTF8String may need to be up to 1.5* the size of theUCS2String
//      This means that for each UCS2 character, 3 UTF8 characters may be generated
int UCS2ToUTF8String(const UCS2String theUCS2String, UTF8String theUTF8String)
{
	unsigned int	aTotalBytesWritten	= 0;
	unsigned int	aUTF8CharLength		= 0;
	const UCS2Char*	anInStream			= theUCS2String;
	unsigned char*	anOutStream			= (unsigned char*)theUTF8String;

	// Allow for NULL here since SDKs allow for NULL string parameters
	if (theUCS2String == NULL)
	{
		*anOutStream = 0x00;
		return 1;
	}

	// Loop until we reach a NULL terminator
	while(*anInStream != 0)
	{
		aUTF8CharLength = (unsigned int)_UCS2CharToUTF8String(*anInStream, (UTF8String)anOutStream);

		// Move out stream to next character position
		anOutStream += aUTF8CharLength;

		// Move to next UCS2 character
		anInStream++;

		// Record number of bytes written
		aTotalBytesWritten += aUTF8CharLength;
	}

	// Copy over the null terminator
	*anOutStream = '\0';
	aTotalBytesWritten++;

	return (int)aTotalBytesWritten;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert a UTF8 string to it's UCS2 (Unicode) equivalent
//
//  [in]	theUTF8String, NULL terminated UTF8String
//	[out]	theUCS2String, NULL terminated c-string
//
//  returns the length of theUCS2String
//
//	  Remarks:
//		Unvalid UTF8 characters are replaced with '?'
//		Memory allocated for theAsciiString may need to be as large as the UTF8String
//		UTF8String will be NULL terminated
int UTF8ToUCS2String(const UTF8String theUTF8String, UCS2String theUCS2String)
{
	return UTF8ToUCS2StringLen(theUTF8String, theUCS2String, (gsi_i32)strlen(theUTF8String));
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Calculate the size needed to convert a UTF8String to a UCS2String
//
//  [in]	theUTF8String, NULL terminated UTF8String
//
//  returns the length (in UCS2 characters) of theUCS2String that would be created
//
//	  Remarks:
//		Unvalid UTF8 characters are treated as 1 byte
int _UTF8ToUCS2ConversionLengthOnly(const UTF8String theUTF8String)
{
	int length = 0;
	const UTF8String theReadPos = theUTF8String;

	assert(theUTF8String != NULL);
	if (theUTF8String == NULL)
		return 0;

	while (*theReadPos != '\0')
	{
		// Check for valid two byte string
		if (UTF8_IS_TWO_BYTE(theReadPos[0]) && UTF8_IS_FOLLOW_BYTE(theReadPos[1]))
			theReadPos += 2;

		// Check for valid three byte string
		else if (UTF8_IS_THREE_BYTE(theReadPos[0]) &&
				 UTF8_IS_FOLLOW_BYTE(theReadPos[1]) &&
				 UTF8_IS_FOLLOW_BYTE(theReadPos[2]))
		{
			theReadPos += 3;
		}
		// Anything else means one UTF8 character read from the buffer
		else
			theReadPos++;

		// Increment the length of the UCS2 string
		length++;
	}

	// don't count the null as a character, this conforms
	// with ANSI strlen functions
	return length;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Calculate the size needed to convert a UCS2String to a UTF8String
//
//  [in]	theUCS2String, NULL terminated UCS2String
//
//  returns the length of theUTF8String that would be created
//
//	  Remarks:
//		Unvalid UTF8 characters are treated as 1 byte
int _UCS2ToUTF8ConversionLengthOnly(const UCS2String theUCS2String)
{
	int length = 0;
	const UCS2String theReadPos = theUCS2String;
	assert(theUCS2String != NULL);
	while (*theReadPos != 0x0000)
	{
		// Values <= 0x7F are single byte ascii
		if (*theReadPos <= 0x7F)
			length++;
		// Values > 0x7F and <= 0x07FF are two bytes in UTF8
		else if (*theReadPos <= 0x07FF)
			length += 2;
		// Anything else is 3 bytes of UTF8
		else
			length += 3;

		// Set read pos to right spot (1 more UCS2 Character = 2 bytes)
		theReadPos++;
	}

	// don't count the null as a character, this conforms
	// with ANSI strlen functions
	return length;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert a UTF8String to a UCS2String, allocate space for the UCS2String
//
//  [in]	theUTF8String, NULL terminated UTF8String
//
//  returns the newly allocated UCS2String
//
//	  Remarks:
//		The callee is responsible for freeing the allocated memory block
UCS2String UTF8ToUCS2StringAlloc(const UTF8String theUTF8String)
{
	// Allow for NULL here since SDKs allow for NULL string parameters
	if (theUTF8String == NULL)
		return NULL;
	else
	{
		// Find the length of the UCS2 string and allocate a block
		int newLength = _UTF8ToUCS2ConversionLengthOnly(theUTF8String);
		UCS2String aUCS2String = (UCS2String)gsimalloc(sizeof(UCS2Char)*(newLength + 1));

		// Do the conversion
		UTF8ToUCS2String(theUTF8String, aUCS2String);

		// Return the allocated string
		return aUCS2String;
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert a UCS2String to a UTF8String, allocate space for the UTF8String
//
//  [in]	UCS2String, NULL terminated UCS2String
//
//  returns the newly allocated UTF8String
//
//	  Remarks:
//		The callee is responsible for freeing the allocated memory block
UTF8String UCS2ToUTF8StringAlloc(const UCS2String theUCS2String)
{
	// Allow for NULL here since SDKs allow for NULL string parameters
	if (theUCS2String == NULL)
		return NULL;
	else
	{
		// Find the length of the UCS2 string and allocate a block
		int newLength			= _UCS2ToUTF8ConversionLengthOnly(theUCS2String);
		UTF8String aUTF8String	= (UTF8String)gsimalloc(sizeof(char)*(newLength + 1));

		// Do the conversion
		UCS2ToUTF8String(theUCS2String, aUTF8String);

		// Return the allocated string
		return aUTF8String;
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert a UTF8StringArray to a UCS2StringArray, allocate space for the UCS2Strings
//
//  [in]	UTF8StringArray, array of NULL terminated UTF8Strings
//  [in]	theNumStrings, how many strings are in the array
//
//  returns the newly allocated UCS2StringArray
//
//	  Remarks:
//		The callee is responsible for freeing the allocated memory block(s)
UCS2String* UTF8ToUCS2StringArrayAlloc(const UTF8String* theUTF8StringArray, int theNumStrings)
{
	// Allow for NULL here since SDKs allow for NULL string arrays
	if(theUTF8StringArray == NULL || theNumStrings == 0)
		return NULL;
	else
	{
		UCS2String* aUCS2StringArray = (UCS2String*)gsimalloc(sizeof(UCS2String)*theNumStrings);
		int stringNum = 0;
		while(stringNum < theNumStrings)
		{
			aUCS2StringArray[stringNum] = UTF8ToUCS2StringAlloc(theUTF8StringArray[stringNum]);
			stringNum++;
		}

		return aUCS2StringArray;
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert a UCS2StringArray to a UTF8StringArray, allocate space for the UTF8Strings
//
//  [in]	UCS2StringArray, array of NULL terminated UCS2Strings
//  [in]	theNumStrings, how many strings are in the array
//
//  returns the newly allocated UTF8StringArray
//
//	  Remarks:
//		The callee is responsible for freeing the allocated memory block
UTF8String* UCS2ToUTF8StringArrayAlloc(const UCS2String* theUCS2StringArray, int theNumStrings)
{
	// Allow for NULL here since SDKs allow for NULL string arrays
	if (theUCS2StringArray == NULL || theNumStrings == 0)
		return NULL;
	else
	{
		UTF8String* aUTF8StringArray = (UTF8String*)gsimalloc(sizeof(UTF8String)*theNumStrings);
		int stringNum = 0;
		while(stringNum < theNumStrings)
		{
			aUTF8StringArray[stringNum] = UCS2ToUTF8StringAlloc(theUCS2StringArray[stringNum]);
			stringNum++;
		}

		return aUTF8StringArray;
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert a UCS2String to an AsciiString
//
//  [in]		UCS2StringArray, NULL terminated UCS2String
//  [in/out]	theAsciiString, ascii representation
//
//  returns the length of the Ascii string
//
//	  Remarks:
//		callee is responsible for allocating memory for theAsciiString
//		Invalid ASCII characters are truncated
//		The ASCII buffer must be at least 1/2 the size of the UCS2String
int UCS2ToAsciiString(const UCS2String theUCS2String, char* theAsciiString)
{
	int length = 0;
	const UCS2String aReadPos = theUCS2String;
	char* aWritePos = theAsciiString;

	assert(theAsciiString != NULL);

	// Allow for NULL here since SDKs allow for NULL string arrays
	if (theUCS2String == NULL)
	{
		*theAsciiString = '\0';
		return 1;
	}

	// Convert each character until a '\0' is reached
	while(*aReadPos != '\0')
	{
		(*aWritePos++) = (char)(0x00FF & (*aReadPos++));
		length++;
	}

	// append the NULL
	*aWritePos = '\0';
	length++;

	return length;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert an ASCII string to a UCS2String
//
//  [in]		theAsciiString, NULL terminated ASCII string
//  [in/out]	theUCS2String, UCS2String to be filled with the converted ASCII
//
//  returns the length of the unicode string
//
//	  Remarks:
//		The callee is responsible for allocating memory for theUCS2String
//		the size returned should always be 2x the size passed in
int AsciiToUCS2String(const char* theAsciiString, UCS2String theUCS2String)
{
	int length = 0;
	const char* aReadPos = theAsciiString;
	UCS2String aWritePos = theUCS2String;

	assert(theUCS2String != NULL);

	// Allow for NULL here since SDKs allow for NULL string arrays
	if (theAsciiString == NULL)
	{
		*theUCS2String = 0x0000;
		return 1;
	}

	// Convert each character until a '\0' is reached
	while(*aReadPos != '\0')
	{
		(*aWritePos++) = (unsigned short)(0x00FF & (*aReadPos++)); // copy and strip extra byte
		length++;
	}

	// append a NULL terminator to the UCS2String
	*aWritePos = '\0';
	length++;

	return length;
}

/*
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert a UCS2String to a UTF8String with a maximum length
//
//  [in]     theUCS2String, NULL terminated UCS2String
//  [in/out] theUTF8String, The UTF8 equivilent of theUCS2String
//  [in]     theMaxLength, maximum number of UTF8 characters to write
//
//  returns the length of the UTF8String
//
//	  Remarks:
//		The length of theUTF8String will not exceed theMaxLength supplied.
int UCS2ToUTF8StringLength(const UCS2String theUCS2String, UTF8String theUTF8String, int theMaxLength)
{
	return 0;
}
*/

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Convert a UTF8String to a UCS2String with a maximum length
//
//  [in]     theUTF8String, NULL terminated UTF8String
//  [in/out] theUCS2String, The UCS2 equivilent of theUTF8String
//  [in]     theMaxLength, maximum number of UTF8 characters to write
//
//  returns the length of the UCS2String
//
//	  Remarks:
//		The length of theUCS2String will not exceed theMaxLength supplied.
int UTF8ToUCS2StringLen(const UTF8String theUTF8String, UCS2String theUCS2String, int theMaxLength)
{
	int aNumCharsWritten	= 0;
	int aNumBytesRead		= 0;
	int aTotalBytesRead     = 0;
	const unsigned char* anInStream	= (const unsigned char*)theUTF8String;
	UCS2Char*            anOutStream= theUCS2String;

	// Allow for NULL here since SDKs allow for NULL string arrays
	if (theUTF8String == NULL)
	{
		*anOutStream = 0x0000;
		return 1;
	}

	// Loop until we find the NULL terminator
	while (*anInStream != '\0' && theMaxLength > aTotalBytesRead)
	{
		// Convert one character
		aNumBytesRead = _ReadUCS2CharFromUTF8String((UTF8String)anInStream, anOutStream, theMaxLength-aTotalBytesRead);
		if (aNumBytesRead == 0)
		{
			// Error, read past end of buffer
			theUCS2String[0] = 0x0000;
			return 0;
		}
		aTotalBytesRead += aNumBytesRead;

		// Move InStream position to new data
		anInStream += aNumBytesRead;

		// Keep track of characters written
		aNumCharsWritten++;

		// Move OutStream to next write position
		anOutStream++;
	}

	// NULL terminate the UCS2String
	*anOutStream = 0x0000;
	aNumCharsWritten++;

	return aNumCharsWritten;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
} //extern "C"
#endif


text:
import numpy as np
from _solve_lines import fast_mag_chain_nu, derivative_passing, \
                    mag_chain_uncoupled, mag_chain_uncoupled_derivative, \
                    fast_mag_chain_uncoupled, cython_mag_mag_error, cython_mag
from scipy import optimize
from math import atanh, tanh

# -------Coupled lines: solving Ising model for one projection -----------

def solve_line(field, Js, y, big_field=15, hext=None):
    """
    Solve Ising chain

    Parameters
    ----------

    field: 1-d ndarray
        Local field on the spins

    Js: float
        Coupling between spins

    y: float
        Sum of the spins (value of the projection)

    big_field: float

    hext: float
        Lagrange multiplier in order to impose the sum of the magnetizations

    Returns
    -------

    hloc: 1-d ndarray, same shape as field
        local magnetization (with the Onsager term removed)
    """
    # Handle large fields
    mask_blocked = np.abs(field) > big_field
    field[mask_blocked] = big_field * np.sign(field[mask_blocked])
    if np.all(mask_blocked) and np.abs(np.sign(field).sum() - y) < 0.1:
        return 0.5 * field, hext
    # Solve Ising chain
    hloc, hext = _solve_canonical_h(field, Js, y, hext)
    mask_blocked = np.abs(hloc) > big_field
    hloc[mask_blocked] = big_field * np.sign(hloc[mask_blocked])
    # Remove initial field
    hloc -= field
    return hloc, hext

def _solve_canonical_h(h, J, y, hext=None):
    """
    Solve Ising chain in the canonical formulation.

    Parameters
    ----------

    h: 1-d ndarray of floats
        local field

    y: total magnetization

    J: 1-d ndarray of floats
        coupling between spins

    hext: float
        Lagrange multiplier in order to impose the sum of the magnetizations

    Returns
    -------

    hloc: 1-d ndarray of floats
        local magnetization
    """
    epsilon = .05
    if hext is None or np.isnan(hext):
        hext = 0
    hext = 0
    N = float(len(h))
    y = min(y, N)
    y = max(y, -N)
    mag_tot, hloc = _mag_chain(h, J, hext, full_output=True)
    if abs(mag_tot - y) < epsilon:
        return hloc, hext
    if mag_tot < y:
        hmin = 0
        hext = 8
        while y - _mag_chain(h, J, hext) > epsilon:
            hmin = hext
            hext *= 2
        hmax = hext
    else:
        hmax = 0
        hext = -8
        while _mag_chain(h, J, hext) - y > epsilon:
            hmax = hext
            hext *= 2
        hmin = hext
    mag_tot = 2 * N
    iter_nb = 1
    # dichotomy
    while abs(mag_tot - y) > epsilon and iter_nb < 200:
        iter_nb += 1
        hext = 0.5 * (hmin + hmax)
        mag_tot, hloc = _mag_chain(h, J, hext, full_output=True)
        if mag_tot < y:
            hmin = hext
        else:
            hmax = hext
    return hloc, hext

def _mag_chain(h, J, hext, full_output=False):
    """
    Compute the total magnetization for an Ising chain.
    Use the cython function fast_mag_chain_nu

    Parameters
    ----------

    h: 1-d ndarray of floats
        local field

    J: 1-d ndarray
        couplings between spins

    hext: float
        global field
    """
    magtot, hloc = fast_mag_chain_nu(h, J, hext)
    if full_output:
        return magtot, hloc
    else:
        return magtot

# ------------------- Uncoupled lines (no interaction between neighbors)------

def solve_uncoupled_line(field, y, big_field=15, hext=None):
    """
    Solve Ising chain

    Parameters
    ----------

    field: 1-d ndarray
        Local field on the spins

    y: float
        Sum of the spins (value of the projection)

    big_field: float
        Largest possible value of the external field, in order to
        avoid overflow problems. It's not clear yet whether it should be
        large or not.

    Returns
    -------

    hext: float
        External field (Lagrange multiplier)

    Notes
    -----

    The returned value hext solves

        sum_i tanh(field[i] + hext) = y

    For now a bisection method is used, with some care taken to avoid
    overflow.

    TODO: use the previous value of hext, in some cases it might be possible
    to use newton's methods to converge faster.
    """
    if abs(y) >= len(field) - 0.5:
        return np.sign(y) * big_field
    # Handle large fields
    mask_blocked = np.abs(field) > big_field
    field[mask_blocked] = big_field * np.sign(field[mask_blocked])
    if hext is None:
        hext = 0
    # Solve Ising chain
    hext = _bisect_mag(field, y, big_field)
    #hext = bisect_field(field, y, hext, tol=0.2)
    return hext

def _bisect_mag(field, y, big_field):
    mag = np.tanh(field)
    magsup = tanh(big_field)
    try:
        Mext = optimize.brentq(cython_mag_mag_error, -magsup, magsup,
                            xtol=1.e-2, args=(mag, y))
    except ValueError:
        if cython_mag_mag_error(magsup, mag, y) > 0:
            return big_field
        elif cython_mag_mag_error(- magsup, mag, y) < 0:
            return -big_field
    return atanh(Mext)

def _mag_chain_uncoupled_error(hext, hi, y):
    return mag_chain_uncoupled(hi, hext) - y

def _bisect_field(field, y, hext, tol=0.1):
    niter_max = 30
    l = float(len(field))
    err_init =  _mag_chain_uncoupled_error(hext, field, y)
    dx = 10
    if err_init < 0:
        vmin = hext
        vmax = - field.min() + atanh(y/l) + 0.1
        dx = 0.5 * (vmax - vmin)
    else:
        vmin = - field.max() + atanh(y/l) - 0.1
        vmax = hext
        dx = 0.5 * (vmax - vmin)
    i = 0
    while i < niter_max:
        xm = vmin + dx
        err = _mag_chain_uncoupled_error(xm, field, y)
        if abs(err) < tol:
            return xm
        if err <= 0:
            vmin = xm
        dx *= 0.5
        i += 1
    if i == niter_max:
        raise ValueError

# ---------------------- Unused functions (to be removed?) ---------------

def mag_chain_deriv(h, J, hext):
    """
    Compute the total magnetization for an Ising chain.
    Use the cython function fast_mag_chain_nu

    Parameters
    ----------

    h: 1-d ndarray of floats
        local field

    J: 1-d ndarray
        couplings between spins

    hext: float
        global field
    """
    magtot, deriv, hloc = derivative_passing(h, J, hext)
    return magtot, deriv, hloc

def solve_canonical_h_newton(h, J, y, hext_init=None):
    """
    Solve Ising chain in the canonical formulation.

    Use Newton's method when the initial guess is close enough.

    Parameters
    ----------

    h: 1-d ndarray of floats
        local field

    J: 1-d ndarray of floats
        coupling between spins

    y: float
        total magnetization

    hext_init: float
        initial guess

    Returns
    -------

    hloc: 1-d ndarray of floats
        local magnetization
    """
    if hext_init is None:
        hext_init = np.sign(y)
    epsilon = .05
    N = len(h)
    y = min(y, N)
    y = max(y, -N)
    hext = hext_init
    mag_tot, deriv_mag_tot, hloc = mag_chain_deriv(h, J, hext)
    iter_nb = 1
    dicho = False
    dmax = 1  # heuristic, 1 or 1.5?
    # First, use the dichotomy if we are too far from the expected result
    if np.abs(mag_tot - y) > dmax or deriv_mag_tot < 1.e-5 or abs(hext) > 6.5:
        dicho = True
        # Search bounds for the dichotomy
        if mag_tot < y:
            hmin = hext
            hext = max(8, hext + 1)
            mag_tot = _mag_chain(h, J, hext)
            while y - mag_tot > epsilon:
                hmin = hext
                hext *= 2
                mag_tot = _mag_chain(h, J, hext)
            hmax = hext
        else:
            hmax = hext
            hext = min(-8, hext - 1)
            mag_tot = _mag_chain(h, J, hext)
            while mag_tot - y > epsilon:
                hmax = hext
                hext *= 2
                mag_tot = _mag_chain(h, J, hext)
            hmin = hext
        # dichotomy
        while (abs(mag_tot - y) > epsilon and
              (abs(mag_tot - y) > dmax or
               np.abs(hext) > 6.5) and iter_nb < 200):
            iter_nb += 1
            hext = 0.5 * (hmin + hmax)
            mag_tot, hloc = _mag_chain(h, J, hext, full_output=True)
            if mag_tot < y:
                hmin = hext
            else:
                hmax = hext
    iter_first = iter_nb
    if iter_first > 20:
        print "iter too much"
    iter_nb = 0
    # Now that we are close enough, we use Newton's method
    if dicho is False and deriv_mag_tot > 0:
        hext -= (mag_tot - y) / deriv_mag_tot
    while abs(mag_tot - y) > epsilon and iter_nb < 40:
        mag_tot, deriv_mag_tot, hloc = mag_chain_deriv(h, J, hext)
        if deriv_mag_tot == 0:
            raise ValueError
        hext -= (mag_tot - y) / deriv_mag_tot
        iter_nb += 1
    return hloc, hext

redpajama_set_name: RedPajamaGithub


text:
@import Foundation;

@interface DummyCarDoor : NSObject

@property (nonatomic) NSString *doorName;

@end


text:
class CreateFollows < ActiveRecord::Migration[5.0]
  def change
    create_table :follows do |t|
      t.integer :follower_id
      t.integer :followed_id

      add_foreign_key :follows, :user, column: :follower_id
      add_foreign_key :follows, :user, column: :followed_id
    end
  end
end


text:
"""Definition of various recurrent neural network cells."""
from __future__ import print_function

import warnings
import functools

from .. import symbol, init, ndarray
from ..base import string_types, numeric_types

def _cells_state_shape(cells):
    return sum([c.state_shape for c in cells], [])

def _cells_state_info(cells):
    return sum([c.state_info for c in cells], [])

def _cells_begin_state(cells, **kwargs):
    return sum([c.begin_state(**kwargs) for c in cells], [])

def _cells_unpack_weights(cells, args):
    for cell in cells:
        args = cell.unpack_weights(args)
    return args

def _cells_pack_weights(cells, args):
    for cell in cells:
        args = cell.pack_weights(args)
    return args

def _normalize_sequence(length, inputs, layout, merge, in_layout=None):
    assert inputs is not None, \
        "unroll(inputs=None) has been deprecated. " \
        "Please create input variables outside unroll."

    axis = layout.find('T')
    in_axis = in_layout.find('T') if in_layout is not None else axis
    if isinstance(inputs, symbol.Symbol):
        if merge is False:
            assert len(inputs.list_outputs()) == 1, \
                "unroll doesn't allow grouped symbol as input. Please convert " \
                "to list with list(inputs) first or let unroll handle splitting."
            inputs = list(symbol.split(inputs, axis=in_axis, num_outputs=length,
                                       squeeze_axis=1))
    else:
        assert length is None or len(inputs) == length
        if merge is True:
            inputs = [symbol.expand_dims(i, axis=axis) for i in inputs]
            inputs = symbol.Concat(*inputs, dim=axis)
            in_axis = axis

    if isinstance(inputs, symbol.Symbol) and axis != in_axis:
        inputs = symbol.swapaxes(inputs, dim0=axis, dim1=in_axis)

    return inputs, axis

class RNNParams(object):
    """Container for holding variables.
    Used by RNN cells for parameter sharing between cells.

    Parameters
    ----------
    prefix : str
        Names of all variables created by this container will
        be prepended with prefix.
    """
    def __init__(self, prefix=''):
        self._prefix = prefix
        self._params = {}

    def get(self, name, **kwargs):
        """Get the variable given a name if one exists or create a new one if missing.

        Parameters
        ----------
        name : str
            name of the variable
        **kwargs :
            more arguments that's passed to symbol.Variable
        """
        name = self._prefix + name
        if name not in self._params:
            self._params[name] = symbol.Variable(name, **kwargs)
        return self._params[name]

class BaseRNNCell(object):
    """Abstract base class for RNN cells

    Parameters
    ----------
    prefix : str, optional
        Prefix for names of layers
        (this prefix is also used for names of weights if `params` is None
        i.e. if `params` are being created and not reused)
    params : RNNParams, default None.
        Container for weight sharing between cells.
        A new RNNParams container is created if `params` is None.
    """
    def __init__(self, prefix='', params=None):
        if params is None:
            params = RNNParams(prefix)
            self._own_params = True
        else:
            self._own_params = False
        self._prefix = prefix
        self._params = params
        self._modified = False

        self.reset()

    def reset(self):
        """Reset before re-using the cell for another graph."""
        self._init_counter = -1
        self._counter = -1
        if hasattr(self, '_cells'):
            for cell in self._cells:
                cell.reset()

    def __call__(self, inputs, states):
        """Unroll the RNN for one time step.

        Parameters
        ----------
        inputs : sym.Variable
            input symbol, 2D, batch * num_units
        states : list of sym.Variable
            RNN state from previous step or the output of begin_state().

        Returns
        -------
        output : Symbol
            Symbol corresponding to the output from the RNN when unrolling
            for a single time step.
        states : nested list of Symbol
            The new state of this RNN after this unrolling.
            The type of this symbol is same as the output of begin_state().
            This can be used as input state to the next time step
            of this RNN.

        See Also
        --------
        begin_state: This function can provide the states for the first time step.
        unroll: This function unrolls an RNN for a given number of (>=1) time steps.
        """
        raise NotImplementedError()

    @property
    def params(self):
        """Parameters of this cell"""
        self._own_params = False
        return self._params

    @property
    def state_info(self):
        """shape and layout information of states"""
        raise NotImplementedError()

    @property
    def state_shape(self):
        """shape(s) of states"""
        return [ele['shape'] for ele in self.state_info]

    @property
    def _gate_names(self):
        """name(s) of gates"""
        return ()

    def begin_state(self, func=symbol.zeros, **kwargs):
        """Initial state for this cell.

        Parameters
        ----------
        func : callable, default symbol.zeros
            Function for creating initial state. Can be symbol.zeros,
            symbol.uniform, symbol.Variable etc.
            Use symbol.Variable if you want to directly
            feed input as states.
        **kwargs :
            more keyword arguments passed to func. For example
            mean, std, dtype, etc.

        Returns
        -------
        states : nested list of Symbol
            Starting states for the first RNN step.
        """
        assert not self._modified, \
            "After applying modifier cells (e.g. DropoutCell) the base " \
            "cell cannot be called directly. Call the modifier cell instead."
        states = []
        for info in self.state_info:
            self._init_counter += 1
            if info is None:
                state = func(name='%sbegin_state_%d'%(self._prefix, self._init_counter),
                             **kwargs)
            else:
                kwargs.update(info)
                state = func(name='%sbegin_state_%d'%(self._prefix, self._init_counter),
                             **kwargs)
            states.append(state)
        return states

    def unpack_weights(self, args):
        """Unpack fused weight matrices into separate
        weight matrices.

        For example, say you use a module object `mod` to run a network that has an lstm cell.
        In `mod.get_params()[0]`, the lstm parameters are all represented as a single big vector.
        `cell.unpack_weights(mod.get_params()[0])` will unpack this vector into a dictionary of
        more readable lstm parameters - c, f, i, o gates for i2h (input to hidden) and
        h2h (hidden to hidden) weights.

        Parameters
        ----------
        args : dict of str -> NDArray
            Dictionary containing packed weights.
            usually from `Module.get_params()[0]`.

        Returns
        -------
        args : dict of str -> NDArray
            Dictionary with unpacked weights associated with
            this cell.

        See Also
        --------
        pack_weights: Performs the reverse operation of this function.
        """
        args = args.copy()
        if not self._gate_names:
            return args
        h = self._num_hidden
        for group_name in ['i2h', 'h2h']:
            weight = args.pop('%s%s_weight'%(self._prefix, group_name))
            bias = args.pop('%s%s_bias' % (self._prefix, group_name))
            for j, gate in enumerate(self._gate_names):
                wname = '%s%s%s_weight' % (self._prefix, group_name, gate)
                args[wname] = weight[j*h:(j+1)*h].copy()
                bname = '%s%s%s_bias' % (self._prefix, group_name, gate)
                args[bname] = bias[j*h:(j+1)*h].copy()
        return args

    def pack_weights(self, args):
        """Pack separate weight matrices into a single packed
        weight.

        Parameters
        ----------
        args : dict of str -> NDArray
            Dictionary containing unpacked weights.

        Returns
        -------
        args : dict of str -> NDArray
            Dictionary with packed weights associated with
            this cell.
        """
        args = args.copy()
        if not self._gate_names:
            return args
        for group_name in ['i2h', 'h2h']:
            weight = []
            bias = []
            for gate in self._gate_names:
                wname = '%s%s%s_weight'%(self._prefix, group_name, gate)
                weight.append(args.pop(wname))
                bname = '%s%s%s_bias'%(self._prefix, group_name, gate)
                bias.append(args.pop(bname))
            args['%s%s_weight'%(self._prefix, group_name)] = ndarray.concatenate(weight)
            args['%s%s_bias'%(self._prefix, group_name)] = ndarray.concatenate(bias)
        return args

    def unroll(self, length, inputs, begin_state=None, layout='NTC', merge_outputs=None):
        """Unroll an RNN cell across time steps.

        Parameters
        ----------
        length : int
            Number of steps to unroll.
        inputs : Symbol, list of Symbol, or None
            If `inputs` is a single Symbol (usually the output
            of Embedding symbol), it should have shape
            (batch_size, length, ...) if layout == 'NTC',
            or (length, batch_size, ...) if layout == 'TNC'.

            If `inputs` is a list of symbols (usually output of
            previous unroll), they should all have shape
            (batch_size, ...).
        begin_state : nested list of Symbol, default None
            Input states created by `begin_state()`
            or output state of another cell.
            Created from `begin_state()` if None.
        layout : str, optional
            `layout` of input symbol. Only used if inputs
            is a single Symbol.
        merge_outputs : bool, optional
            If False, return outputs as a list of Symbols.
            If True, concatenate output across time steps
            and return a single symbol with shape
            (batch_size, length, ...) if layout == 'NTC',
            or (length, batch_size, ...) if layout == 'TNC'.
            If None, output whatever is faster.

        Returns
        -------
        outputs : list of Symbol or Symbol
            Symbol (if `merge_outputs` is True) or list of Symbols
            (if `merge_outputs` is False) corresponding to the output from
            the RNN from this unrolling.

        states : nested list of Symbol
            The new state of this RNN after this unrolling.
            The type of this symbol is same as the output of begin_state().
        """
        self.reset()

        inputs, _ = _normalize_sequence(length, inputs, layout, False)
        if begin_state is None:
            begin_state = self.begin_state()

        states = begin_state
        outputs = []
        for i in range(length):
            output, states = self(inputs[i], states)
            outputs.append(output)

        outputs, _ = _normalize_sequence(length, outputs, layout, merge_outputs)

        return outputs, states

    #pylint: disable=no-self-use
    def _get_activation(self, inputs, activation, **kwargs):
        """Get activation function. Convert if is string"""
        if isinstance(activation, string_types):
            return symbol.Activation(inputs, act_type=activation, **kwargs)
        else:
            return activation(inputs, **kwargs)

class RNNCell(BaseRNNCell):
    """Simple recurrent neural network cell.

    Parameters
    ----------
    num_hidden : int
        Number of units in output symbol.
    activation : str or Symbol, default 'tanh'
        Type of activation function. Options are 'relu' and 'tanh'.
    prefix : str, default ``'rnn_'``
        Prefix for name of layers (and name of weight if params is None).
    params : RNNParams, default None
        Container for weight sharing between cells. Created if None.
    """
    def __init__(self, num_hidden, activation='tanh', prefix='rnn_', params=None):
        super(RNNCell, self).__init__(prefix=prefix, params=params)
        self._num_hidden = num_hidden
        self._activation = activation
        self._iW = self.params.get('i2h_weight')
        self._iB = self.params.get('i2h_bias')
        self._hW = self.params.get('h2h_weight')
        self._hB = self.params.get('h2h_bias')

    @property
    def state_info(self):
        return [{'shape': (0, self._num_hidden), '__layout__': 'NC'}]

    @property
    def _gate_names(self):
        return ('',)

    def __call__(self, inputs, states):
        self._counter += 1
        name = '%st%d_'%(self._prefix, self._counter)
        i2h = symbol.FullyConnected(data=inputs, weight=self._iW, bias=self._iB,
                                    num_hidden=self._num_hidden,
                                    name='%si2h'%name)
        h2h = symbol.FullyConnected(data=states[0], weight=self._hW, bias=self._hB,
                                    num_hidden=self._num_hidden,
                                    name='%sh2h'%name)
        output = self._get_activation(i2h + h2h, self._activation,
                                      name='%sout'%name)

        return output, [output]

class LSTMCell(BaseRNNCell):
    """Long-Short Term Memory (LSTM) network cell.

    Parameters
    ----------
    num_hidden : int
        Number of units in output symbol.
    prefix : str, default ``'lstm_'``
        Prefix for name of layers (and name of weight if params is None).
    params : RNNParams, default None
        Container for weight sharing between cells. Created if None.
    forget_bias : bias added to forget gate, default 1.0.
        Jozefowicz et al. 2015 recommends setting this to 1.0
    """
    def __init__(self, num_hidden, prefix='lstm_', params=None, forget_bias=1.0,
                 cublas_algo_verbose=False, cublas_off=False, cublas_tensor_core=None,
                 cublas_algo_fwd=None, cublas_algo_bwd_data=None, cublas_algo_bwd_weights=None,
                 cublas_algo_fwd_prec='None', cublas_algo_bwd_prec='None'):
        super(LSTMCell, self).__init__(prefix=prefix, params=params)

        self._num_hidden = num_hidden
        # parameters to give detailed control over internal GEMM behavior
        self._cublas_algo_verbose = cublas_algo_verbose
        self._cublas_off = cublas_off
        self._cublas_tensor_core = cublas_tensor_core
        self._cublas_algo_fwd = cublas_algo_fwd
        self._cublas_algo_bwd_data = cublas_algo_bwd_data
        self._cublas_algo_bwd_weights = cublas_algo_bwd_weights
        self._cublas_algo_fwd_prec = cublas_algo_fwd_prec
        self._cublas_algo_bwd_prec = cublas_algo_bwd_prec
        self._iW = self.params.get('i2h_weight')
        self._hW = self.params.get('h2h_weight')
        # we add the forget_bias to i2h_bias, this adds the bias to the forget gate activation
        self._iB = self.params.get('i2h_bias', init=init.LSTMBias(forget_bias=forget_bias))
        self._hB = self.params.get('h2h_bias')

    @property
    def state_info(self):
        return [{'shape': (0, self._num_hidden), '__layout__': 'NC'},
                {'shape': (0, self._num_hidden), '__layout__': 'NC'}]

    @property
    def _gate_names(self):
        return ['_i', '_f', '_c', '_o']

    def __call__(self, inputs, states):
        self._counter += 1
        name = '%st%d_'%(self._prefix, self._counter)
        i2h = symbol.FullyConnected(data=inputs, weight=self._iW, bias=self._iB,
                                    num_hidden=self._num_hidden*4,
                                    name='%si2h'%name,
                                    cublas_algo_verbose=self._cublas_algo_verbose,
                                    cublas_off=self._cublas_off,
                                    cublas_tensor_core=self._cublas_tensor_core,
                                    cublas_algo_fwd=self._cublas_algo_fwd,
                                    cublas_algo_bwd_data=self._cublas_algo_bwd_data,
                                    cublas_algo_bwd_weights=self._cublas_algo_bwd_weights,
                                    cublas_algo_fwd_prec=self._cublas_algo_fwd_prec,
                                    cublas_algo_bwd_prec=self._cublas_algo_bwd_prec)
        h2h = symbol.FullyConnected(data=states[0], weight=self._hW, bias=self._hB,
                                    num_hidden=self._num_hidden*4,
                                    name='%sh2h'%name,
                                    cublas_algo_verbose=self._cublas_algo_verbose,
                                    cublas_off=self._cublas_off,
                                    cublas_tensor_core=self._cublas_tensor_core,
                                    cublas_algo_fwd=self._cublas_algo_fwd,
                                    cublas_algo_bwd_data=self._cublas_algo_bwd_data,
                                    cublas_algo_bwd_weights=self._cublas_algo_bwd_weights,
                                    cublas_algo_fwd_prec=self._cublas_algo_fwd_prec,
                                    cublas_algo_bwd_prec=self._cublas_algo_bwd_prec)
        gates = i2h + h2h
        slice_gates = symbol.SliceChannel(gates, num_outputs=4,
                                          name="%sslice"%name)
        in_gate = symbol.Activation(slice_gates[0], act_type="sigmoid",
                                    name='%si'%name)
        forget_gate = symbol.Activation(slice_gates[1], act_type="sigmoid",
                                        name='%sf'%name)
        in_transform = symbol.Activation(slice_gates[2], act_type="tanh",
                                         name='%sc'%name)
        out_gate = symbol.Activation(slice_gates[3], act_type="sigmoid",
                                     name='%so'%name)
        next_c = symbol._internal._plus(forget_gate * states[1], in_gate * in_transform,
                                        name='%sstate'%name)
        next_h = symbol._internal._mul(out_gate, symbol.Activation(next_c, act_type="tanh"),
                                       name='%sout'%name)

        return next_h, [next_h, next_c]

class GRUCell(BaseRNNCell):
    """Gated Rectified Unit (GRU) network cell.
    Note: this is an implementation of the cuDNN version of GRUs
    (slight modification compared to Cho et al. 2014).

    Parameters
    ----------
    num_hidden : int
        Number of units in output symbol.
    prefix : str, default ``'gru_'``
        Prefix for name of layers (and name of weight if params is None).
    params : RNNParams, default None
        Container for weight sharing between cells. Created if None.
    """
    def __init__(self, num_hidden, prefix='gru_', params=None):
        super(GRUCell, self).__init__(prefix=prefix, params=params)
        self._num_hidden = num_hidden
        self._iW = self.params.get("i2h_weight")
        self._iB = self.params.get("i2h_bias")
        self._hW = self.params.get("h2h_weight")
        self._hB = self.params.get("h2h_bias")

    @property
    def state_info(self):
        return [{'shape': (0, self._num_hidden),
                 '__layout__': 'NC'}]

    @property
    def _gate_names(self):
        return ['_r', '_z', '_o']

    def __call__(self, inputs, states):
        # pylint: disable=too-many-locals
        self._counter += 1

        seq_idx = self._counter
        name = '%st%d_' % (self._prefix, seq_idx)
        prev_state_h = states[0]

        i2h = symbol.FullyConnected(data=inputs,
                                    weight=self._iW,
                                    bias=self._iB,
                                    num_hidden=self._num_hidden * 3,
                                    name="%s_i2h" % name)
        h2h = symbol.FullyConnected(data=prev_state_h,
                                    weight=self._hW,
                                    bias=self._hB,
                                    num_hidden=self._num_hidden * 3,
                                    name="%s_h2h" % name)

        i2h_r, i2h_z, i2h = symbol.SliceChannel(i2h, num_outputs=3, name="%s_i2h_slice" % name)
        h2h_r, h2h_z, h2h = symbol.SliceChannel(h2h, num_outputs=3, name="%s_h2h_slice" % name)

        reset_gate = symbol.Activation(i2h_r + h2h_r, act_type="sigmoid",
                                       name="%s_r_act" % name)
        update_gate = symbol.Activation(i2h_z + h2h_z, act_type="sigmoid",
                                        name="%s_z_act" % name)

        next_h_tmp = symbol.Activation(i2h + reset_gate * h2h, act_type="tanh",
                                       name="%s_h_act" % name)

        next_h = symbol._internal._plus((1. - update_gate) * next_h_tmp, update_gate * prev_state_h,
                                        name='%sout' % name)

        return next_h, [next_h]

class FusedRNNCell(BaseRNNCell):
    """Fusing RNN layers across time step into one kernel.
    Improves speed but is less flexible. Currently only
    supported if using cuDNN on GPU.

    Parameters
    ----------
    num_hidden : int
        Number of units in output symbol.
    num_layers : int, default 1
        Number of layers in the cell.
    mode : str, default 'lstm'
        Type of RNN. options are 'rnn_relu', 'rnn_tanh', 'lstm', 'gru'.
    bidirectional : bool, default False
        Whether to use bidirectional unroll. The output dimension size is doubled if bidrectional.
    dropout : float, default 0.
        Fraction of the input that gets dropped out during training time.
    get_next_state : bool, default False
        Whether to return the states that can be used as starting states next time.
    forget_bias : bias added to forget gate, default 1.0.
        Jozefowicz et al. 2015 recommends setting this to 1.0
    prefix : str, default ``'$mode_'`` such as ``'lstm_'``
        Prefix for names of layers
        (this prefix is also used for names of weights if `params` is None
        i.e. if `params` are being created and not reused)
    params : RNNParams, default None
        Container for weight sharing between cells. Created if None.
    """
    def __init__(self, num_hidden, num_layers=1, mode='lstm', bidirectional=False,
                 dropout=0., get_next_state=False, forget_bias=1.0,
                 prefix=None, params=None,
                 cudnn_algo_verbose=False,
                 cudnn_algo=-1,
                 cudnn_tensor_core=None):
        if prefix is None:
            prefix = '%s_'%mode
        super(FusedRNNCell, self).__init__(prefix=prefix, params=params)
        self._num_hidden = num_hidden
        self._num_layers = num_layers
        self._mode = mode
        self._bidirectional = bidirectional
        self._dropout = dropout
        self._get_next_state = get_next_state
        self._directions = ['l', 'r'] if bidirectional else ['l']
        self._cudnn_algo_verbose = cudnn_algo_verbose
        self._cudnn_algo = cudnn_algo
        self._cudnn_tensor_core = cudnn_tensor_core

        initializer = init.FusedRNN(None, num_hidden, num_layers, mode,
                                    bidirectional, forget_bias,
                                    cudnn_algo_verbose, cudnn_algo, cudnn_tensor_core)
        self._parameter = self.params.get('parameters', init=initializer)

    @property
    def state_info(self):
        b = self._bidirectional + 1
        n = (self._mode == 'lstm') + 1
        return [{'shape': (b*self._num_layers, 0, self._num_hidden), '__layout__': 'LNC'}
                for _ in range(n)]

    @property
    def _gate_names(self):
        return {'rnn_relu': [''],
                'rnn_tanh': [''],
                'lstm': ['_i', '_f', '_c', '_o'],
                'gru': ['_r', '_z', '_o']}[self._mode]

    @property
    def _num_gates(self):
        return len(self._gate_names)

    def _slice_weights(self, arr, li, lh):
        """slice fused rnn weights"""
        args = {}
        gate_names = self._gate_names
        directions = self._directions

        b = len(directions)
        p = 0
        for layer in range(self._num_layers):
            for direction in directions:
                for gate in gate_names:
                    name = '%s%s%d_i2h%s_weight'%(self._prefix, direction, layer, gate)
                    if layer > 0:
                        size = b*lh*lh
                        args[name] = arr[p:p+size].reshape((lh, b*lh))
                    else:
                        size = li*lh
                        args[name] = arr[p:p+size].reshape((lh, li))
                    p += size
                for gate in gate_names:
                    name = '%s%s%d_h2h%s_weight'%(self._prefix, direction, layer, gate)
                    size = lh**2
                    args[name] = arr[p:p+size].reshape((lh, lh))
                    p += size

        for layer in range(self._num_layers):
            for direction in directions:
                for gate in gate_names:
                    name = '%s%s%d_i2h%s_bias'%(self._prefix, direction, layer, gate)
                    args[name] = arr[p:p+lh]
                    p += lh
                for gate in gate_names:
                    name = '%s%s%d_h2h%s_bias'%(self._prefix, direction, layer, gate)
                    args[name] = arr[p:p+lh]
                    p += lh

        assert p == arr.size, "Invalid parameters size for FusedRNNCell"
        return args

    def unpack_weights(self, args):
        args = args.copy()
        arr = args.pop(self._parameter.name)
        b = len(self._directions)
        m = self._num_gates
        h = self._num_hidden
        num_input = arr.size//b//h//m - (self._num_layers - 1)*(h+b*h+2) - h - 2

        nargs = self._slice_weights(arr, num_input, self._num_hidden)
        args.update({name: nd.copy() for name, nd in nargs.items()})
        return args

    def pack_weights(self, args):
        args = args.copy()
        b = self._bidirectional + 1
        m = self._num_gates
        c = self._gate_names
        h = self._num_hidden
        w0 = args['%sl0_i2h%s_weight'%(self._prefix, c[0])]
        num_input = w0.shape[1]
        total = (num_input+h+2)*h*m*b + (self._num_layers-1)*m*h*(h+b*h+2)*b

        arr = ndarray.zeros((total,), ctx=w0.context, dtype=w0.dtype)
        for name, nd in self._slice_weights(arr, num_input, h).items():
            nd[:] = args.pop(name)
        args[self._parameter.name] = arr
        return args

    def __call__(self, inputs, states):
        raise NotImplementedError("FusedRNNCell cannot be stepped. Please use unroll")

    def unroll(self, length, inputs, begin_state=None, layout='NTC', merge_outputs=None):
        self.reset()

        inputs, axis = _normalize_sequence(length, inputs, layout, True)
        if axis == 1:
            warnings.warn("NTC layout detected. Consider using "
                          "TNC for FusedRNNCell for faster speed")
            inputs = symbol.swapaxes(inputs, dim1=0, dim2=1)
        else:
            assert axis == 0, "Unsupported layout %s"%layout
        if begin_state is None:
            begin_state = self.begin_state()

        states = begin_state
        if self._mode == 'lstm':
            states = {'state': states[0], 'state_cell': states[1]} # pylint: disable=redefined-variable-type
        else:
            states = {'state': states[0]}

        rnn = symbol.RNN(data=inputs, parameters=self._parameter,
                         state_size=self._num_hidden, num_layers=self._num_layers,
                         bidirectional=self._bidirectional, p=self._dropout,
                         state_outputs=self._get_next_state,
                         mode=self._mode, name=self._prefix+'rnn',
                         cudnn_algo_verbose=self._cudnn_algo_verbose,
                         cudnn_algo=self._cudnn_algo,
                         **states)

        attr = {'__layout__' : 'LNC'}
        if not self._get_next_state:
            outputs, states = rnn, []
        elif self._mode == 'lstm':
            rnn[1]._set_attr(**attr)
            rnn[2]._set_attr(**attr)
            outputs, states = rnn[0], [rnn[1], rnn[2]]
        else:
            rnn[1]._set_attr(**attr)
            outputs, states = rnn[0], [rnn[1]]

        if axis == 1:
            outputs = symbol.swapaxes(outputs, dim1=0, dim2=1)

        outputs, _ = _normalize_sequence(length, outputs, layout, merge_outputs)

        return outputs, states

    def unfuse(self):
        """Unfuse the fused RNN in to a stack of rnn cells.

        Returns
        -------
        cell : mxnet.rnn.SequentialRNNCell
            unfused cell that can be used for stepping, and can run on CPU.
        """
        stack = SequentialRNNCell()
        get_cell = {'rnn_relu': lambda cell_prefix: RNNCell(self._num_hidden,
                                                            activation='relu',
                                                            prefix=cell_prefix),
                    'rnn_tanh': lambda cell_prefix: RNNCell(self._num_hidden,
                                                            activation='tanh',
                                                            prefix=cell_prefix),
                    'lstm': lambda cell_prefix: LSTMCell(self._num_hidden,
                                                         prefix=cell_prefix),
                    'gru': lambda cell_prefix: GRUCell(self._num_hidden,
                                                       prefix=cell_prefix)}[self._mode]
        for i in range(self._num_layers):
            if self._bidirectional:
                stack.add(BidirectionalCell(
                    get_cell('%sl%d_'%(self._prefix, i)),
                    get_cell('%sr%d_'%(self._prefix, i)),
                    output_prefix='%sbi_l%d_'%(self._prefix, i)))
            else:
                stack.add(get_cell('%sl%d_'%(self._prefix, i)))

            if self._dropout > 0 and i != self._num_layers - 1:
                stack.add(DropoutCell(self._dropout, prefix='%s_dropout%d_'%(self._prefix, i)))

        return stack

class SequentialRNNCell(BaseRNNCell):
    """Sequantially stacking multiple RNN cells.

    Parameters
    ----------
    params : RNNParams, default None
        Container for weight sharing between cells. Created if None.
    """
    def __init__(self, params=None):
        super(SequentialRNNCell, self).__init__(prefix='', params=params)
        self._override_cell_params = params is not None
        self._cells = []

    def add(self, cell):
        """Append a cell into the stack.

        Parameters
        ----------
        cell : BaseRNNCell
            The cell to be appended. During unroll, previous cell's output (or raw inputs if
            no previous cell) is used as the input to this cell.
        """
        self._cells.append(cell)
        if self._override_cell_params:
            assert cell._own_params, \
                "Either specify params for SequentialRNNCell " \
                "or child cells, not both."
            cell.params._params.update(self.params._params)
        self.params._params.update(cell.params._params)

    @property
    def state_info(self):
        return _cells_state_info(self._cells)

    def begin_state(self, **kwargs): # pylint: disable=arguments-differ
        assert not self._modified, \
            "After applying modifier cells (e.g. ZoneoutCell) the base " \
            "cell cannot be called directly. Call the modifier cell instead."
        return _cells_begin_state(self._cells, **kwargs)

    def unpack_weights(self, args):
        return _cells_unpack_weights(self._cells, args)

    def pack_weights(self, args):
        return _cells_pack_weights(self._cells, args)

    def __call__(self, inputs, states):
        self._counter += 1
        next_states = []
        p = 0
        for cell in self._cells:
            assert not isinstance(cell, BidirectionalCell)
            n = len(cell.state_info)
            state = states[p:p+n]
            p += n
            inputs, state = cell(inputs, state)
            next_states.append(state)
        return inputs, sum(next_states, [])

    def unroll(self, length, inputs, begin_state=None, layout='NTC', merge_outputs=None):
        self.reset()

        num_cells = len(self._cells)
        if begin_state is None:
            begin_state = self.begin_state()

        p = 0
        next_states = []
        for i, cell in enumerate(self._cells):
            n = len(cell.state_info)
            states = begin_state[p:p+n]
            p += n
            inputs, states = cell.unroll(length, inputs=inputs, begin_state=states, layout=layout,
                                         merge_outputs=None if i < num_cells-1 else merge_outputs)
            next_states.extend(states)

        return inputs, next_states

class DropoutCell(BaseRNNCell):
    """Apply dropout on input.

    Parameters
    ----------
    dropout : float
        Percentage of elements to drop out, which
        is 1 - percentage to retain.
    prefix : str, default ``'dropout_'``
        Prefix for names of layers
        (this prefix is also used for names of weights if `params` is None
        i.e. if `params` are being created and not reused)
    params : RNNParams, default None
        Container for weight sharing between cells. Created if None.
    """
    def __init__(self, dropout, prefix='dropout_', params=None):
        super(DropoutCell, self).__init__(prefix, params)
        assert isinstance(dropout, numeric_types), "dropout probability must be a number"
        self.dropout = dropout

    @property
    def state_info(self):
        return []

    def __call__(self, inputs, states):
        if self.dropout > 0:
            inputs = symbol.Dropout(data=inputs, p=self.dropout)
        return inputs, states

    def unroll(self, length, inputs, begin_state=None, layout='NTC', merge_outputs=None):
        self.reset()
        inputs, _ = _normalize_sequence(length, inputs, layout, merge_outputs)
        if isinstance(inputs, symbol.Symbol):
            return self(inputs, [])
        else:
            return super(DropoutCell, self).unroll(
                length, inputs, begin_state=begin_state, layout=layout,
                merge_outputs=merge_outputs)

class ModifierCell(BaseRNNCell):
    """Base class for modifier cells. A modifier
    cell takes a base cell, apply modifications
    on it (e.g. Zoneout), and returns a new cell.

    After applying modifiers the base cell should
    no longer be called directly. The modifer cell
    should be used instead.
    """
    def __init__(self, base_cell):
        super(ModifierCell, self).__init__()
        base_cell._modified = True
        self.base_cell = base_cell

    @property
    def params(self):
        self._own_params = False
        return self.base_cell.params

    @property
    def state_info(self):
        return self.base_cell.state_info

    def begin_state(self, init_sym=symbol.zeros, **kwargs): # pylint: disable=arguments-differ
        assert not self._modified, \
            "After applying modifier cells (e.g. DropoutCell) the base " \
            "cell cannot be called directly. Call the modifier cell instead."
        self.base_cell._modified = False
        begin = self.base_cell.begin_state(init_sym, **kwargs)
        self.base_cell._modified = True
        return begin

    def unpack_weights(self, args):
        return self.base_cell.unpack_weights(args)

    def pack_weights(self, args):
        return self.base_cell.pack_weights(args)

    def __call__(self, inputs, states):
        raise NotImplementedError

class ZoneoutCell(ModifierCell):
    """Apply Zoneout on base cell.

    Parameters
    ----------
    base_cell : BaseRNNCell
        Cell on whose states to perform zoneout.
    zoneout_outputs : float, default 0.
        Fraction of the output that gets dropped out during training time.
    zoneout_states : float, default 0.
        Fraction of the states that gets dropped out during training time.
    """
    def __init__(self, base_cell, zoneout_outputs=0., zoneout_states=0.):
        assert not isinstance(base_cell, FusedRNNCell), \
            "FusedRNNCell doesn't support zoneout. " \
            "Please unfuse first."
        assert not isinstance(base_cell, BidirectionalCell), \
            "BidirectionalCell doesn't support zoneout since it doesn't support step. " \
            "Please add ZoneoutCell to the cells underneath instead."
        assert not isinstance(base_cell, SequentialRNNCell) or not base_cell._bidirectional, \
            "Bidirectional SequentialRNNCell doesn't support zoneout. " \
            "Please add ZoneoutCell to the cells underneath instead."
        super(ZoneoutCell, self).__init__(base_cell)
        self.zoneout_outputs = zoneout_outputs
        self.zoneout_states = zoneout_states
        self.prev_output = None

    def reset(self):
        super(ZoneoutCell, self).reset()
        self.prev_output = None

    def __call__(self, inputs, states):
        cell, p_outputs, p_states = self.base_cell, self.zoneout_outputs, self.zoneout_states
        next_output, next_states = cell(inputs, states)
        mask = lambda p, like: symbol.Dropout(symbol.ones_like(like), p=p)

        prev_output = self.prev_output if self.prev_output is not None else symbol.zeros((0, 0))

        output = (symbol.where(mask(p_outputs, next_output), next_output, prev_output)
                  if p_outputs != 0. else next_output)
        states = ([symbol.where(mask(p_states, new_s), new_s, old_s) for new_s, old_s in
                   zip(next_states, states)] if p_states != 0. else next_states)

        self.prev_output = output

        return output, states

class ResidualCell(ModifierCell):
    """Adds residual connection as described in Wu et al, 2016
    (https://arxiv.org/abs/1609.08144).

    Output of the cell is output of the base cell plus input.

    Parameters
    ----------
    base_cell : BaseRNNCell
        Cell on whose outputs to add residual connection.
    """

    def __init__(self, base_cell):
        super(ResidualCell, self).__init__(base_cell)

    def __call__(self, inputs, states):
        output, states = self.base_cell(inputs, states)
        output = symbol.elemwise_add(output, inputs, name="%s_plus_residual" % output.name)
        return output, states

    def unroll(self, length, inputs, begin_state=None, layout='NTC', merge_outputs=None):
        self.reset()

        self.base_cell._modified = False
        outputs, states = self.base_cell.unroll(length, inputs=inputs, begin_state=begin_state,
                                                layout=layout, merge_outputs=merge_outputs)
        self.base_cell._modified = True

        merge_outputs = isinstance(outputs, symbol.Symbol) if merge_outputs is None else \
                        merge_outputs
        inputs, _ = _normalize_sequence(length, inputs, layout, merge_outputs)
        if merge_outputs:
            outputs = symbol.elemwise_add(outputs, inputs, name="%s_plus_residual" % outputs.name)
        else:
            outputs = [symbol.elemwise_add(output_sym, input_sym,
                                           name="%s_plus_residual" % output_sym.name)
                       for output_sym, input_sym in zip(outputs, inputs)]

        return outputs, states

class BidirectionalCell(BaseRNNCell):
    """Bidirectional RNN cell.

    Parameters
    ----------
    l_cell : BaseRNNCell
        cell for forward unrolling
    r_cell : BaseRNNCell
        cell for backward unrolling
    params : RNNParams, default None.
        Container for weight sharing between cells.
        A new RNNParams container is created if `params` is None.
    output_prefix : str, default ``'bi_'``
        prefix for name of output
    """
    def __init__(self, l_cell, r_cell, params=None, output_prefix='bi_'):
        super(BidirectionalCell, self).__init__('', params=params)
        self._output_prefix = output_prefix
        self._override_cell_params = params is not None

        if self._override_cell_params:
            assert l_cell._own_params and r_cell._own_params, \
                "Either specify params for BidirectionalCell " \
                "or child cells, not both."
            l_cell.params._params.update(self.params._params)
            r_cell.params._params.update(self.params._params)
        self.params._params.update(l_cell.params._params)
        self.params._params.update(r_cell.params._params)
        self._cells = [l_cell, r_cell]

    def unpack_weights(self, args):
        return _cells_unpack_weights(self._cells, args)

    def pack_weights(self, args):
        return _cells_pack_weights(self._cells, args)

    def __call__(self, inputs, states):
        raise NotImplementedError("Bidirectional cannot be stepped. Please use unroll")

    @property
    def state_info(self):
        return _cells_state_info(self._cells)

    def begin_state(self, **kwargs): # pylint: disable=arguments-differ
        assert not self._modified, \
            "After applying modifier cells (e.g. DropoutCell) the base " \
            "cell cannot be called directly. Call the modifier cell instead."
        return _cells_begin_state(self._cells, **kwargs)

    def unroll(self, length, inputs, begin_state=None, layout='NTC', merge_outputs=None):
        self.reset()

        inputs, axis = _normalize_sequence(length, inputs, layout, False)
        if begin_state is None:
            begin_state = self.begin_state()

        states = begin_state
        l_cell, r_cell = self._cells
        l_outputs, l_states = l_cell.unroll(length, inputs=inputs,
                                            begin_state=states[:len(l_cell.state_info)],
                                            layout=layout, merge_outputs=merge_outputs)
        r_outputs, r_states = r_cell.unroll(length,
                                            inputs=list(reversed(inputs)),
                                            begin_state=states[len(l_cell.state_info):],
                                            layout=layout, merge_outputs=merge_outputs)

        if merge_outputs is None:
            merge_outputs = (isinstance(l_outputs, symbol.Symbol)
                             and isinstance(r_outputs, symbol.Symbol))
            if not merge_outputs:
                if isinstance(l_outputs, symbol.Symbol):
                    l_outputs = list(symbol.SliceChannel(l_outputs, axis=axis,
                                                         num_outputs=length, squeeze_axis=1))
                if isinstance(r_outputs, symbol.Symbol):
                    r_outputs = list(symbol.SliceChannel(r_outputs, axis=axis,
                                                         num_outputs=length, squeeze_axis=1))

        if merge_outputs:
            l_outputs = [l_outputs]
            r_outputs = [symbol.reverse(r_outputs, axis=axis)]
        else:
            r_outputs = list(reversed(r_outputs))

        outputs = [symbol.Concat(l_o, r_o, dim=1+merge_outputs,
                                 name=('%sout'%(self._output_prefix) if merge_outputs
                                       else '%st%d'%(self._output_prefix, i)))
                   for i, l_o, r_o in
                   zip(range(len(l_outputs)), l_outputs, r_outputs)]

        if merge_outputs:
            outputs = outputs[0]

        states = [l_states, r_states]
        return outputs, states

class BaseConvRNNCell(BaseRNNCell):
    """Abstract base class for Convolutional RNN cells"""
    def __init__(self, input_shape, num_hidden,
                 h2h_kernel, h2h_dilate,
                 i2h_kernel, i2h_stride,
                 i2h_pad, i2h_dilate,
                 i2h_weight_initializer, h2h_weight_initializer,
                 i2h_bias_initializer, h2h_bias_initializer,
                 activation, prefix='', params=None, conv_layout='NCHW'):
        super(BaseConvRNNCell, self).__init__(prefix=prefix, params=params)
        # Convolution setting
        self._h2h_kernel = h2h_kernel
        assert (self._h2h_kernel[0] % 2 == 1) and (self._h2h_kernel[1] % 2 == 1), \
            "Only support odd number, get h2h_kernel= %s" % str(h2h_kernel)
        self._h2h_pad = (h2h_dilate[0] * (h2h_kernel[0] - 1) // 2,
                         h2h_dilate[1] * (h2h_kernel[1] - 1) // 2)
        self._h2h_dilate = h2h_dilate
        self._i2h_kernel = i2h_kernel
        self._i2h_stride = i2h_stride
        self._i2h_pad = i2h_pad
        self._i2h_dilate = i2h_dilate

        self._num_hidden = num_hidden
        self._input_shape = input_shape
        self._conv_layout = conv_layout
        self._activation = activation

        # Infer state shape
        data = symbol.Variable('data')
        self._state_shape = symbol.Convolution(data=data,
                                               num_filter=self._num_hidden,
                                               kernel=self._i2h_kernel,
                                               stride=self._i2h_stride,
                                               pad=self._i2h_pad,
                                               dilate=self._i2h_dilate,
                                               layout=conv_layout)
        self._state_shape = self._state_shape.infer_shape(data=input_shape)[1][0]
        self._state_shape = (0, ) + self._state_shape[1:]

        # Get params
        self._iW = self.params.get('i2h_weight', init=i2h_weight_initializer)
        self._hW = self.params.get('h2h_weight', init=h2h_weight_initializer)
        self._iB = self.params.get('i2h_bias', init=i2h_bias_initializer)
        self._hB = self.params.get('h2h_bias', init=h2h_bias_initializer)

    @property
    def _num_gates(self):
        return len(self._gate_names)

    @property
    def state_info(self):
        return [{'shape': self._state_shape, '__layout__': self._conv_layout},
                {'shape': self._state_shape, '__layout__': self._conv_layout}]

    def _conv_forward(self, inputs, states, name):

        i2h = symbol.Convolution(name='%si2h'%name,
                                 data=inputs,
                                 num_filter=self._num_hidden*self._num_gates,
                                 kernel=self._i2h_kernel,
                                 stride=self._i2h_stride,
                                 pad=self._i2h_pad,
                                 dilate=self._i2h_dilate,
                                 weight=self._iW,
                                 bias=self._iB,
                                 layout=self._conv_layout)

        h2h = symbol.Convolution(name='%sh2h'%name,
                                 data=states[0],
                                 num_filter=self._num_hidden*self._num_gates,
                                 kernel=self._h2h_kernel,
                                 dilate=self._h2h_dilate,
                                 pad=self._h2h_pad,
                                 stride=(1, 1),
                                 weight=self._hW,
                                 bias=self._hB,
                                 layout=self._conv_layout)
        return i2h, h2h

    def __call__(self, inputs, states):
        raise NotImplementedError("BaseConvRNNCell is abstract class for convolutional RNN")

class ConvRNNCell(BaseConvRNNCell):
    """Convolutional RNN cells

    Parameters
    ----------
    input_shape : tuple of int
        Shape of input in single timestep.
    num_hidden : int
        Number of units in output symbol.
    h2h_kernel : tuple of int, default (3, 3)
        Kernel of Convolution operator in state-to-state transitions.
    h2h_dilate : tuple of int, default (1, 1)
        Dilation of Convolution operator in state-to-state transitions.
    i2h_kernel : tuple of int, default (3, 3)
        Kernel of Convolution operator in input-to-state transitions.
    i2h_stride : tuple of int, default (1, 1)
        Stride of Convolution operator in input-to-state transitions.
    i2h_pad : tuple of int, default (1, 1)
        Pad of Convolution operator in input-to-state transitions.
    i2h_dilate : tuple of int, default (1, 1)
        Dilation of Convolution operator in input-to-state transitions.
    i2h_weight_initializer : str or Initializer
        Initializer for the input weights matrix, used for the convolution
        transformation of the inputs.
    h2h_weight_initializer : str or Initializer
        Initializer for the recurrent weights matrix, used for the convolution
        transformation of the recurrent state.
    i2h_bias_initializer : str or Initializer, default zeros
        Initializer for the bias vector.
    h2h_bias_initializer : str or Initializer, default zeros
        Initializer for the bias vector.
    activation : str or Symbol,
        default functools.partial(symbol.LeakyReLU, act_type='leaky', slope=0.2)
        Type of activation function.
    prefix : str, default ``'ConvRNN_'``
        Prefix for name of layers (and name of weight if params is None).
    params : RNNParams, default None
        Container for weight sharing between cells. Created if None.
    conv_layout : str, , default 'NCHW'
        Layout of ConvolutionOp
    """
    def __init__(self, input_shape, num_hidden,
                 h2h_kernel=(3, 3), h2h_dilate=(1, 1),
                 i2h_kernel=(3, 3), i2h_stride=(1, 1),
                 i2h_pad=(1, 1), i2h_dilate=(1, 1),
                 i2h_weight_initializer=None, h2h_weight_initializer=None,
                 i2h_bias_initializer='zeros', h2h_bias_initializer='zeros',
                 activation=functools.partial(symbol.LeakyReLU, act_type='leaky', slope=0.2),
                 prefix='ConvRNN_', params=None, conv_layout='NCHW'):
        super(ConvRNNCell, self).__init__(input_shape=input_shape, num_hidden=num_hidden,
                                          h2h_kernel=h2h_kernel, h2h_dilate=h2h_dilate,
                                          i2h_kernel=i2h_kernel, i2h_stride=i2h_stride,
                                          i2h_pad=i2h_pad, i2h_dilate=i2h_dilate,
                                          i2h_weight_initializer=i2h_weight_initializer,
                                          h2h_weight_initializer=h2h_weight_initializer,
                                          i2h_bias_initializer=i2h_bias_initializer,
                                          h2h_bias_initializer=h2h_bias_initializer,
                                          activation=activation, prefix=prefix,
                                          params=params, conv_layout=conv_layout)

    @property
    def _gate_names(self):
        return ('',)

    def __call__(self, inputs, states):
        self._counter += 1
        name = '%st%d_'%(self._prefix, self._counter)
        i2h, h2h = self._conv_forward(inputs, states, name)
        output = self._get_activation(i2h + h2h, self._activation,
                                      name='%sout'%name)
        return output, [output]

    @property
    def state_info(self):
        return [{'shape': self._state_shape, '__layout__': self._conv_layout}]

class ConvLSTMCell(BaseConvRNNCell):
    """Convolutional LSTM network cell.

    Reference:
        Xingjian et al. NIPS2015

    Parameters
    ----------
    input_shape : tuple of int
        Shape of input in single timestep.
    num_hidden : int
        Number of units in output symbol.
    h2h_kernel : tuple of int, default (3, 3)
        Kernel of Convolution operator in state-to-state transitions.
    h2h_dilate : tuple of int, default (1, 1)
        Dilation of Convolution operator in state-to-state transitions.
    i2h_kernel : tuple of int, default (3, 3)
        Kernel of Convolution operator in input-to-state transitions.
    i2h_stride : tuple of int, default (1, 1)
        Stride of Convolution operator in input-to-state transitions.
    i2h_pad : tuple of int, default (1, 1)
        Pad of Convolution operator in input-to-state transitions.
    i2h_dilate : tuple of int, default (1, 1)
        Dilation of Convolution operator in input-to-state transitions.
    i2h_weight_initializer : str or Initializer
        Initializer for the input weights matrix, used for the convolution
        transformation of the inputs.
    h2h_weight_initializer : str or Initializer
        Initializer for the recurrent weights matrix, used for the convolution
        transformation of the recurrent state.
    i2h_bias_initializer : str or Initializer, default zeros
        Initializer for the bias vector.
    h2h_bias_initializer : str or Initializer, default zeros
        Initializer for the bias vector.
    activation : str or Symbol
        default functools.partial(symbol.LeakyReLU, act_type='leaky', slope=0.2)
        Type of activation function.
    prefix : str, default ``'ConvLSTM_'``
        Prefix for name of layers (and name of weight if params is None).
    params : RNNParams, default None
        Container for weight sharing between cells. Created if None.
    conv_layout : str, , default 'NCHW'
        Layout of ConvolutionOp
    """
    def __init__(self, input_shape, num_hidden,
                 h2h_kernel=(3, 3), h2h_dilate=(1, 1),
                 i2h_kernel=(3, 3), i2h_stride=(1, 1),
                 i2h_pad=(1, 1), i2h_dilate=(1, 1),
                 i2h_weight_initializer=None, h2h_weight_initializer=None,
                 i2h_bias_initializer='zeros', h2h_bias_initializer='zeros',
                 activation=functools.partial(symbol.LeakyReLU, act_type='leaky', slope=0.2),
                 prefix='ConvLSTM_', params=None,
                 conv_layout='NCHW'):
        super(ConvLSTMCell, self).__init__(input_shape=input_shape, num_hidden=num_hidden,
                                           h2h_kernel=h2h_kernel, h2h_dilate=h2h_dilate,
                                           i2h_kernel=i2h_kernel, i2h_stride=i2h_stride,
                                           i2h_pad=i2h_pad, i2h_dilate=i2h_dilate,
                                           i2h_weight_initializer=i2h_weight_initializer,
                                           h2h_weight_initializer=h2h_weight_initializer,
                                           i2h_bias_initializer=i2h_bias_initializer,
                                           h2h_bias_initializer=h2h_bias_initializer,
                                           activation=activation, prefix=prefix,
                                           params=params, conv_layout=conv_layout)

    @property
    def _gate_names(self):
        return ['_i', '_f', '_c', '_o']

    def __call__(self, inputs, states):
        self._counter += 1
        name = '%st%d_'%(self._prefix, self._counter)
        i2h, h2h = self._conv_forward(inputs, states, name)
        gates = i2h + h2h
        slice_gates = symbol.SliceChannel(gates, num_outputs=4, axis=self._conv_layout.find('C'),
                                          name="%sslice"%name)
        in_gate = symbol.Activation(slice_gates[0], act_type="sigmoid",
                                    name='%si'%name)
        forget_gate = symbol.Activation(slice_gates[1], act_type="sigmoid",
                                        name='%sf'%name)
        in_transform = self._get_activation(slice_gates[2], self._activation,
                                            name='%sc'%name)
        out_gate = symbol.Activation(slice_gates[3], act_type="sigmoid",
                                     name='%so'%name)
        next_c = symbol._internal._plus(forget_gate * states[1], in_gate * in_transform,
                                        name='%sstate'%name)
        next_h = symbol._internal._mul(out_gate, self._get_activation(next_c, self._activation),
                                       name='%sout'%name)

        return next_h, [next_h, next_c]

    @property
    def state_info(self):
        return [{'shape': self._state_shape, '__layout__': self._conv_layout},
                {'shape': self._state_shape, '__layout__': self._conv_layout}]

class ConvGRUCell(BaseConvRNNCell):
    """Convolutional Gated Rectified Unit (GRU) network cell.

    Parameters
    ----------
    input_shape : tuple of int
        Shape of input in single timestep.
    num_hidden : int
        Number of units in output symbol.
    h2h_kernel : tuple of int, default (3, 3)
        Kernel of Convolution operator in state-to-state transitions.
    h2h_dilate : tuple of int, default (1, 1)
        Dilation of Convolution operator in state-to-state transitions.
    i2h_kernel : tuple of int, default (3, 3)
        Kernel of Convolution operator in input-to-state transitions.
    i2h_stride : tuple of int, default (1, 1)
        Stride of Convolution operator in input-to-state transitions.
    i2h_pad : tuple of int, default (1, 1)
        Pad of Convolution operator in input-to-state transitions.
    i2h_dilate : tuple of int, default (1, 1)
        Dilation of Convolution operator in input-to-state transitions.
    i2h_weight_initializer : str or Initializer
        Initializer for the input weights matrix, used for the convolution
        transformation of the inputs.
    h2h_weight_initializer : str or Initializer
        Initializer for the recurrent weights matrix, used for the convolution
        transformation of the recurrent state.
    i2h_bias_initializer : str or Initializer, default zeros
        Initializer for the bias vector.
    h2h_bias_initializer : str or Initializer, default zeros
        Initializer for the bias vector.
    activation : str or Symbol,
        default functools.partial(symbol.LeakyReLU, act_type='leaky', slope=0.2)
        Type of activation function.
    prefix : str, default ``'ConvGRU_'``
        Prefix for name of layers (and name of weight if params is None).
    params : RNNParams, default None
        Container for weight sharing between cells. Created if None.
    conv_layout : str, , default 'NCHW'
        Layout of ConvolutionOp
    """
    def __init__(self, input_shape, num_hidden,
                 h2h_kernel=(3, 3), h2h_dilate=(1, 1),
                 i2h_kernel=(3, 3), i2h_stride=(1, 1),
                 i2h_pad=(1, 1), i2h_dilate=(1, 1),
                 i2h_weight_initializer=None, h2h_weight_initializer=None,
                 i2h_bias_initializer='zeros', h2h_bias_initializer='zeros',
                 activation=functools.partial(symbol.LeakyReLU, act_type='leaky', slope=0.2),
                 prefix='ConvGRU_', params=None, conv_layout='NCHW'):
        super(ConvGRUCell, self).__init__(input_shape=input_shape, num_hidden=num_hidden,
                                          h2h_kernel=h2h_kernel, h2h_dilate=h2h_dilate,
                                          i2h_kernel=i2h_kernel, i2h_stride=i2h_stride,
                                          i2h_pad=i2h_pad, i2h_dilate=i2h_dilate,
                                          i2h_weight_initializer=i2h_weight_initializer,
                                          h2h_weight_initializer=h2h_weight_initializer,
                                          i2h_bias_initializer=i2h_bias_initializer,
                                          h2h_bias_initializer=h2h_bias_initializer,
                                          activation=activation, prefix=prefix,
                                          params=params, conv_layout=conv_layout)

    @property
    def _gate_names(self):
        return ['_r', '_z', '_o']

    @property
    def state_info(self):
        return [{'shape': self._state_shape, '__layout__': self._conv_layout}]

    def __call__(self, inputs, states):
        self._counter += 1
        seq_idx = self._counter
        name = '%st%d_' % (self._prefix, seq_idx)
        i2h, h2h = self._conv_forward(inputs, states, name)

        i2h_r, i2h_z, i2h = symbol.SliceChannel(i2h, num_outputs=3, name="%s_i2h_slice" % name)
        h2h_r, h2h_z, h2h = symbol.SliceChannel(h2h, num_outputs=3, name="%s_h2h_slice" % name)

        reset_gate = symbol.Activation(i2h_r + h2h_r, act_type="sigmoid",
                                       name="%s_r_act" % name)
        update_gate = symbol.Activation(i2h_z + h2h_z, act_type="sigmoid",
                                        name="%s_z_act" % name)

        next_h_tmp = self._get_activation(i2h + reset_gate * h2h, self._activation,
                                          name="%s_h_act" % name)

        next_h = symbol._internal._plus((1. - update_gate) * next_h_tmp, update_gate * states[0],
                                        name='%sout' % name)

        return next_h, [next_h]


text:
<?php
namespace AppBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use AppBundle\Entity\Rating;

class LoadRatingData extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $rating1 = new Rating();
        $rating1
            ->setSendingUser($this->getReference('user-sender'))
            ->setMeasure(3.5)
            ->setQuality(4)
            ->setConviviality(5)
            ->setRating('Très bon mais un peu juste sur les quantités.');

        $manager->persist($rating1);
        $manager->flush();

        $this->addReference('user-rating-1', $rating1);
    }

    public function getOrder()
    {
        return 8;
    }
}


text:
/*
 * Description:
 *     What is this file about?
 *
 * Revision history:
 *     xxxx-xx-xx, author, first version
 *     xxxx-xx-xx, author, fix bug about xxx
 */
# include "mutation_log.h"
# include <gtest/gtest.h>
# include <chrono>
# include <condition_variable>

using namespace ::dsn;
using namespace ::dsn::replication;

TEST(replication, mutation_log_learn)
{
    std::chrono::steady_clock clock;
    gpid gpid(1, 1);
    std::string str = "hello, world!";
    std::string logp = "./test-log";

    // prepare mutations
    std::vector<mutation_ptr> mutations;
    auto time_tic = clock.now();
    for (int i = 0; i < 1000; i++)
    {
        mutation_ptr mu(new mutation());
        mu->data.header.ballot = 1;
        mu->data.header.decree = i + 2;
        mu->data.header.pid = gpid;
        mu->data.header.last_committed_decree = i;
        mu->data.header.log_offset = 0;

        binary_writer writer;
        //we want a update mutation to be ~4kByte
        for (int j = 0; j < 300; j++)
        {
            writer.write(str);
        }
        mu->data.updates.push_back(mutation_update());
        mu->data.updates.back().code = RPC_REPLICATION_WRITE_EMPTY;
        mu->data.updates.back().data = writer.get_buffer();

        mu->client_requests.push_back(nullptr);

        mutations.push_back(mu);
    }
    auto time_toc = clock.now();
    std::cout << "prepare mutations time(us): " << std::chrono::duration_cast<std::chrono::microseconds>(time_toc - time_tic).count() << std::endl;

    decree learn_points[] = {584,585,586, 594,595,596,604,605,606 };

    for (auto& lp : learn_points)
    {
        // prepare dir
        utils::filesystem::remove_path(logp);
        utils::filesystem::create_directory(logp);

        // writing logs
        time_tic = clock.now();
        mutation_log_ptr mlog = new mutation_log(logp, 4, 32, true, true, gpid);
        mlog->open(nullptr);
        for (auto& mu : mutations)
        {
            mlog->append(mu, LPC_AIO_IMMEDIATE_CALLBACK, nullptr, nullptr, 0);
        }
        mlog->flush();
        time_toc = clock.now();
        std::cout << "learn_point[" << lp << "]: write time(us): " << std::chrono::duration_cast<std::chrono::microseconds>(time_toc - time_tic).count() << std::endl;

        // gc
        time_tic = clock.now();
        decree durable_decree = lp;
        mlog->garbage_collection(gpid, durable_decree, 0);
        mlog->close();
        time_toc = clock.now();
        std::cout << "learn_point[" << lp << "]: gc time(us): " << std::chrono::duration_cast<std::chrono::microseconds>(time_toc - time_tic).count() << std::endl;

        // reading logs
        time_tic = clock.now();
        mlog = new mutation_log(logp, 1, 1, true, true, gpid);
        mlog->open([](mutation_ptr& mu)->bool{ return true; });
        time_toc = clock.now();
        std::cout << "learn_point[" << lp << "]: read time(us): " << std::chrono::duration_cast<std::chrono::microseconds>(time_toc - time_tic).count() << std::endl;

        // learning
        time_tic = clock.now();
        learn_state state;
        mlog->get_learn_state(gpid, durable_decree + 1, state);
        mlog->close();
        mlog = nullptr;
        time_toc = clock.now();
        std::cout << "learn_point[" << lp << "]: learn time(us): " << std::chrono::duration_cast<std::chrono::microseconds>(time_toc - time_tic).count() << std::endl;

        // replaying
        time_tic = clock.now();
        int64_t offset = 0;
        std::set<decree> learned_decress;
        mutation_log::replay(state.files,
            [&mutations, &learned_decress, &clock](mutation_ptr& mu)->bool
            {
                //wait for 5 usec mimicing mutation replay time
                auto tic = clock.now();
                while (std::chrono::duration_cast<std::chrono::microseconds>(clock.now() - tic).count() < 5)
                {
                    ;
                }
                learned_decress.insert(mu->data.header.decree);

                mutation_ptr wmu = mutations[mu->data.header.decree - 2];
#ifdef DSN_USE_THRIFT_SERIALIZATION
                EXPECT_TRUE(wmu->data.header == mu->data.header);
#else
                EXPECT_TRUE(memcmp((const void*)&wmu->data.header,
                    (const void*)&mu->data.header,
                    sizeof(mu->data.header)) == 0
                    );
#endif
                EXPECT_TRUE(wmu->data.updates.size() == mu->data.updates.size());
                EXPECT_TRUE(wmu->data.updates[0].data.length() == mu->data.updates[0].data.length());
                EXPECT_TRUE(memcmp((const void*)wmu->data.updates[0].data.data(),
                    (const void*)mu->data.updates[0].data.data(),
                    mu->data.updates[0].data.length()) == 0
                    );
                EXPECT_TRUE(wmu->data.updates[0].code == mu->data.updates[0].code);
                EXPECT_TRUE(wmu->client_requests.size() == mu->client_requests.size());

                return true;
            },
            offset
            ).end_tracking();
        time_toc = clock.now();
        std::cout << "learn_point[" << lp << "]: replay time(us): " << std::chrono::duration_cast<std::chrono::microseconds>(time_toc - time_tic).count() << std::endl;

        // checking
        time_tic = clock.now();
        for (decree s = durable_decree + 1; s < 1000; s++)
        {
            auto it = learned_decress.find(s);
            ASSERT_TRUE(it != learned_decress.end());
        }
        time_toc = clock.now();
        std::cout << "learn_point[" << lp << "]: check time(us): " << std::chrono::duration_cast<std::chrono::microseconds>(time_toc - time_tic).count() << std::endl;

        // clear all
        utils::filesystem::remove_path(logp);
    }
}


text:
require 'test_helper'

# Test session creation and deletion
class SessionsControllerTest < ActionDispatch::IntegrationTest
  test 'should get create' do
    # get sessions_create_url
    # assert_response :success
    assert true
  end

  test 'logout should delete session information' do
    delete logout_url
    assert_response :redirect
  end
end