This article describes MemTrack, a library which replaces the standard operator new
with a special version that records information about each memory allocation. This information can be analyzed later for debugging purposes or for performance measurement. The article begins by discussing the use of macros to instrument memory allocation in C and the use of macros combined with "placement operator new
" to accomplish the same thing in C++. Then it describes the alternative approach used in the MemTrack library. This alternative approach differs from the more conventional approach in two important ways: First, it does not rely on the implicit use of placement operator new
syntax and, second, it can capture the type of each memory allocation.
The use of macros to instrument memory allocation in C is a well-known technique, and it's worth reviewing. Two standard C preprocessor macros are the key to this technique: the __FILE__
and __LINE__
macros. __FILE__
expands to a string literal containing the filename of the source file currently being processed, and __LINE__
always expands to the line number of the line that the __LINE__
macro appears on.
Typically, __FILE__
and __LINE__
will be embedded inside another macro, so that they can be applied transparently. The typical targets for this approach are malloc()
and its sibling functions. For example:
#define malloc(size) custom_malloc(size, __FILE__, __LINE__)
Ideally, the instrumented memory allocation functions can be transparently substituted for the regular ones throughout an entire project by making changes to a single header file.
A similar approach can be used in C++, but to understand it, it's first necessary to discuss "placement operator new
". C++ makes it possible to define custom versions of operator new
, and these custom versions may take extra arguments. The simplest example is the classic placement operator new
:
void *operator new(size_t size, void *p) { return p; }
This version of operator new
can be used to construct a C++ object at an arbitrary place in memory, hence the name "placement operator new
". This capability was thought to be so useful that a stock implementation of placement operator new
with these semantics is provided by the standard C++ library. This operator new
can be called like so:
Object *object = new(buffer) Object;
The first argument to any operator new
function is the size of the memory block to allocate. This argument is always supplied implicitly by the compiler. If there are any extra arguments, then they are listed in parentheses immediately after the new
keyword, using normal function call syntax.
There's no restriction on the number of parameters a custom implementation of operator new
may take, nor is there any restriction on how those parameters may be used. Nevertheless, the moniker "placement operator new
" is used broadly (and confusingly) to refer to all forms of operator new
which take extra arguments, even those forms which do not match the classic placement semantics.
We can use the placement syntax to define a version of operator new
equivalent to our hypothetical custom_malloc()
function above:
void *operator new(size_t size, char const *filename, int lineNum) { ... }
Now that we know how to pass arguments to operator new
, and since the preprocessor will not recursively expand macros, we can define a new
macro equivalent to the malloc()
macro above:
#define new new(__FILE__, __LINE__)
As in the case for C, we'd like to be able to transparently switch between the normal memory allocation function and the instrumented one by changing a single include file. This goal may be more difficult to achieve in C++ than in C, however. One problem is that the new
macro will conflict with any explicit use of placement syntax. For example, a use of classic placement new
syntax will conflict with the new
macro:
Object *object = new(buffer) Object;
will expand to something like:
Object *object = new("object.cpp", 131)(buffer) Object;
which is clearly in error. Another problem is that any declaration of a custom operator new
will also conflict with the macro.
The notion that we can have a custom memory allocator begs the question of just how such an allocator should be implemented. If we are only interested in recording extra information about each memory allocation then the easiest technique is to simply piggyback on top of the standard allocator. When the custom allocator is called with a request for memory, it simply asks the standard allocator for the memory, which the custom allocator then returns to the original caller.
It's easy to store the extra information in the piggyback scheme. Assume we need to store m bytes of extra data for every allocation. If the original caller requests n bytes of information, then the custom allocator will simply request n +m bytes of storage from the standard allocator. The custom allocator will then retain the first m bytes of storage for its own use and return a pointer to the original caller that points m bytes into the new memory block. Needless to say, this kind of allocator needs to be paired with a de-allocator that is aware of this offset. The piggyback scheme is the approach used by MemTrack.
MemTrack uses an alternative approach to instrumenting memory allocation in C++. It separates the allocation of a block of memory from the storage of the descriptive information about that memory. Instead, this information is applied later in a process I refer to as "stamping". Since the stamping step is embedded inside a new
macro, this approach is as easy to use as the placement new
approach.
There's more work involved in making the stamping process work. Since the new
operator does not require parentheses for its type argument, we can't write a new
macro that will capture the type argument. This means that we can't just pass the result of the new
expression into a stamp()
function which then returns its argument after stamping it. However, if we make our stamping function an overloaded operator we can accomplish the same thing, and we don't have to capture the type in the macro -- we just have to juxtapose the stamping operator with the new
expression, which we can do without capturing the type in the new
macro.
Astute readers will have already noticed that the stamping function must not only be an operator but that it must also be a template function. This is because the stamping operator must be capable of returning exactly the same type as the new
expression. This is a lot of work simply to avoid the use of placement new
. However, the use of the template introduces a new capability that's simply not available with the placement new
approach: we can capture the type of the new expression inside the stamping operator and record it along with the other information we care about. It's exactly this capability that makes the stamping approach worth exploring.
new
MacroThe new
macro and its component parts are the heart of MemTrack, so let's examine them in detail. These examples were drawn from the "MemTrack.h" header file, although they've been simplified somewhat for the sake of clarity.
Let's start with the new
macro itself:
#define new MemStamp(__FILE__, __LINE__) * new
This will expand the following statement
Object *object = new Object;
into something like:
Object *object = MemStamp("object.cpp", 131) * new Object;
The MemStamp temporary combines the filename and line number into a single entity, which then serves as the first argument to operator*
. operator*
is then called with both the stamp and the newly allocated object as arguments, and it returns the new object after stamping it.
The MemStamp class looks like this:
class MemStamp { public: // member variables char const * const filename; int const lineNum; public: // construction/destruction MemStamp(char const *filename, int lineNum) : filename(filename), lineNum(lineNum) { } ~MemStamp() { } };
The operator*
template is quite simple, and the only thing really of note is the call to typeid(T).name()
in the call to the internal stamping function.
template <class T> inline T *operator*(const MemStamp &stamp, T *p) { TrackStamp(p, stamp, typeid(T).name()); return p; }
Since the first argument to operator*
is a MemStamp
value, it's very unlikely that this definition of operator*
will conflict with any ordinary use of the operator.
The previous section describes the new
macro that MemTrack uses to automatically and transparently (as much as is possible) instrument source code. This is only half the story, though. The other half of the story is the custom allocator, the stamping function, and the mechanism for later retrieving the information that we've stamped on all those memory blocks.
The public interface to MemTrack consists of two sets of functions. The first set of functions are the Track*
functions:
void *TrackMalloc(size_t size); void TrackFree(void *p); void TrackStamp(void *p, const MemStamp &stamp, char const *typeName); void TrackDumpBlocks(); void TrackListMemoryUsage();
Normally there will be no need to call TrackMalloc()
or TrackFree()
directly, but they're available if you can think of a good reason to use them. TrackStamp()
is needed for the implementation of the stamping operator, and TrackDumpBlocks()
and TrackListMemoryUsage()
provide ways to dump information about the currently allocated memory blocks.
The second set of functions are the overrides for global new
and delete
operators.
void *operator new(size_t size) { ... } void operator delete(void *p) { ... } void *operator new[](size_t size) { ... } void operator delete[](void *p) { ... }
There are no prototypes for these functions in "MemTrack.h" since the signatures of these functions are automatically known to the C++ compiler. However, the override definitions appear in "MemTrack.cpp" and they will override the default versions supplied by the compiler. These functions basically just call TrackMalloc()
and TrackFree()
.
TrackMalloc()
uses the piggyback approach described earlier in the article. The extra information stored for each allocated block of memory is referred to as the prolog, and currently the prolog is broken into two parts, the "block header", and the "signature". Block headers serve two important functions. First, they store all the extra information for each memory block, such as the filename and the type name. Second, they store the forward and backward pointers of the doubly-linked list that links all currently allocated memory blocks together.
The signature consists of a specific 64 bit pattern that can be used to identify a memory block as one that has been allocated by TrackMalloc()
and which can safely be "stamped". If a pointer is pointing to a block of memory returned from TrackMalloc()
, then the 8 bytes before that pointer will consist of the signature. This approach is rather crude, and it introduces some risks when testing pointers to valid memory blocks allocated by other memory allocators. The first problem is that there is a chance of a false positive on a signature test which would then result in a memory overwrite error when the memory block is stamped. The second problem is that the signature test could attempt to read memory not assigned to the process, resulting in a memory access fault. Neither of these problems should occur when the MemTrack allocator is the only one being used in a program, however.
I tested MemTrack using FH-reader, a library I wrote several years ago for reading Macromedia FreeHand files. FH-reader made a good platform for testing the type capture capabilities of MemTrack since it represents FreeHand files in memory using objects of more than 70 different classes.
TrackDumpBlocks()
listed 80701 blocks after one test run of the FH-reader test driver. This quantity of information is a little hard to interpret usefully. TrackListMemoryUsage()
lists total memory usage by type from highest to lowest. Table 1 is the first 20 items from a test run of FH-reader.
----------------------- Memory Usage Statistics ----------------------- allocated type blocks bytes -------------- ------ ----- struct FHRDocPath::IndexedRec 11031 13.7% 2756600 45.8% class FHRDocPath 10734 13.3% 772848 12.8% class FHRDocElemPropLst 13132 16.3% 420224 7.0% struct FHRDocVDict::IndexedRec 3595 4.5% 370336 6.2% struct FHRDocMDict::IndexedRec 13368 16.6% 208200 3.5% class FHRDocObject * 36 0.0% 172836 2.9% struct FHRDocData::IndexedRec 890 1.1% 159880 2.7% struct FHRDocLineTable::IndexedRec 408 0.5% 152824 2.5% struct FHRDocMList::IndexedRec 2656 3.3% 119168 2.0% class FHRDocMList 1964 2.4% 62848 1.0% class FHRDocVMpObj 2096 2.6% 58688 1.0% class FHRDocProcessColor 1259 1.6% 50360 0.8% struct FHRDocTextBlok::IndexedRec 680 0.8% 48756 0.8% class FHRDocUString 1800 2.2% 43200 0.7% class FHRDocGroup 684 0.8% 41040 0.7% class FHRDocObject * (__cdecl*)(void) 36 0.0% 39928 0.7% class FHRDocXform 516 0.6% 35088 0.6% class FHRDocTextColumn 403 0.5% 33852 0.6% class FHRDocTString 407 0.5% 29304 0.5% struct FHRDocUString::IndexedRec 1800 2.2% 27904 0.5%
Besides the potential for conflict with the definition of other operator new
functions there is another problem worth mentioning. C++ allows classes to be declared inside functions, but it does not allow templates to be specialized on these classes. This restriction makes the MemTrack new
macro unusable for local classes.
MemTrack also lacks a lot of features that a fully functional library would provide, such as logic to check for memory overwrites and double frees. A fully functional library should also be able to make claims about portability that MemTrack currently can't since it has only been tested on one compiler on one platform (Visual C++.Net on Windows 2000). The signature mechanism has some serious deficiencies, which could make MemTrack unusable for some projects. Finally, using any library that relies on a global macro to redefine a language keyword is potentially asking for trouble. However, MemTrack has been used successfully with the FH-reader library, providing a successful demonstration of the memory stamping and type capture techniques described in this article.
malloc()
, calloc()
, realloc()
, and free()
functions. #define
.#ifndef MemTrack_H_ #define MemTrack_H_ #include <typeinfo> namespace MemTrack { /* ---------------------------------------- class MemStamp */ class MemStamp { public: // member variables char const * const filename; int const lineNum; public: // construction/destruction MemStamp(char const *filename, int lineNum) : filename(filename), lineNum(lineNum) { } ~MemStamp() { } }; /* ---------------------------------------- memory allocation and stamping prototypes */ void *TrackMalloc(size_t size); void TrackFree(void *p); void TrackStamp(void *p, const MemStamp &stamp, char const *typeName); void TrackDumpBlocks(); void TrackListMemoryUsage(); /* ---------------------------------------- operator * (MemStamp, ptr) */ template <class T> inline T *operator*(const MemStamp &stamp, T *p) { TrackStamp(p, stamp, typeid(T).name()); return p; } } // namespace MemTrack /* ---------------------------------------- new macro */ #define MEMTRACK_NEW MemTrack::MemStamp(__FILE__, __LINE__) * new #define new MEMTRACK_NEW #endif // MemTrack_H_
/* ---------------------------------------- includes */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <new> #include "MemTrack.h" #undef new // IMPORTANT! /* ------------------------------------------------------------ */ /* -------------------- namespace MemTrack -------------------- */ /* ------------------------------------------------------------ */ namespace MemTrack { /* ------------------------------------------------------------ */ /* --------------------- class BlockHeader -------------------- */ /* ------------------------------------------------------------ */ class BlockHeader { private: // static member variables static BlockHeader *ourFirstNode; private: // member variables BlockHeader *myPrevNode; BlockHeader *myNextNode; size_t myRequestedSize; char const *myFilename; int myLineNum; char const *myTypeName; public: // members BlockHeader(size_t requestedSize); ~BlockHeader(); size_t GetRequestedSize() const { return myRequestedSize; } char const *GetFilename() const { return myFilename; } int GetLineNum() const { return myLineNum; } char const *GetTypeName() const { return myTypeName; } void Stamp(char const *filename, int lineNum, char const *typeName); static void AddNode(BlockHeader *node); static void RemoveNode(BlockHeader *node); static size_t CountBlocks(); static void GetBlocks(BlockHeader **blockHeaderPP); static bool TypeGreaterThan(BlockHeader *header1, BlockHeader *header2); }; /* ---------------------------------------- BlockHeader static member variables */ BlockHeader *BlockHeader::ourFirstNode = NULL; /* ---------------------------------------- BlockHeader constructor */ BlockHeader::BlockHeader(size_t requestedSize) { myPrevNode = NULL; myNextNode = NULL; myRequestedSize = requestedSize; myFilename = "[unknown]"; myLineNum = 0; myTypeName = "[unknown]"; } /* ---------------------------------------- BlockHeader destructor */ BlockHeader::~BlockHeader() { } /* ---------------------------------------- BlockHeader Stamp */ void BlockHeader::Stamp(char const *filename, int lineNum, char const *typeName) { myFilename = filename; myLineNum = lineNum; myTypeName = typeName; } /* ---------------------------------------- BlockHeader AddNode */ void BlockHeader::AddNode(BlockHeader *node) { assert(node != NULL); assert(node->myPrevNode == NULL); assert(node->myNextNode == NULL); // If we have at least one node in the list ... if (ourFirstNode != NULL) { // ... make the new node the first node's predecessor. assert(ourFirstNode->myPrevNode == NULL); ourFirstNode->myPrevNode = node; } // Make the first node the new node's succesor. node->myNextNode = ourFirstNode; // Make the new node the first node. ourFirstNode = node; } /* ---------------------------------------- BlockHeader RemoveNode */ void BlockHeader::RemoveNode(BlockHeader *node) { assert(node != NULL); assert(ourFirstNode != NULL); // If target node is the first node in the list... if (ourFirstNode == node) { // ... make the target node's successor the first node. assert(ourFirstNode->myPrevNode == NULL); ourFirstNode = node->myNextNode; } // Link target node's predecessor, if any, to its successor. if (node->myPrevNode != NULL) { node->myPrevNode->myNextNode = node->myNextNode; } // Link target node's successor, if any, to its predecessor. if (node->myNextNode != NULL) { node->myNextNode->myPrevNode = node->myPrevNode; } // Clear target node's previous and next pointers. node->myPrevNode = NULL; node->myNextNode = NULL; } /* ---------------------------------------- BlockHeader CountBlocks */ size_t BlockHeader::CountBlocks() { size_t count = 0; BlockHeader *currNode = ourFirstNode; while (currNode != NULL) { count++; currNode = currNode->myNextNode; } return count; } /* ---------------------------------------- BlockHeader GetBlocks */ void BlockHeader::GetBlocks(BlockHeader **blockHeaderPP) { BlockHeader *currNode = ourFirstNode; while (currNode != NULL) { *blockHeaderPP = currNode; blockHeaderPP++; currNode = currNode->myNextNode; } } /* ---------------------------------------- BlockHeader TypeGreaterThan */ bool BlockHeader::TypeGreaterThan(BlockHeader *header1, BlockHeader *header2) { return (strcmp(header1->myTypeName, header2->myTypeName) > 0); } /* ------------------------------------------------------------ */ /* ---------------------- class Signature --------------------- */ /* ------------------------------------------------------------ */ class Signature { private: // constants static const unsigned int SIGNATURE1 = 0xCAFEBABE; static const unsigned int SIGNATURE2 = 0xFACEFACE; private: // member variables unsigned int mySignature1; unsigned int mySignature2; public: // construction/destruction Signature() : mySignature1(SIGNATURE1), mySignature2(SIGNATURE2) {}; ~Signature() { mySignature1 = 0; mySignature2 = 0; } public: // static member functions static bool IsValidSignature(const Signature *pProspectiveSignature) { try { if (pProspectiveSignature->mySignature1 != SIGNATURE1) return false; if (pProspectiveSignature->mySignature2 != SIGNATURE2) return false; return true; } catch (...) { return false; } } }; /* ------------------------------------------------------------ */ /* -------------------- address conversion -------------------- */ /* ------------------------------------------------------------ */ /* We divide the memory blocks we allocate into two "chunks", the * "prolog chunk" where we store information about the allocation, * and the "user chunk" which we return to the caller to use. */ /* ---------------------------------------- alignment */ const size_t ALIGNMENT = 4; /* If "value" (a memory size or offset) falls on an alignment boundary, * then just return it. Otherwise return the smallest number larger * than "value" that falls on an alignment boundary. */ #define PAD_TO_ALIGNMENT_BOUNDARY(value) \ ((value) + ((ALIGNMENT - ((value) % ALIGNMENT)) % ALIGNMENT)) /* ---------------------------------------- chunk structs */ /* We declare incomplete structures for each chunk, just to * provide type safety. */ struct PrologChunk; struct UserChunk; /* ---------------------------------------- chunk sizes and offsets */ const size_t SIZE_BlockHeader = PAD_TO_ALIGNMENT_BOUNDARY(sizeof(BlockHeader)); const size_t SIZE_Signature = PAD_TO_ALIGNMENT_BOUNDARY(sizeof(Signature)); const size_t OFFSET_BlockHeader = 0; const size_t OFFSET_Signature = OFFSET_BlockHeader + SIZE_BlockHeader; const size_t OFFSET_UserChunk = OFFSET_Signature + SIZE_Signature; const size_t SIZE_PrologChunk = OFFSET_UserChunk; /* ---------------------------------------- GetUserAddress */ static UserChunk *GetUserAddress(PrologChunk *pProlog) { char *pchProlog = reinterpret_cast<char *>(pProlog); char *pchUser = pchProlog + OFFSET_UserChunk; UserChunk *pUser = reinterpret_cast<UserChunk *>(pchUser); return pUser; } /* ---------------------------------------- GetPrologAddress */ static PrologChunk *GetPrologAddress(UserChunk *pUser) { char *pchUser = reinterpret_cast<char *>(pUser); char *pchProlog = pchUser - OFFSET_UserChunk; PrologChunk *pProlog = reinterpret_cast<PrologChunk *>(pchProlog); return pProlog; } /* ---------------------------------------- GetHeaderAddress */ static BlockHeader *GetHeaderAddress(PrologChunk *pProlog) { char *pchProlog = reinterpret_cast<char *>(pProlog); char *pchHeader = pchProlog + OFFSET_BlockHeader; BlockHeader *pHeader = reinterpret_cast<BlockHeader *>(pchHeader); return pHeader; } /* ---------------------------------------- GetSignatureAddress */ static Signature *GetSignatureAddress(PrologChunk *pProlog) { char *pchProlog = reinterpret_cast<char *>(pProlog); char *pchSignature = pchProlog + OFFSET_Signature; Signature *pSignature = reinterpret_cast<Signature *>(pchSignature); return pSignature; } /* ------------------------------------------------------------ */ /* -------------- memory allocation and stamping -------------- */ /* ------------------------------------------------------------ */ /* ---------------------------------------- TrackMalloc */ void *TrackMalloc(size_t size) { // Allocate the memory, including space for the prolog. PrologChunk *pProlog = (PrologChunk *)malloc(SIZE_PrologChunk + size); // If the allocation failed, then return NULL. if (pProlog == NULL) return NULL; // Use placement new to construct the block header in place. BlockHeader *pBlockHeader = new (pProlog) BlockHeader(size); // Link the block header into the list of extant block headers. BlockHeader::AddNode(pBlockHeader); // Use placement new to construct the signature in place. Signature *pSignature = new (GetSignatureAddress(pProlog)) Signature; // Get the offset to the user chunk and return it. UserChunk *pUser = GetUserAddress(pProlog); return pUser; } /* ---------------------------------------- TrackFree */ void TrackFree(void *p) { // It's perfectly valid for "p" to be null; return if it is. if (p == NULL) return; // Get the prolog address for this memory block. UserChunk *pUser = reinterpret_cast<UserChunk *>(p); PrologChunk *pProlog = GetPrologAddress(pUser); // Check the signature, and if it's invalid, return immediately. Signature *pSignature = GetSignatureAddress(pProlog); if (!Signature::IsValidSignature(pSignature)) return; // Destroy the signature. pSignature->~Signature(); pSignature = NULL; // Unlink the block header from the list and destroy it. BlockHeader *pBlockHeader = GetHeaderAddress(pProlog); BlockHeader::RemoveNode(pBlockHeader); pBlockHeader->~BlockHeader(); pBlockHeader = NULL; // Free the memory block. free(pProlog); } /* ---------------------------------------- TrackStamp */ void TrackStamp(void *p, const MemStamp &stamp, char const *typeName) { // Get the header and signature address for this pointer. UserChunk *pUser = reinterpret_cast<UserChunk *>(p); PrologChunk *pProlog = GetPrologAddress(pUser); BlockHeader *pHeader = GetHeaderAddress(pProlog); Signature *pSignature = GetSignatureAddress(pProlog); // If the signature is not valid, then return immediately. if (!Signature::IsValidSignature(pSignature)) return; // "Stamp" the information onto the header. pHeader->Stamp(stamp.filename, stamp.lineNum, typeName); } /* ---------------------------------------- TrackDumpBlocks */ void TrackDumpBlocks() { // Get an array of pointers to all extant blocks. size_t numBlocks = BlockHeader::CountBlocks(); BlockHeader **ppBlockHeader = (BlockHeader **)calloc(numBlocks, sizeof(*ppBlockHeader)); BlockHeader::GetBlocks(ppBlockHeader); // Dump information about the memory blocks. printf("\n"); printf("=====================\n"); printf("Current Memory Blocks\n"); printf("=====================\n"); printf("\n"); for (size_t i = 0; i < numBlocks; i++) { BlockHeader *pBlockHeader = ppBlockHeader[i]; char const *typeName = pBlockHeader->GetTypeName(); size_t size = pBlockHeader->GetRequestedSize(); char const *fileName = pBlockHeader->GetFilename(); int lineNum = pBlockHeader->GetLineNum(); printf("*** #%-6d %5d bytes %-50s\n", i, size, typeName); printf("... %s:%d\n", fileName, lineNum); } // Clean up. free(ppBlockHeader); } /* ---------------------------------------- struct MemDigest */ struct MemDigest { char const *typeName; int blockCount; size_t totalSize; static TotalSizeGreaterThan(MemDigest &md1, MemDigest &md2) { return md1.totalSize > md2.totalSize; } }; /* ---------------------------------------- SummarizeMemoryUsageForType */ static void SummarizeMemoryUsageForType( MemDigest *pMemDigest, BlockHeader **ppBlockHeader, size_t startPost, size_t endPost ) { pMemDigest->typeName = ppBlockHeader[startPost]->GetTypeName(); pMemDigest->blockCount = 0; pMemDigest->totalSize = 0; for (size_t i = startPost; i < endPost; i++) { pMemDigest->blockCount++; pMemDigest->totalSize += ppBlockHeader[i]->GetRequestedSize(); assert(strcmp(ppBlockHeader[i]->GetTypeName(), pMemDigest->typeName) == 0); } } /* ---------------------------------------- TrackListMemoryUsage */ void TrackListMemoryUsage() { // If there are no allocated blocks, then return now. size_t numBlocks = BlockHeader::CountBlocks(); if (numBlocks == 0) return; // Get an array of pointers to all extant blocks. BlockHeader **ppBlockHeader = (BlockHeader **)calloc(numBlocks, sizeof(*ppBlockHeader)); BlockHeader::GetBlocks(ppBlockHeader); // Sort the blocks by type name. std::sort( ppBlockHeader, ppBlockHeader + numBlocks, BlockHeader::TypeGreaterThan ); // Find out how many unique types we have. size_t numUniqueTypes = 1; for (size_t i = 1; i < numBlocks; i++) { char const *prevTypeName = ppBlockHeader[i - 1]->GetTypeName(); char const *currTypeName = ppBlockHeader[i]->GetTypeName(); if (strcmp(prevTypeName, currTypeName) != 0) numUniqueTypes++; } // Create an array of "digests" summarizing memory usage by type. size_t startPost = 0; size_t uniqueTypeIndex = 0; MemDigest *pMemDigestArray = (MemDigest *)calloc(numUniqueTypes, sizeof(*pMemDigestArray)); for (size_t i = 1; i <= numBlocks; i++) // yes, less than or *equal* to { char const *prevTypeName = ppBlockHeader[i - 1]->GetTypeName(); char const *currTypeName = (i < numBlocks) ? ppBlockHeader[i]->GetTypeName() : ""; if (strcmp(prevTypeName, currTypeName) != 0) { size_t endPost = i; SummarizeMemoryUsageForType( pMemDigestArray + uniqueTypeIndex, ppBlockHeader, startPost, endPost ); startPost = endPost; uniqueTypeIndex++; } } assert(uniqueTypeIndex = numUniqueTypes); // Sort the digests by total memory usage. std::sort( pMemDigestArray, pMemDigestArray + numUniqueTypes, MemDigest::TotalSizeGreaterThan ); // Compute the grand total memory usage. size_t grandTotalNumBlocks = 0; size_t grandTotalSize = 0; for (size_t i = 0; i < numUniqueTypes; i++) { grandTotalNumBlocks += pMemDigestArray[i].blockCount; grandTotalSize += pMemDigestArray[i].totalSize; } // Dump the memory usage statistics. printf("\n"); printf("-----------------------\n"); printf("Memory Usage Statistics\n"); printf("-----------------------\n"); printf("\n"); printf("%-50s%5s %5s %7s %s \n", "allocated type", "blocks", "", "bytes", ""); printf("%-50s%5s %5s %7s %s \n", "--------------", "------", "", "-----", ""); for (size_t i = 0; i < numUniqueTypes; i++) { MemDigest *pMD = pMemDigestArray + i; size_t blockCount = pMD->blockCount; double blockCountPct = 100.0 * blockCount / grandTotalNumBlocks; size_t totalSize = pMD->totalSize; double totalSizePct = 100.0 * totalSize / grandTotalSize; printf( "%-50s %5d %5.1f%% %7d %5.1f%%\n", pMD->typeName, blockCount, blockCountPct, totalSize, totalSizePct ); } printf("%-50s %5s %5s %7s %s \n", "--------", "-----", "", "-------", ""); printf("%-50s %5d %5s %7d %s \n", "[totals]", grandTotalNumBlocks, "", grandTotalSize, ""); // Clean up. free(ppBlockHeader); free(pMemDigestArray); } } // namespace MemTrack /* ------------------------------------------------------------ */ /* ---------------------- new and delete ---------------------- */ /* ------------------------------------------------------------ */ /* ---------------------------------------- operator new */ void *operator new(size_t size) { void *p = MemTrack::TrackMalloc(size); if (p == NULL) throw std::bad_alloc(); return p; } /* ---------------------------------------- operator delete */ void operator delete(void *p) { MemTrack::TrackFree(p); } /* ---------------------------------------- operator new[] */ void *operator new[](size_t size) { void *p = MemTrack::TrackMalloc(size); if (p == NULL) throw std::bad_alloc(); return p; } /* ---------------------------------------- operator delete[] */ void operator delete[](void *p) { MemTrack::TrackFree(p); }


{waveshaper-shape-cluster.png width=373}
This contains the {Waveshaper_shape shape} {_parameter}, which selects the kind of wave shape, and the {Waveshaper_width width} {_slider} which alters the harmonic structure. For the pulse shape, this represents the width of the pulse in percent. For the saws shape, this represents the phase difference between two sawtooth waves, also in percent. For the various FM shapes, it represents the phase modulation depth in cycles. For the noise and impulse shapes, the width has no effect, nor do either of the {Waveshaper_mod_cluster modulation clusters}.


set loopdim x|y|z|t|e
By default, the animation dimension is time. This command allows you to set which dimension to animate.


07:15 to 11:00 am Ride for Peace
Non competitive ride from
Palacio de Governo to Cristo Rei.
BBQ at finish line.
BMX and kids especially welcome
04:30 Breakfast at Timor Lodge open
06:00 Trucks taking riders travel bags
leaves Timor Lodge for Camp Aileu
07:00 Stage 1 Starts Palacio de
Governo
04:30 Breakfast starts in Camp Aileu
07:00 Stage 2 race starts
15:00 Awards Ceremony
15:30 Entertainment starts
18:30 Entertainment ending
20:00 Kitchen closes
04:30 Breakfast starts in Camp Aileu
07:00 Stage 3 race starts
15:00 Awards Ceremony
15:30 Entertainment starts
18:30 Entertainment ending
20:00 Kitchen closes
04:30 Breakfast starts in Camp Aileu
07:00 Stage 4 race starts
15:00 Awards Ceremony
15:30 Entertainment starts
18:30 Entertainment ending
20:00 Kitchen closes
04:30 Breakfast starts in Camp Aileu
07:00 Stage 5 race starts
17:30 Pre drinks @ Timor Lodge
19:00 Dinner
20:00 Championship Awards Ceremony
10:00 After Party at Timor Lodge


Shania Twain calls out 'very ageist' country music radio stations
by Mariah HaasShania Twain is less than thrilled with the airplay that women in country music are currently getting on radio stations.
The 54-year-old icon, speaking to USA Today, explained how she hopes that will soon change, with women artists being heard more evenly on the platform.
“There's a lot of good female talent out there, and they've been more vocal about the resistance at radio to include them more equally in airplay,” Twain told the outlet.
SHANIA TWAIN ANNOUNCES NEW LAS VEGAS RESIDENCY
“I'm hoping that does start to make a change because there are many female artists with strong songs that belong in the Top 40 on country radio that are just not there," she added.
The "That Don't Impress Me Much" songstress, who is set to perform at the American Music Awards on Sunday, echoed similar sentiments made by other artists in the industry, including Miranda Lambert and Jennifer Nettles.
Nettles, 45, notably walked the CMA Awards red carpet last week donning a cape with powerful messages that read: "Play our f--kin records. Please & Thank You" and “Equal Play."
JENNIFER NETTLES CALLS FOR EQUAL PLAY WITH CMAS RED CARPET LOOK
In addition to more airplay for women artists, Twain further explained that radio has been "very ageist as well."
“I don't hear Reba [McEntire] on the radio anymore; I don't hear Patty Loveless on the radio anymore. I don't hear Shania Twain on the radio anymore in country! So that's got to change, too," Twain noted.
"Thankfully with technology, we do have other outlets of getting our music out there and radio isn't the end all be all of somebody's success today," she continued. "But it's very frustrating and it's a disservice not only to the artist, but to the public, that they can't turn on the radio and hear all the best music that's being made right now."
Twain also shared her thoughts on the dispute between Taylor Swift and Big Machine Label Group after it was alleged that Swift's former label initially was preventing the "Lover" singer from performing her earlier hit records at the AMAs.
CLICK HERE TO GET THE FOX NEWS APP
"I don't know a lot about the details of that, but I'm a big supporter of Taylor," Twain said. "I think she's just incredibly brilliant. I haven't had a chance to talk to her about it and I don't really know where everybody is coming from, but I'll always support the artist and their access to their own music.
"It seems a bit ridiculous to not have that."
The American Music Awards airs this Sunday at 8 p.m. ET on ABC.


LUMINARIAS
Reviewed by Harvey Karten New Latin Pictures Director: Jose Luis Valenzuela Writer: Evelina Fernandez, play by Evelina Fernandez Cast: Evelina Fernandez, Scott Bakula, Marta DuBois, Angela Moya, Dyana Ortelli, Seidy Lopez, Robert Beltran, Sal Lopez, Cheech Marin, Sab Shimono
There's nothing wrong with a sitcom, with its predictable, credibility-challenging plot, provided that the characters are vibrant and likeable and the writer's heart is in the right place. That's just the kind of TV-type comedy that "Luminarias" provides. Directed by Jose Luis Valenzuela, "Luminarias" had its birth as a staged play by the director's real-life wife, Evelina Fernandez, which the playwright--who radiates a spirited performance as its lead character--has successfully opened up for the big screen. Despite its mere one million-dollar budget," Luminarias" is the sort of picture that could make a grand showing in Latino communities throughout the U.S. and given its easy-listening format should draw a reasonable crossover audience as well.
Though the story bears some resemblance to Forest Whitaker's "Waiting To Exhale," which displayed Whitney Houston, Angela Bassett, Loretta Devine and Lela Rochon auspiciously despite that movie's redundant plot, Valenzuela's film deals with men who are not all jerks. What's more important, serious racial issues are discussed in some depth. While the characters in "Waiting to Exhale" are all black, this time we're treated to a Jesse-Jackson rainbow involving Koreans, Korean-Americans, Mexican-Americans, one Jewish-American, and one African-American, all jumbled together in an East Los Angeles nexus. The focus is on four well-to-do, professional Mexican-American women who get together regularly in an Angeleno restaurant known as Luminarias to discuss the men in their lives. They drink margueritas and tequilas, easing the way for the women to let it all hang out. We listen in on their jovial banter and serious arguments alike, absorbing an image of the affinities and antipathies of people we do not often get to see in the movie theaters: prosperous Latinas living in spacious housing, driving Mercedes and the like, and throwing lavish parties for their families and friends.
We quickly learn from their spirited restaurant banter that these women may be of the same professional class but their views on men and race diverge considerably. Andrea (Evelina Fernandez), a domestic relations lawyer in her forties, is herself getting divorced from her wayward husband Joe (Robert Beltran). She is particularly incensed that Joe is cavorting with an Anglo woman, furthering her own racist view that the only reason whites date Latinas is to feel superior. Despite her wealth, she admits to having a deeply felt rage. Her friend Sofia (Marta DuBois), on the other hand, is a therapist who believes in mixing in with the white society and has forsaken her old East Los Angeles neighborhood for the predominantly Anglo west side. Ironically, she is the only one of this gang of four to wind up with a Mexican man, a waiter named Pablo (Sal Lopez) who can barely speak English. In smaller roles Dyana Ortelli plays Irene, a flamboyant clothing designer who is ashamed of her transvestite brother (Geoffrey Rivas) and who has sworn off sex for the Lenten season, while Angela Moya performs in the role of Lilly, an artist who is dating a Korean man, Lu (Andrew C. Lim).
The one subplot that does not mesh with the buoyant tone of the rest of the story involves Cindy (Seidy Lopez), in a custody battle with the physically abusive ex-husband, Tony (Richard Coca). But as the hub of the story, Scott Bakula turns out a credible performance as Joseph, a lawyer who finds himself opposing Andrea in court. Drawn to his adversary, Joseph is at first rebuffed by Andrea not only because he is fighting against the interests of her client but more important because he is white and Jewish. Struggling with her own racist attitudes toward Anglos, Andrea is frank and cutting as she challenges Joseph to come up with the real reason he is interested in a woman who is not of his race and religion. As in most romantic comedies, their differences keep them apart until the movie's conclusion in which Valenzuela wraps up all the loose ends too conveniently for a tale which seeks to elevate itself above sit-comish fare.
The music is terrific though not intrusive and the upbeat tempo of this good-hearted and spirited comedy makes "Luminarias" easy to take as social commentary that deals with themes of identity, marriage and independence. This is one of those rare pictures that do not treat Spanish-speaking Americans as either gangsters or servants but as people who have prospered in a multi-cultural society that all too often patronizes and demeans even those non-whites who have lived in the U.S. for generations.
Rated R. Running time: 100 minutes. (C) 2000 by Harvey Karten<EMAIL_ADDRESS>The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


{% extends "recipes/base.html" %} {% block head_title %} Deleted {% endblock head_title %} {% block content %}
Recipe successfully deleted.
Back


AS GOOD AS IT GETS A Film Review By Daniel Chodos Copyright Dan Chodos 1998
"What if this is as good as it gets?", bellows Melvin Udall (Jack Nicholson) midway through the film in a psychiatrist's waiting room. James Brook's delightful new comedy answers that question with a firm "no, it gets better Jack," and then takes us on a journey to prove it. There are three central characters to "As Good As It Gets": Melvin the obsessive compulsive but successful writer, Carol (Helen Hunt), the warm hearted, single mothered waitress, and Simon (Greg Kinnear), the gay artist who lives next door. Each have something to gain from one another and although their stories knock on the door of clichesville it is entertaining none the less to watch.
The film relies on Nicholson's natural screen charm to get us to overlook his homophobia and racist reactions to the full illustrious city of New York.. We're supposed to juicily bite into the fact that his bigotry should be excused because he has obsessive compulsive disorder. In that aspect "As Good As It Gets" insults its audience floundering in between a serious character study of people OCD and a light hearted comedy. Take one scene where Melvin obsessively washes his germs away using 3 bars of soap. It's a painful scene to watch, sloppily giving the audience an excuse to pity poor Melvin. It doesn't belong in this movie because there is no justification for it. It's obvious from the get go that Brook's has trouble layering the comedy he's aiming for with a character study the we deserve.
The plot unfolds like a pyramid as Melvin attempts to reach for a higher level of happiness in his life. Carol, the waitress at a local restaurant he routinely eats in has a sick son with a very serious case of asthma. In an almost desperate attempt to cling to the only person who will give him the time of day, Melvin essentially buys Carol's affection in somewhat awkward and seedy circumstances. We know from their first encounter on screen that it's only a matter of time (in fact, too long) before Melvin and Carol get romantically linked.
But what stands out is the terrific performance by Kinnear as the understated Simon. It seems as if Brooks doesn't even try to reach for something and as a result comes a magnificent character developed from simple storytelling. If he had only applied that same style to Melvin and Carol, leaving out the unnecessary footnotes and relationship filler, we would have fluency on the same level (although more serious) as Woody Allen's "Annie Hall".
While Nicholson's charm temporarily sways us from thinking about the awkward moments, there are much deeper questions we want answered. Why after so long does Melvin want to change? We want to believe that Melvin is a more complex character than nasal-yet-funny phrases like "do you get me sweetheart?" Unfortunately, Melvin and the film are funny, but laughter here is only skin deep.
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Class AStar
Interface to setup and run the A* algorithm.
Inheritance
Inherited Members
Namespace: Fibula.Common.Utilities.Pathfinding
Assembly: Fibula.Common.Utilities.dll
Syntax
public class AStar
Constructors
| Improve this Doc View SourceAStar(INodeFactory, INode, INode, Int32)
Initializes a new instance of the AStar class.
Declaration
public AStar(INodeFactory nodeFactory, INode start, INode goal, int maxSearchSteps = 100)
Parameters
| Type | Name | Description |
|---|---|---|
| INodeFactory | nodeFactory | A reference to the node factory in use. |
| INode | start | The starting node for the AStar algorithm. |
| INode | goal | The goal node for the AStar algorithm. |
| System.Int32 | maxSearchSteps | Optional. The maximum number of Step operations to perform on the search. |
Properties
| Improve this Doc View SourceCurrentNode
Gets the current node that the AStar algorithm is at.
Declaration
public INode CurrentNode { get; }
Property Value
| Type | Description |
|---|---|
| INode |
Methods
| Improve this Doc View SourceGetLastPath()
Gets the path of the last solution of the AStar algorithm. Will return a partial path if the algorithm has not finished yet.
Declaration
public IEnumerable<INode> GetLastPath()
Returns
| Type | Description |
|---|---|
| System.Collections.Generic.IEnumerable<INode> | Returns null if the algorithm has never been run. |
Run()
Steps the AStar algorithm forward until it either fails or finds the goal node.
Declaration
public SearchState Run()
Returns
| Type | Description |
|---|---|
| SearchState | Returns the state the algorithm finished in, Failed or GoalFound. |
Step()
Moves the AStar algorithm forward one step.
Declaration
public SearchState Step()
Returns
| Type | Description |
|---|---|
| SearchState | Returns the state the alorithm is in after the step, either Failed, GoalFound or still Searching. |


DG's Greener Side is a family owned and operated lawncare and landscaping business located in Westmoreland County. We handle all phases of residential and commercial lawncare/landscape in the Westmoreland County area.
We believe in hard work and quality service for a reasonable price. We have been in business for several years and have done hundreds of various lawncare/landscape jobs.
Our company is very involved and takes great pride in our community. We go the extra mile because we care about our customers, and we care that your yard is a DG's Greener Side maintained lawn.
We are very blessed that our business continues to grow every year as a result of referrals. We would like to thank everyone who has recognized our hard work, commitment, and quality service, that has referred us.


Novation Drumstation / D Station
Single Patch Editor
This patch editor should work with any Drumstation with v1.3 firmware, and with the D Station. I cannot say if it will work right with earlier firmware than that (testing was done on a D Station).
Communicating with Edisyn
It'd be best if you selected PROGRAM mode. Set the Drumstation's MIDI Receive (Rx) channel to be the same as Edisyn's MIDI Send/Receive channel.
Sending and Writing a Patch to the Drumstation
The Drumstation has very, very limited sysex. Edisyn can send a single patch dump to the synth. If the Drumstation's "Write" switch is set to PROTECT, then when Edisyn issues a send, this sends the patch dump to the synth's current working memory as normal. If the "Write" switch is set to ENABLE, then Edisyn's send in fact overwrites the current patch slot.
If you have recently sent a patch to current working memory, you can also write that patch by switching the "Write" switch to ENABLE, selecting the desired patch (program) number, and pressing "Write". Remember that you can only write to slots 25...39; the earlier slots are read-only presets.
Receiving a Patch from the Drumstation
You have to send the patch manually from your unit. To do this, go to MODE 5 ("Save"). You should see an "SS" on-screen. This is for saving a single program. Then press the "+" (plus) button once. The Drumstation will send the patch to Edisyn, which should update itself in response.
Sending Individual Parameters
Edisyn can update a limited number of individual parameters via CC. See the "Controller Map" in your manual for a list of the parameters and their CC values: Edisyn will update them in real time. Other parameters can only be updated via patch dump.
Bank Sysex
The Drumstation can also send and receive Bank sysex messages: these are messages which contain all 15 writable patches (25...39). You can send this kind of message from the Drumstation to Edisyn by going to MODE 5 ("Save"), then selecting "SA", then pressing the "+" button once. Edisyn can save these messages, upload them to the Drumstation, or edit any one patch in them.
Gotchas
- While it would be possible to program Edisyn to change the patch and then do a patch send, because we don't know if you've set the switch to PROTECT or to ENABLE, it seems foolish to do this. For this reason, Edisyn doesn't even display a patch number for the patch.
- There are many myths surrounding the differences between the V1 Drumstation, the V2 Drumstation, and the D Station. But the truth is, if you have updated your Drumstation to firmware v1.3, then it is identical in all respects to the D Station, including polyphony and MIDI features.
Thanks
Thanks to Chris Pacejo<EMAIL_ADDRESS>for bugfixes.
| By
| Sean Luke
|
| Date
| August 2020
|


|
density
C++11 library for paged memory management, function queues, heterogeneous queues and lifo memory management
|
The directory 'test' contains a test program that you can build with cmake. The directory 'bench' contains a benchmark program that you can build with cmake. On Windows you can also build both at once with Visual Studio 2017 using the solution test/vs2017/density_tests.sln.
The test program executes a number of test on all the data structures of the library. When doing massive multithread tests, it scales to the host machine spawning 3 threads for each logical cpu of the system.
The test program supports the following command-line parameters:
- rand_seed:<32-bit unsigned integer> - default is zero. Seed used to initialize the main random generator. If it is zero the random generator is initialized with std::ranom_device. In multi-thread test the random generator for the spawned threads is forked from the main one. - exceptions:<0 or 1> - default is 1. If non-zero enables the testing of exceptional execution paths. This is done using test allocators and test objects that throw an exception once in every point that may possibly throw. - spare_one_cpu:<0 or 1> - default is 1. If non-zero in multi-thread tests the second logical processor is not used. - print_progress:<0 or 1> - default is 1. If non-zero shows a percentage of the progress during queue test - test_allocators:<0 or 1> - default is 1. If non-zero enables special allocators that detect bugs in the memory management. The tests with the normal allocators are executed in any case. - queue_tests_cardinality:<size_t> - default is 2000. Number of elements to push in every queue tests. In multi-thread tests this number is partitioned among all threads.
If the test program is built with the macro DENSITY_USER_DATA_STACK defined, the normal data stack is replaced with a test data stack that checks for bug in the memory management.
Example:
The benchmark program needs to read the source files from which it is compiled. It uses the macro __FILE__ to locate them, which generally has a path relative to the project file. So if you execute the program from another location, you have to provide a source directory.
The benchmark program supports the following command-line parameters:
-source:<string> - by default empty, max length = 4095. Path to prepend to the __FILE__ macro to access the source files.


//So here is a fenced in block where I'm trying to test javascript syntax highlighting console.warn("yo this is crazy");


Install and configure Ghost with Nginx - Arch Linux, CMS, Ghost, Nginx
Difficulty: 2
Time: 1.0 hrs
Ghost is a simple blogging platform that is fast and easy to set up and provides good customization options. This article will help you to set up a Ghost blogging platform with Nginx on Arch Linux.
These procedures assume that you have sudo
privileges.
When asked about the selection of member of base-devel, select all members by pressing Enter.
Ghost.org
.
/var/www/ghost
.
ghost
directory.
When starting, Ghost displays the message "Your blog is now available on http://provided URL".
To shut down the blog and return to the command prompt, press Ctrl+C.
/var/www/ghost/config.js
for editing.
production: { url: 'http://Your IP Address or domain name', mail: {}, database: { client: 'sqlite3', connection: { filename: path.join(__dirname, '/content/data/ghost.db') }, debug: false }, server: { // Host to be passed to node's `net.Server#listen()` host: 'Your IP Address', // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT` port: '2368' } }
http://Your domain name or IP Address:2368/
. The Ghost blog should be available via specified URL. In this article, you installed and configured Ghost with Nginx on Arch Linux. The Ghost blogging platform, with its ease of deployment and use, can help you set up and extend your content management infrastructure. For an optimized performance, you can host mulitple Ghost blogs on a single server.


class Solution: def maximumRequests(self, N: int, requests: List[List[int]]) -> int: M = len(requests) ret = 0 for i in range(1 << M): changes = [0] * N request_fulfilled = 0 for j in range(M): if i & (1 << j): u, v = requests[j] changes[u] -= 1 changes[v] += 1 request_fulfilled += 1 if all([x == 0 for x in changes]): ret = max(ret, request_fulfilled) return ret


Software Developer – Machine-learning/Artificial-intelligence - Huntsville, AL 35805
IERUS specializes in a variety of electromagnetic spectrum technology research, testing, and implementation. IERUS supports customers with a diverse set of competencies including software, firmware, and hardware development, air and missile defense, and systems engineering. IERUS develops value for our defense and commercial customers through accelerations of the technology life cycle: identifying, creating, transitioning, and producing technologies with integrity of purpose and product. IERUS are the recipients of the “Best Places to Work” two years running, and were finalists the five years prior. IERUS offers competitive compensation packages, retirement options, and benefits packages. To learn more, please visit www.ierustech.com.
IERUS participates in projects that generally seek to apply and advance machine-learning (ML) and artificial intelligence (AI) as applied to our relevant domains of expertise. Past and present areas of expertise include:
RADAR
Signal processing, system design, operational optimization, detection, discrimination, and tracking
RF/EO/IR
Signal processing, system design, signatures, tracking, and testing
Electronic Warfare (EW)
System design, research, testing, counter-measures
Antennas
System design and testing
Image processing
Segmentation, recognition, and denoising
Critical infrastructures
Process control systems, situational awareness, cyber security, anomaly detection
Vehicles and vessels
Situational awareness, cyber security, anomaly detection
ML/AI R&D
Algorithm development, GPU acceleration, global and local optimization of complex and fused data, adversarial ML, network architecture and computability
Minimum Educational Experience:
MS degree in Electrical Engineering, Computer Science, Applied Mathematics, Statistics, or related field, plus 2+ years of experience in applying software engineering solutions featuring machine-learning, to the problem types described above
OR: BS degree in Electrical Engineering, Computer Engineering, or Computer Science plus 3+ years’ experience in applying software engineering solutions featuring machine-learning, to the problem types described above
Minimum Qualifications:
Must be a U.S. citizen
Secret security clearance, preferred TS clearance and TS/SCI opportunities
Experience implementing machine learning solutions for engineering and scientific domains. Should be familiar with related implementation tasks such as feature selection, regression, classification, sensor-fusion, time-series analysis, missing data, optimization, recommender systems, etc.
Mastery of rapid prototyping in at least 1 (preferably 2 or more) of the following scripting languages: Python, R, MATLAB, etc.
Experience implementing solutions using at least 2 of the following supervised methods: SVM/SVR, fuzzy systems (TSK, etc.), tree ensemble methods (Bayesian, bagging, boosting, etc.), NNs (supervised), others
Experience applying advanced math and statistics, especially optimization and related linear algebra techniques
Preferred Qualifications:
PhD in Electrical Engineering, Computer Science, Computer Engineering or related field
Proficiency in at least 1 hard programming language (C/C++, Java, etc.)
Experience implementing solutions using any of the following unsupervised methods: Clustering (k-nearest neighbor, DBSCAN, Dirichlet, etc.), autocorrelation, Deep learning methods (DNNs, CNNs, RNNs, LSTMs, etc.) and packages (TensorFlow, Theano, Torch, Caffe, Neon, etc.), GMMs, HMMs, etc.
Experience with Government funding agencies and programs (e.g. DARPA, IARPA, AFRL, SBIR/STTR, RiF, etc.)
Publication and/or patent history of applying original solutions to relevant types of problems
Experience implementing solutions using signal processing algorithms and packages
TS/SCI clearance;
Engineering experience in the defense industry;
Image processing experience;
Radar system analysis experience;
RF Electronics experience;
Antenna design and analysis experience;
Software Defined Radio (SDR) experience;
Analysis tool-building experience;
Target acquisition, tracking and/or algorithm development;
Advanced modeling skills and optimization;
Knowledge of domain specific RADAR principles, including signal processing, RCS analysis, target acquisition; target tracking, resource management, discrimination, and battle manager interfaces;
Experience with GMD/BMDS systems, BMDS radar systems, radar simulation tests and or radar metrics; and/or
Location:
Huntsville / Various Locations in the US
IERUS Technologies is an Equal Opportunity/Affirmative Action Employer committed to recruiting, hiring and retaining a diverse workforce. All qualified applicants will receive consideration for employment without regard to race, color, religion, sex, sexual orientation, gender identity, national origin, disability or veteran status. For more information please click here.
IERUS Technologies participates in E-Verify.


This chapter provides an overview of new and changed deployment features in JDK 8.
The following sections describe the improvements and the release in which they were introduced.
For information on JDK 7, see Chapter 34, "Java Rich Internet Applications Enhancements in JDK 7."
The 8u40 release includes the following enhancements:
The UserJvmOptionsService
API is provided for self-contained applications. This API can be used to add a settings feature to your application that enables users to set the JVM options to use when the application is run. See Chapter 15, "Customizing JVM Options in Self-Contained Applications" for information.
File associations can be registered for self-contained applications. See Section 7.3.7, "Associating Files with a Self-Contained Application" and the <fx:association> element for information.
Arguments can be passed to a self-contained application when the application is started from the command line. See Section 7.3.6, "Passing Arguments to a Self-Contained Application" for information.
Self-contained applications can be created with multiple entry points when built using Ant. See Section 7.3.8, "Supporting Multiple Entry Points" for information.
The <fx:bundleArgument>
element for <fx:deploy>
Ant task supports the following new arguments for OS X bundlers: mac.CFBundleVersion
, and mac.dmg.simple
. See <fx:bundleArgument> for information.
Starting with JDK 8u31 release, the SSLv3 protocol is removed from the Java Control Panel Advanced options. See the 8u31 Update Release Notes for more information.
The 8u20 release includes the following enhancements related to deployment:
The JavaFX Packager tool is renamed to Java Packager and is run with the javapackager
command. Support for self-contained applications is expanded to enable arguments to be passed to the bundlers that are used to generate the native installable packages. See Chapter 7, "Self-Contained Application Packaging."
The Medium security level has been removed. Only High and Very High are supported. See Section 20.4.1, "Security Level."
For enterprise customers who use the Deployment Rule Set, the attribute force
is available for the action
element. When this attribute is set to true
, the JRE version requested by any RIA that matches the rule is overridden and the RIA is run with the version of the JRE that is specified in the rule. See Chapter 28, "Deployment Rule Set."
The 8u11 release includes the following enhancements related to deployment:
An option to suppress offers from sponsors when the JRE is installed or updated is available in the Advanced tab of the Java Control Panel. See Section 20.5.12, "Miscellaneous" for information.
The Entry-Point attribute can be included in the JAR file manifest to identify one or more classes as a valid entry point for your RIA. See Section 26.6, "Entry-Point Attribute" for information.
The 8u5 release includes the following enhancements related to deployment:
The frequency in which the security prompts are shown for an application has been reduced.
The JDK 8 release includes the following enhancements related to deployment:
For sandbox Rich Internet Applications (RIAs), URLPermission
is now used to allow connections back to the server from which they were started. URLPermissions
is granted based on protocol, host, and port of the code source. This change has the following implications:
For sandbox RIAs, SocketPermissions
for the origin host is no longer granted. Calls from JavaScript code to the RIA are not granted SocketPermissions
.
Sandbox RIAs that are loaded from a server using the HTTP protocol are not allowed to connect back to the server using the HTTPS protocol.
Sandbox RIAs loaded from a server on a specific port using either the HTTP or HTTPS protocol are not allowed to connect back to a different port on the server. For example, if the RIA is started from https://www.example.com:80
, then the RIA is not allowed to connect back to https://www.example.com:8888
.
Sandbox RIAs loaded from a server using either the HTTP or HTTPS protocol and a domain name are not allowed to connect back to the server using an IP address. For example, if the RIA is started from https://www.example.com:8080
, then the RIA is not allowed to connect back to https://<IP_ADDRESS>:8080
.
Privileged RIAs loaded from a server using the HTTP protocol do not accept calls from JavaScript code using the HTTPS protocol. To make calls to your RIA from JavaScript code using HTTPS, you must load your RIA using HTTPS.
The Permissions
attribute is now required in the JAR file manifest for the main JAR file of all RIAs at all security levels. See Chapter 26, "JAR File Manifest Attributes for Security" for information on the Permissions
attribute.
The Java class file format has been updated because of JSR 292, Java Virtual Machine Support for Non-Java Languages. Consequently, the Pack200 engine has been updated accordingly to ensure that Java SE 8 class files are compressed effectively. In particular, the Pack200 engine now recognizes constant pool entries and new bytecodes introduced by JSR 292.
As a result, compressed files created with this version of pack200 will not be compatible with older versions of unpack200.
In general, if a compressed file contains Java SE 8 or Java SE 7 class files, then it will not be compatible with older unpackers. (For example, if a compressed file contains Java SE 7 class files, then it will not be compatible with unpackers from Java SE 6 or earlier.)
See Section 30.2, "Deploying JAR Files Compressed with Pack200" and RFE 6981776.
The old Java Plug-in (the version available prior to Java SE 6 Update 10) has been removed from this release. See RFE 7076143.


GroupTable
component is a table with an ability to group information dynamically by any field. In order
to group a table by a column, drag the required column and drop it to the left of the separator in the
table header.
A groupDatasource
must be specified for GroupTable
in the datasource
attribute
of the rows
element. Otherwise, grouping will not work.
group
is an optional element that can be present in a single instance inside columns
element.
It contains a set of column
elements, by which grouping will be performed initially when opening a screen.
The functionality of GroupTable
is similar to a simple Table.


MOULIN ROUGE ------------
In 1899, the summer of love, impoverished British writer Christian (Ewan McGregor, "Star Wars: Episode I - the Phantom Menace") arrives in Paris to find inspiration in Montmarte's bohemian artistic neighborhood. When a narcoleptic Argentian (Jacek Koman) and a midget dressed as a nun (John Leguizamo as Henri de Toulouse Lautrec) fall through his ceiling, Christian's cast in their alpine play, "Spectacular, Spectacular." He breaks their collective writers' block by belting out "The hills are alive!," is declared the play's new author and trundled off to meet Zidler (Jim Broadbent, "Topsy Turvy"), the owner of their venue, the "Moulin Rouge."
Lautrec promises Christian that he'll meet with the play's star, Satine (Nicole Kidman) alone, just as Zidler is promising the same to the Duke (Richard Roxburgh, "Mission: Impossible II"), a potential backer. Satine, Moulin Rouge's star and courtesan, gets mixed signals and sets to seducing Christian, believing he's the wealthy Duke.
The story of "Moulin Rouge" (written by Baz Luhrmann and Craig Pearce, "William Shakespeare's Romeo + Juliet") mirrors Dumas' "Camille," where another consumptive courtesan captures the heart of an idealistic young man, but director Luhrmann uses the age old tale as a springboard to dazzle his audience with lavishly colorful visuals, dizzily photographed, alarmingly editted and musically propelled via snippets of countless pop tunes.
Our initial introduction to the Moulin Rouge is through the eyes of Christian after imbibing in absinthe (guided by Australian songstress Kylie Minogue as the green fairy), the legendary hallucinogenic green liqueur. The skirts of can-can dancers whoosh by with a kaleidoscopic effect as the performers sing the most unlikely medley of "Voulez Vous Couchez Avec Moi?" and "Smells Like Teen Spirit." A wild assortment of freaks and fashionistas make the patrons of the Moulin Rouge the Studio 54'ers of their day. Then Satine makes her entrance, dangling from above on a swing, brilliant red hair and lips spotlighted against chalk white skin. Satine's introductory medley, "Diamonds Are a Girl's Best Friend/"Material Girl," prove that Kidman can carry a tune, but are an uninspired choice.
Luhrmann then gives us a dose of the ludicrous as Satine writhes around her opulent Indian elephant abode as Christian recites the 'poetry' of Elton John's "Your Song." The real Duke's arrival calls for quick thinking on Satine's part and aided by Christian's fellow playmates she outlines the play's plot on the spot. This sequence plays as if the Marx Brothers collided with the Three Stooges.
After this, Luhrmann eases up on the hyperkinetic editting and "Moulin Rouge" settles in with its first truly showstopping number in which Zidler performs "Like a Virgin" for the Duke accompanied by a chorus of dancing waiters. Other highlights include the narcoleptic Argentian's advise to Christian about getting involved with courtesans by way of a tango number set to "Roxanne," and the climax of the play within a play.
Luhrman has created a great piece of eye candy, from his opening black and white zoom through the streets of Paris leading to the Moulin Rouge (looking like "The Cabinet of Dr. Caligari" crossed with "The City of Lost Children") to the multi-level Indian set stages of a Bollywood Ziegfeld. His "Romeo + Juliet" team of cinematographer Donald McAlpine, editor Jill Bilcock, and production designer/costume designer Catherine Martin are joined by art director Ann-Marie Beauchamp and Set Decorator Brigitte Broch ("Chronos," "Amores Perros").
Yet all the film's spectular excesses don't add up to a completely satisfying experience, careening as it does from slapstick to melodrama. Kidman looks ravishing, but her plight never pulls on the heartstrings. McGregor fares better, largely due to the real emotion he delivers with his full bodied singing voice. Broadbent's Zidler is a pragmatic, rather than evil, version of Joel Grey's "Cabaret" emcee and he gives the film's most interesting performance (when Luhrmann lets us see it), yet his presence distractingly recalls the theatrical "Topsy Turvy." Leguizamo is little more than a tearful clown - Toulouse who? Roxburgh's Duke is as two dimentionally villainous as the plot demands.
"Moulin Rouge" is itself like a courtesan, a lavishly oufitted, desirable beauty who excels at artifice.
B
For more Reeling reviews visit www.reelingreviews.com
<EMAIL_ADDRESS><EMAIL_ADDRESS>The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Internship
Google DeepMind, London
Internship
Flickr, San Francisco
Ph.D in Computer Science
MILA Lab, University of Montreal
Research internship
idiap Research Institute, Switzerland
Visiting student
Jim DiCarlo’s lab, MIT
M.Sc. in Artificial Intelligence
Universitat Politècnica de Catalunya
B.Sc. in Physics
Sharif University of Technology
You can find my most up to date pulications list at Google Scholar


Vote
Crossbar
.io
Synchronizes votes across all demo instances in real-time, using a Node.js backend.
Open additional instance
Crossbar.io Homepage
Vote for your favourite flavour of ice cream!
Banana
Vote
Chocolate
Vote
Lemon
Vote
Reset Votes


Error 422: Unprocessable Entity
The change you wanted was rejected. Maybe you tried to change something you didn't have access to. For more information, please contact Fenhl on Discord or at
<EMAIL_ADDRESS>.


JavaScript Event Challenge: Challenge 23
Here is a paragraph of text
Here is another paragraph of text
Here is a third paragraph of text
Turn Them all Green Dammit!


Type of Event
Private
Corporate
Wedding
Guest count?
Duration?
Vibe and Feel
Classy
Upbeat
Rager
DJ Services Quote
DJ Hourly Rate ~ $
Sound System ~ $
Complete the form now to recieve a reply with DJ availability!
Your Name
Phone Number
Email


TechFire
Dashboard
Constants
Subsystems
Vision Debug
View Camera
t =
waiting for data
Shooter
---
100rpm/y section, 1000ms/x section
Feeder
50rpm/y section, 1000ms/x section
Drive linear
---
Drive angular
Gear Holder
---
Hopper
---
Climber
---
Recorder
Stop Recording
Start Recording
Download CSV
Raw Values
{{k}}
{{v}}


Firebase is Google’s mobile platform that helps you quickly develop high-quality apps and grow your business.


These release notes cover new developer and user-facing incompatibilities, important issues, features, and major improvements.
MultiRowRangeFilter is a filter to support scanning multiple row key ranges. If the number of the ranges is small, using multiple scans can also do the same thing and can work well. But when the number of ranges are quite big (e.g. millions), use the MultiRowRangeFilter will be nice. In this filter, the ranges will be sorted and merged, so users do not have to take care of ranges are not continuous. And if users are using something like rest, thrift or pig to access the data the filter might be the practical solution.
Allow a directory containing the jars or some wildcards to be specified, such as: hdfs://namenode:port/user/hadoop-user/ or hdfs://namenode:port/user/hadoop-user/*.jar
Please note that if a directory is specified, all jar files(.jar) directly in the directory are added, but it does not search files in the subtree rooted in the directory. Do not contain any wildcard if you would like to specify a directory.
Adds a PRIORITY property to the HTableDescriptor. PRIORITY should be in the same range as the RpcScheduler defines it (HConstants.XXX_QOS).
Table priorities are only used for region opening for now. There can be other uses later (like RpcScheduling).
Regions of high priority tables (priority >= than HIGH_QOS) are opened from a different thread pool than the regular region open thread pool. However, table priorities are not used as a global order for region assigning or opening.
HBASE-16052 improves the performance and scalability of HBaseFsck, especially for large clusters with a small number of large tables.
Searching for lingering reference files is now a multi-threaded operation. Loading HDFS region directory information is now multi-threaded at the region-level instead of the table-level to maximize concurrency. A performance bug in HBaseFsck that resulted in redundant I/O and RPCs was fixed by introducing a FileStatusFilter that filters FileStatus objects directly.
When LocalHBaseCluster is started from the command line the Master would give up after 30 seconds due to a hardcoded timeout meant for unit tests. This change allows the timeout to be configured via hbase-site as well as sets it to 5 minutes when LocalHBaseCluster is started from the command line.
A new hfile configuration "hfile.index.block.min.entries" which defaults to 16 determines how many entries the hfile index block can have at least. The configuration which determines how large the index block can be at max (hfile.index.block.max.size) is ignored as long as we have fewer than hfile.index.block.min.entries entries. This ensures that multi-level index does not build up with too many levels.
HBase now ensures the jsr305 implementation from the findbugs project is not included in its binary artifacts or the compile / runtime dependencies of its user facing modules. Downstream users that rely on this jar will need to update their dependencies.


The combined region of Kumaon and Garhwal has been known as Uttarakhand since the time of the Puranas, the ancient Hindu scriptures.Uttarakhand, the 27th state of India, is often referred as the Land of Gods. It is a place blessed with the beauty of heaven and the grace of Gods. This is the place where the rivers passing through the huge rocks and wind passing through large pine trees produces a natural melody by itself. It was carved out of the state of Uttar Pradesh on November 9, 2000. It is one of the most beautiful state in the Indian union. Apart from the beautiful views of Himalayas, it is also home of the point of origin of Ganga and Yamuna. Gangotri, Yamunotri, Badrinath and Kedarnath are some of the places regarded sacred by Hindus.
Uttarakhand borders China in the north and Nepal to the east, while its neighbour states are Himachal Pradesh to the west and Uttar in the south. The region is traditionally referred to as Uttarakhand in old literature and scriptures which derives from the Sanskrit for North Country. The provisional capital of Uttarakhand is Dehra Dun which is also a rail-head and the largest city in the region. The small hamlet of Gairsen has been mooted as the future capital owing to its geographic centrality but controversies and lack of resources have led Dehra Dun to be the provisional capital. The High Court of Uttarakhand is situated in Nainital though most of the litigation is in Dehra Dun or Haridwar.


Slow, maybe, but bloc is on the right path to integration
by PATTY MAGUBIRAIn Summary
- The EAC is working on making it easy for students and professionals to work in any country in the bloc, secretary general says.
East Africans have more to celebrate as the East African Community marks its 20th anniversary, says EAC Secretary General Liberat Mfumukeko.
Speaking at the official launch of the anniversary’s celebrations in Arusha, Mr Mfumukeko said the integration agenda has brought about a number of benefits.
“Unfortunately, we tend to look at the problems, but we’re headed in the right direction regardless of what you have heard recently,” he said in reference to the postponed November 30 Heads of State Summit.
He however noted that the region is still heavily dependent on imports from Europe and Asia.
He recalled the situation 11 years ago, when Burundian companies were struggling to import goods from the port of Dar es Salaam, but the EAC’s programme of harmonising Customs authorities across the region has made doing business easy.
“When I came to Arusha in 2015, we had to stop twice at the Namanga border. It is better today, we can cross more easily than it used to be,’’ he said, referring to the no visa rule for East African citizens moving within the bloc.
Also Read
-
Ethiopia's Sidama vote to form autonomous region
-
Malaysia's last known Sumatran rhino dies
-
Bolivia's interim President rejects amnesty for Morales
-
Plane crash kills at least 18 in eastern Congo
Advertisement
The EAC is working on making it easy for students and professionals to work in any country in the bloc.
In healthcare, the EAC has funded the establishment of the first centre of excellence at the Muhimbili National Hospital in Dar es Salaam, Tanzania, where all East Africans can have heart disease diagnosis and surgery instead of travelling abroad for the same.
“About three weeks ago, we inaugurated a similar centre for kidney diseases in Nairobi, Kenya,” Mr Mfumukeko said, adding that another programme for training medical doctors was in progress at the Agha Khan University, Nairobi.
He also mentioned the completed Arusha-Namanga-Nairobi and Holili-Taveta roads. And, recently, EAC raised $800 million for the Malindi-Mombasa-Horohoro-Tanga-Bagamoyo road whose construction will start soon.
The community has also negotiated with the African Development Bank for a $2.5 billion facility for infrastructure.
“We’re now in a tendering process, but in two or three years you will be able to go to Lusaunga up to Rusumo and Kigali on a nice road. You’ll be able to go to Kasulu, Manyovu up to Bunjumbura on a highway,” Mr Mfumukeko said.


Dual Palindromes
Mario Cruz (Colombia) & Hugo Rickeboer (Argentina)
A number that reads the same from right to left as when read from left to right is called a palindrome. The number 12321 is a palindrome; the number 77778 is not. Of course, palindromes have neither leading nor trailing zeroes, so 0220 is not a palindrome.
The number 21 (base 10) is not palindrome in base 10, but the number 21 (base 10) is, in fact, a palindrome in base 2 (10101).
Write a program that reads two numbers (expressed in base 10):
and then finds and prints (in base 10) the first N numbers strictly greater than S that are palindromic when written in two or more number bases (2 <= base <= 10).
Solutions to this problem do not require manipulating integers larger than the standard 32 bits.
A single line with space separated integers N and S.
3 25
N lines, each with a base 10 number that is palindromic when expressed in at least two of the bases 2..10. The numbers should be listed in order from smallest to largest.
26
27
28


After all MCA scope in India is growing rapidly so if we talk about MCA salaries in India, the basic salary starts from INR 2.5L
Has MCA job salaries also increased according to time and experience apart from this the MCA salary in Wipro is started approximately from 2.5 lakh?
After doing MCA there are lots of job opportunities in MCA so let's discuss job after MCA and salaries of it on the scale of experience
For freshers, the salary starts from nearly 14000 per month and for people having experience of one year or more than that are having salaries that start from 26000 per month and goes up to 1.2 lakh annually according to the job designation and job place.


@Beta val GoMoveHandler: SgfMoveHandler
The move handler used by SgfNodeHandler to handle Go moves.
Checks for captured stones after each move according to the SGF specifications.
SGF


Manager for all aspects of filters in FlashPhoto, including initialization of GLUI control elements for filters, filter creation, application, deletion.
More...
#include <filter_manager.h>
Inherited by image_tools::MIAFilterManager.
|
|
void | AddBlurToGLUI (GLUI_Panel *filter_panel, void(*s_gluicallback)(int)) |
| |
|
void | AddMotionBlurToGLUI (GLUI_Panel *filter_panel, void(*s_gluicallback)(int)) |
| |
|
void | AddSharpenToGLUI (GLUI_Panel *filter_panel, void(*s_gluicallback)(int)) |
| |
|
void | AddEdgeDetectToGLUI (GLUI_Panel *filter_panel, void(*s_gluicallback)(int)) |
| |
|
void | AddThresholdToGLUI (GLUI_Panel *filter_panel, void(*s_gluicallback)(int)) |
| |
|
void | AddSaturationToGLUI (GLUI_Panel *filter_panel, void(*s_gluicallback)(int)) |
| |
|
void | AddChannelToGLUI (GLUI_Panel *filter_panel, void(*s_gluicallback)(int)) |
| |
|
void | AddQuantizationToGLUI (GLUI_Panel *filter_panel, void(*s_gluicallback)(int)) |
| |
|
|
float | channel_color_red_ |
| |
|
float | channel_color_green_ |
| |
|
float | channel_color_blue_ |
| |
|
float | saturation_amount_ |
| |
|
float | threshold_amount_ |
| |
|
float | blur_amount_ |
| |
|
float | sharpen_amount_ |
| |
|
float | motion_blur_amount_ |
| |
|
enum UICtrl::MotionBlurDirection | motion_blur_direction_ |
| |
|
int | quantize_bins_ |
| |
Manager for all aspects of filters in FlashPhoto, including initialization of GLUI control elements for filters, filter creation, application, deletion.
§ ApplyBlur()
| void image_tools::FilterManager::ApplyBlur |
( |
PixelBuffer * |
p | ) |
|
Apply a blur filter to the buffer, blurring sharply defined edges.
- Parameters
-
| buffer | The buffer. Updated to point to a new filtered buffer. |
§ ApplyChannel()
| void image_tools::FilterManager::ApplyChannel |
( |
PixelBuffer * |
p | ) |
|
Apply a channel filter to the buffer.
- Parameters
-
| buffer | The buffer. Updated to point to a new filtered buffer. |
§ ApplyEdgeDetect()
| void image_tools::FilterManager::ApplyEdgeDetect |
( |
PixelBuffer * |
p | ) |
|
Apply an edge detection filter to the buffer.
- Parameters
-
| buffer | The buffer. Updated to point to a new filtered buffer. |
§ ApplyMotionBlur()
| void image_tools::FilterManager::ApplyMotionBlur |
( |
PixelBuffer * |
p | ) |
|
Apply a motion blurring filter to the buffer.
- Parameters
-
| buffer | The buffer. Updated to point to a new filtered buffer. |
§ ApplyQuantize()
| void image_tools::FilterManager::ApplyQuantize |
( |
PixelBuffer * |
p | ) |
|
Apply a quantization filter to the buffer.
- Parameters
-
| buffer | The buffer. Updated to point to a new filtered buffer. |
§ ApplySaturate()
| void image_tools::FilterManager::ApplySaturate |
( |
PixelBuffer * |
p | ) |
|
Apply a channel filter to the buffer.
- Parameters
-
| buffer | The buffer. Updated to point to a new filtered buffer. |
§ ApplySharpen()
| void image_tools::FilterManager::ApplySharpen |
( |
PixelBuffer * |
p | ) |
|
Apply a sharpening filter to the buffer, sharpening blurry/undefined edges.
- Parameters
-
| buffer | The buffer. Updated to point to a new filtered buffer. |
§ ApplySpecial()
| void image_tools::FilterManager::ApplySpecial |
( |
PixelBuffer * |
p | ) |
|
Apply a special filter to the buffer.
- Parameters
-
| buffer | The buffer. Updated to point to a new filtered buffer. |
§ ApplyThreshold()
| void image_tools::FilterManager::ApplyThreshold |
( |
PixelBuffer * |
p | ) |
|
Apply a threshold detection filter to the buffer.
- Parameters
-
| buffer | The buffer. Updated to point to a new filtered buffer. |
§ InitGlui()
| void image_tools::FilterManager::InitGlui |
( |
const GLUI *const |
glui, |
|
|
void(*)(int) |
s_gluicallback |
|
) |
| |
Initialize the elements of the GLUI interface required by the FilterManager.
- Parameters
-
| glui | GLUI handle |
| s_gluicallback | Callback to install |
The documentation for this class was generated from the following files:
- /Users/schwab/Desktop/3081/project/src/lib/libimgtools/src/include/filter_manager.h
- /Users/schwab/Desktop/3081/project/src/lib/libimgtools/src/filter_manager.cc


What a management user is permitted to do is determined by the roles to which the user is assigned. A system of includes and excludes based on the user membership determines to which role a user belongs.
Se considera que un usuario está asignado a un rol si:
Las exclusiones tienen prioridad sobre las inclusiones.


difference between Javascript and CSS
CSS is a styling language used to style the HTML pages so that they can be used to attract the users. JavaScript is a programming language that changes the appearance of web pages and it is dynamic. CSS is static and is related to colour, position, size and style of the web pages and the appearance is made beautiful. Read more ..
Learn New different technologies
Technology is constantly updating at such a rapid pace that it seems it is might be faster than light! A technology or a programming language that is making the rounds this week may be obsolete by the next few days! As more and more funds are invested in research and development, computer scientists and professionals are constantly tweaking and improving existing technologies to get the most out of them. Read more ..
some concepts related to cloud computing
Cloud computing technology gives users access to storage, files, software, and servers through their internet-connected devices: computers, smartphones, tablets, and wearables. Cloud computing providers store and process data in a location that's separate from end users. Read more ..
Some concept of python anonymous functions
A lambda function is a small anonymous function.A lambda function can take any number of arguments, but can only have one expression.
lambda arguments : expression Read more ..


A recent paper by Lessard et. al. show how to reduce the convergence analysis of optimization methods such as gradient descent to verifying the feasibility of a (very carefully constructed) linear matrix inequality (LMI). This is a really neat idea: the idea is to try and unify, and possibly even automate, the black art of proving convergence of algorithms. For those unfamiliar with LMIs, the LMI feasibility problem is defined as, given $m+1$ symmetric matrices $F_0, F_1, ..., F_m$, can we find a vector $x$ such that $$ \begin{align*} F_0 + \sum_{i=1}^{m} F_i x_i \succeq 0 \end{align*} $$ holds, where $A \succeq 0$ means $A$ is positive semi-definite. It turns out there exist fast algorithms to solve LMI feasibility in general (it is an affine problem in $x$), hence why this might be a practical way to certify algorithms.
To illustrate the technique in Lessard, let us focus on proving the convergence rate of gradient descent on strongly convex functions $f : \mathbb{R}^{d} \rightarrow \mathbb{R}$ with $L$-Lipschitz gradients. That is, functions which satisfy both inequalities for all $x,y \in \mathbb{R}^{d}$: $$ \newcommand{\norm}[1]{\left\lVert #1 \right\rVert} \begin{align*} f(y) \geq f(x) + \nabla f(x)^T (y-x) + \frac{m}{2}\norm{y - x}^2 \end{align*} $$ and also $$ \begin{align*} \norm{ \nabla f(x) - \nabla f(y) } \leq L \norm{ x - y} \end{align*} $$ We will first give the so-called "manual" proof using standard analysis techniques. We'll then show how to use the framework provided by Lessard.
The standard analysis proof
Recall that the fixed-step gradient descent algorithm picks an initial starting point $x_0$ and step size $\alpha > 0$ and iteratively applies the following update: $$ \begin{align*} x_k = x_{k-1} - \alpha \nabla f(x_{k-1}) \end{align*} $$ We now show that if $f$ satisfies the conditions specified above and we set $\alpha = \frac{2}{m+L}$, then the following inequality holds for all $k$: $$ \begin{align*} \norm{ x_k - x_* } \leq \left(\frac{ \kappa - 1 }{ \kappa + 1 }\right)^{k} \norm{ x_0 - x_* } \end{align*} $$ where $x_*$ is the (unique) global minimum of $f$, which we know exists because $f$ is strongly convex, and $\kappa = \frac{L}{m}$ is the condition number.
Before we proceed, we first assert without proof a lower bound on $(\nabla f(x) - \nabla f(y))^{T} (x - y)$. It turns out that an equivalent characterization of $m$-strongly convex functions is that this scalar product is lower bounded by: $$ \begin{align*} (\nabla f(x) - \nabla f(y))^{T} (x - y) \geq m \norm{x-y}^2 \end{align*} $$ This, unfortunately, is not strong enough of a lower bound, and therefore we rely on a stronger lower bound stated below, which requires both strong convexity and Lipschitz gradients: $$ \begin{align*} (\nabla f(x) - \nabla f(y))^{T} (x - y) \geq \frac{Lm}{L + m} \norm{x-y}^2 + \frac{1}{L + m} \norm{ \nabla f(x) - \nabla f(y) }^2 \;\quad (\ast) \end{align*} $$
We are now ready to proceed. The crux of the proof is to show that the map $\phi$ defined as $\phi(x) = x - \alpha \nabla f(x)$ is a contractive map (Lipschitz continuous with Lipschitz constant $< 1$). We establish this result below: $$ \begin{align*} \norm{x_k - x_*}^2 &= \norm{ x_{k-1} - \alpha \nabla f(x_{k-1}) - x_* }^2 \\ &= \norm{ x_{k-1} - x_* }^2 - 2\alpha (x_{k-1} - x_*)^T \nabla f(x_k) + \alpha^2 \norm{\nabla f(x_{k-1})}^2 \\ &\leq \norm{ x_{k-1} - x_* }^2 - 2\alpha \left( \frac{Lm}{L + m} \norm{x_{k-1}-x_*}^2 + \frac{1}{L + m} \norm{ \nabla f(x_{k-1}) }^2 \right) + \alpha^2 \norm{\nabla f(x_{k-1})}^2 \\ &= \left( 1 - \frac{2\alpha Lm}{L+m} \right) \norm{ x_{k-1}-x_* }^2 + \left( \alpha^2 - \frac{2\alpha}{L + m} \right)\norm{ \nabla f(x_{k-1}) }^2 \\ &\leq \left( 1 - \frac{2\alpha Lm}{L+m} \right) \norm{ x_{k-1}-x_* }^2 + \left( \alpha^2 - \frac{2\alpha}{L + m} \right)L^2 \norm{ x_{k-1}-x_* }^2 \\ &= \left( \frac{\kappa - 1}{\kappa + 1} \right)^2 \norm{ x_{k-1}-x_* }^2 \end{align*} $$ where in the last step we skipped over some algebra. The result now follows by unrolling the inequality $k$ times (which is the beauty of contractive maps).
The LMI feasibility proof
The very high level idea of the Lessard paper is that you can express optimization algorithms as discrete time linear dynamical systems (LDS), and then leverage very powerful techniques from control theory to verify the stability (e.g. convergence) of your system. Let's see this in more detail. Suppose we control the internals of a linear system where the dynamics of the system are whatever output $y_k$ we provide, the system will provide us as input $u_k$ the gradient of some unknown $f$ evaluated at the point $y_k$. We're free to choose whatever state representation $x_k$ we want, as well as how our system evolves linearly. That is, we get to pick matrices $A, B, C$ such that our linear system behaves as follows: $$ \begin{align*} x_{k+1} &= A x_{k} + B u_{k} \\ y_{k} &= C x_{k} \end{align*} $$ To get gradient descent, it is not hard to see that we simply let our state space $x \in \mathbb{R}^{d}$ and pick $A = I_{d}$, $B=-\alpha I_{d}$, and $C=I_{d}$. Now that we have described gradient descent as a LDS, one of the key points of Lessard is how we can also encode our knowledge on the behavior of $f$ into the LDS. That is, in the derivation above, we used some key facts about strongly convex, Lipschitz functions which were necessary to derive convergence results. Lessard shows us that by encoding $(\ast)$ into the LDS, we can reduce the proof to a LMI feasibility problem!
We will make a short digression and explain the core idea (Theorem 4), which is actually not much more than a clever algebraic trick. Leaving gradient descent aside for now, suppose we have any arbitrary LDS given as $$ \begin{align*} x_{k+1} &= A x_k + B u_k \\ z_{k} &= C x_k + D u_k \end{align*} $$ Now suppose somebody tells us two facts about this system.
- For all $k$ we have $(z_k - z_*)^T M (z_k - z_*) \geq 0$ for some matrix $M$ and any point $z_*$. These are referred to as integral quadratic constraints (IQCs).
- There exists a positive definite $P$, $\lambda \geq 0$, and $0 \leq \rho \leq 1$ such that the following LMI is feasible: $$ \begin{align*} \left[ \begin{array}{cc} A^T P A - \rho^2 I & A^T P B \\ B^T P A & B^T P B \end{array} \right] + \lambda \left[ \begin{array}{cc} C & D \end{array} \right]^{T} M \left[ \begin{array}{cc} C & D \end{array} \right] \preceq 0 \; \quad (\ast\ast) \end{align*} $$
Now all we need to do for gradient descent is to find a suitable LDS and plug it into the result from above. This is arguably where these techniques are no simpler than direct proof, since one has to be clever in her choice of LDS. The paper actually sets up a framework on how to do this, but I find it to be quite distracting symbolically from the main idea, so I will not discuss it. Instead, we will explicitly write out the LDS for gradient descent. Consider: $$ \begin{align*} x_{k+1} &= I_{d}x_{k} - \alpha I_{d} u_{k} \\ z_{k} &= \left[ \begin{array}{c} L I_{d} \\ -m I_{d} \end{array} \right] x_{k} + \left[ \begin{array}{c} -I_{d} \\ I_{d} \end{array} \right] u_{k} \end{align*} $$ The $x_{k+1}$ definition seems clear, but this $z_{k}$ definition looks a bit strange. However, it in fact is something we have already seen! It is a good exercise to show how $z_{k}$, coupled with the following IQC $$ \begin{align*} (z_{k} - z_*)^{T} \left[ \begin{array}{cc} 0_{d} & I_{d} \\ I_{d} & 0_{d} \end{array} \right] (z_{k} - z_*) \geq 0 \end{align*} $$ encodes the inequality $(\ast)$ from above. Now let us see what the LMI which certifies gradient descent is, by plugging in our LDS into $(\ast\ast)$. It turns out it looks like: $$ \begin{align*} \left[ \begin{array}{cc} P - \rho^2 I_{d} & -\alpha P \\ -\alpha P & \alpha^2 P \end{array} \right] + \lambda \left[ \begin{array}{cc} -2mL I_{d} & (L+m)I_{d} \\ (L+m)I_{d} & -2 I_{d} \end{array} \right] \preceq 0 \end{align*} $$ To re-iterate: if you can find a positive definite $P$, $\lambda > 0$, and $0 \leq \rho \leq 1$ such that the above problem is feasible, then you have just proven gradient descent to converge with the rate $\norm{x_k - x_*}^2 \leq \kappa(P) \rho^{2k} \norm{x_0 - x_*}^2$. It is another exercise to check that $P=I_{d}$, $\rho = \frac{\kappa - 1}{\kappa + 1}$, and $\alpha = \frac{2}{L+m}$ (e.g. the known rates which we proved above) makes the problem feasible.
This post simply scratches the surface, with the simplest, most understandable method. The paper goes into more detail about how to derive feasible LMIs for more complicated optimization methods such as the heavy-ball method and Nesterov's method. These more advanced methods are trickier, since $x_{k+1}$ is computed based off of not just $x_{k}$, but also $x_{k-1}$.


Open the Developer Tool to watch what will happen.
It will go to the homepage, if you hit g and h at the same.
hit Ctrl + b or Space to bold this sentence or not.
hit g + a that will alert.
Or you try to hit Ctrl + Space


Breaking: Spurs Appoint Mourinho
by David KappelAfter Mauricio Pochettino was somewhat surprisingly sacked on Tuesday, Jose Mourinho has been officially announced as his replacement on Wednesday morning.
Click through the mini-gallery above to see images of Mourinho at his previous clubs.
Pochettino was relieved of his duties in news that shocked the football world after a string of poor results has seen Spurs drop to 14th place in the Premier League.
The Argentine had been in charge of the Lillywhites since May 2014 and guided them to the UEFA Champions League final last season.
Download The Soccer Laduma Social Media App & Earn Airtime for Selfies!
Spurs confirmed that Mourinho will take over after talks between chairman Daniel Levy and Mourinho’s camp went well over night.
"In Jose we have one of the most successful managers in football," Levy told the club's official website.
"He has a wealth of experience, can inspire teams and is a great tactician. He has won honours at every club he has coached. We believe he will bring energy and belief to the dressing room.”
Mourinho had been out of work since being fired by Manchester United in December 2018, but Spurs are now his third English side following stints with Chelsea and the Red Devils.
He signed a contract until the end of the 2022/23 season and will sit on the bench for Spurs’ clash with West Ham United on Saturday.
Read: World's Richest Club Revealed, Real Dethroned
Pochettino left Spurs after being in charge for 293 games, winning 160 but failing to add silverware to the club’s trophy cabinet.