text:
Q: How to store random integers from the set of 32-bit integers in a compact data structure to rapidly check membership? I am thinking about how to organize/allocate memory and that led me to this question, which I have distilled to its essence, so it may seem out of the blue, but the memory question is too complicated and confusing and distracting, so I am not asking it here. I tried asking it earlier and got no response. So here it goes.
Say you have a system where you want to check if you have some integer exists in it as fast as possible, and you want to be able to add and remove integers as fast as possible too. That is, it's a key-store essentially, not even a key-value-store. It only stores integer keys, and I guess theoretically the value would conceptually be a true boolean, but I don't think it needs to be there necessarily.
One solution is to use sparse arrays. For example, this array would return true in O(1) time for 3, 5, and 9.
[-, -, 3, -, 5, -, -, -, 9, -, -, ...]

You just specify the integer - 1 and get back if it exists at that position in the array. But the problem with this is twofold. First, it takes up a lot of wasted memory with all these null values. And secondly, for my project, I have the added constraint that arrays can only exist at sizes 1, 2, 4, 8, 16, and 32 items in length. So I am stuck using short arrays. Which means I'm left with trees of some sort most likely.
So these are the constraints:

*

*Positive 32-bit integers.

*Compact data structure (minimal wasted space).

*Fast lookup times.

*Fast deletion/insertion times.

*Array sizes in the data structure can only be sized at 1, 2, 4, 8, 16, or 32 items.

One approach I am thinking that might work that fits these constraints is a sort of tree, like a B+tree. But I am not super familiar with these yet, still playing with them. I think it would be like a key-only B+tree (no values, and hence no leaves). But not entirely sure what this would look like (in JavaScript, if I had to pick a language).
Another approach I thought of is a binary trie. But this would take up to 32 steps per integer to add and check membership, which seems like we could potentially optimize somehow.
What is the main approach to storing sequential 32-bit integers in some data structure for rapidly checking membership, doing insertions, and doing removals? Perhaps this can learn from IP lookup tables or things of that nature.
I am using this for a custom programming language, though seeing an implementation in JavaScript would be helpful. If it's just the name of the data structure you're providing, please explain how it works or implement it in JavaScript without resorting to JavaScript built-ins which may already solve the problem.

A: Here is my suggested approach.
Every node should be a 32 entry array.  If the first entry is null or an array, it is a 32-way split of the whole search space.  Otherwise it is descending list of the entries in this block.  Fill in the non-entries with -1.
This means that in no more than 5 lookups we get to the block that either has or doesn't have our value.  We then do a linear scan.  A binary search of a sorted list naively seems like it would be more efficient, but in fact it involves a series of hard to predict branches which CPUs hate.  In a low level language (which I hope yours is), it is faster to avoid the pipeline stall and do a linear search.
Here is an implementation in JavaScript.
class IntegerSet {
    constructor() {
        this.make_node = function () {
            let node = new Array();
            for (let i = 0; i < 32; i++) {
                node[i] = -1;
            }
            return node;
        };
        this.root = this.make_node();

        this.lookup = function (target) {
            let node = this.root;
            let size = 2**32;
            while (Array.isArray(node[0])) {
                size /= 32;
                let idx = Math.floor(target / size);
                node = node[idx];
                target = target % size;
            }

            for (let i = 0; i < 32; i++) {
                if (target == node[i]) {
                    return true;
                }
                // On average this lets us break out 1/4 of the way through.
                else if (node[i] < target) {
                    return false;
                }
            }
            return false;
        };

        this.insert = function (target, node) {
            node = node || this.root;
            let size = 2**32;
            while (Array.isArray(node[0])) {
                size /= 32;
                let idx = Math.floor(target / size);
                node = node[idx];
                target = target % size;
            }

            for (let i = 0; i < 32; i++) {
                if (target == node[i]) {
                    return false;
                }
                else if (node[i] < target) {
                    // copy elements along, in order.
                    let value = node[i];
                    for (let j = i; j < 31; j++) {
                        node[j] = target;
                        target = value;
                        value = node[j+1];
                        if (target == -1) {
                            break;
                        }
                    }
                    node[31] = target; // just in case the block is full
                    if (-1 == target) {
                        return true;
                    }
                    else {
                        break; // we inserted and filled the node.
                    }
                }
            }

            // If we get here, we need to split the node.
            let node_copy = this.make_node();
            for (let i = 0; i < 32; i++) {
                node_copy[i] = node[i];
                node[i] = this.make_node();
            }
            size /= 32;
            let idx = Math.floor(target / size);
            node[idx][0] = target % size;
            for (let i = 0; i < 32; i++) {
                let value = node_copy[i];
                idx = Math.floor(value / size);
                this.insert(value % size, node[idx]);
            }
        };

        this.remove = function (target) {
            let node = this.root;
            let size = 2**32;

            while (Array.isArray(node[0])) {
                size /= 32;
                let idx = Math.floor(target / size);
                node = node[idx];
                target = target % size;
            }

            for (let i = 0; i < 32; i++) {
                if (target == node[i]) {
                    for (let j = i; j < 31; j++) {
                        node[j] = node[j+1];
                        if (node[j] == -1) {
                            break;
                        }
                    }
                    node[31] = -1;
                    return true;
                }
            }
            return false;
        };
    }
}

let foo = new IntegerSet();
for (let i = 0; i < 300; i++) {
    foo.insert(Math.floor(Math.random() * 2**32));
}
console.log(foo.root);
console.log(foo.lookup(5));
console.log(foo.remove(5));
console.log(foo.insert(5));
console.log(foo.root);
console.log(foo.lookup(5));
console.log(foo.remove(5));

Here are the characteristics of this data structure.
A read requires no more than 5 lookups to get to a block, then a scan with at most 64 if statements (which are well-predicted to always be false).  If you insert a lot of random elements, the leaves are on average half-full, and on average we only do 1/4 of the scan.
The fact that there are 32 children of each internal node mean that the internal nodes only add a few percent overhead to the structure.
If you insert and then delete, performance remains good but we never will reclaim memory.

The following is an implementation that is similar to the previous but uses arrays of different size, and allows you to reclaim space.  It aims to make 60-70% of the space actually data.  But this comes, obviously, with penalties on insert/remove.
class IntegerSet {
    constructor() {
        this.make_node = function (size) {
            let node = new Array();
            for (let i = 0; i < size; i++) {
                node[i] = -1;
            }
            node.child_size = 0;
            return node;
        };
        this.root = this.make_node(2);

        this.lookup = function (target) {
            let node = this.root;
            let size = 2**32;
            while (Array.isArray(node[0])) {
                size /= 32;
                let idx = Math.floor(target / size);
                node = node[idx];
                target = target % size;
            }

            let i = 0;
            while (target < node[i]) {
                i++;
            }

            return target == node[i];
        };

        this.insert = function (target, node, parent_node, size) {
            node = node || this.root;
            if (size == null) {
                size = 2**32;
            }
            let idx = null;
            let update_parent = false;
            while (Array.isArray(node[0])) {
                size /= 32;
                parent_node = node;
                update_parent = true;
                idx = Math.floor(target / size);
                node = node[idx];
                target = target % size;
            }

            let i = 0;
            while (target < node[i]) {
                i++;
            }

            if (target == node[i]) {
                return true; // already had it.
            }
            else {
                // copy along, in order.
                let value = node[i];
                while (-1 < target) {
                    value = node[i]
                    node[i] = target;
                    i++;
                    target = value;
                }
                if (update_parent) {
                    parent_node.child_size++;
                }

                if (i == node.length) {
                    let new_node = null;
                    if (node.length < 32) {
                        // Double node size.
                        new_node = this.make_node(node.length * 2);
                        for (let j = 0; j < i; j++) {
                            new_node[j] = node[j];
                        }
                    }
                    else {
                        // Need to split.
                        new_node = this.make_node(node.length);
                        for (let j = 0; j < node.length; j++) {
                            new_node[j] = this.make_node(2);
                        }
                        new_node.child_size = node.length;
                        size /= 32;
                        for (let j = 0; j < 32; j++) {
                            target = node[j];
                            let new_idx = Math.floor(target / size);
                            target = target % size;
                            this.insert(target, new_node[new_idx], parent_node, size);
                        }
                    }
                    if (parent_node != null) {
                        parent_node[idx] = new_node;
                    }
                    else {
                        this.root = new_node;
                    }
                }
            }
        };

        this.remove = function (target) {
            let node = this.root;
            let grandparent_node = null;
            let parent_node = null;
            let size = 2**32;
            let idx = null;
            let parent_idx = null;

            while (Array.isArray(node[0])) {
                size /= 32;
                parent_idx = idx;
                idx = Math.floor(target / size);
                grandparent_node = parent_node;
                parent_node = node;
                node = node[idx];
                target = target % size;
            }

            let i = 0;
            while (target < node[i]) {
                i++;
            }

            if (node[i] == target) {
                // now delete along.
                while (-1 < node[i]) {
                    node[i] = node[i+1];
                    i++;
                }

                if (parent_node != null) {
                    parent_node.child_size--;
                    // Reconsolidate if we save about 1/4 of memory.
                    if (parent_node.child_size < 24) {
                        let new_node = this.make_node(32);
                        let new_id = 0;
                        for (let i = 31; -1 < i; i--) {
                            let old_node = parent_node[i];
                            let j = 0;
                            while (-1 < old_node[j]) {
                                new_node[new_id] = size * i + old_node[j];
                                new_id++;
                                j++;
                            }
                        }
                        if (grandparent_node == null) {
                            this.root = new_node;
                        }
                        else {
                            grandparent_node[parent_idx] = new_node;
                            grandparent_node.child_size += parent_node.child_size - 33;
                        }
                        return true;
                    }
                }

                // Reconsolidate if we save about 2/3 of memory.
                if (i < node.length / 3 && 2 < node.length) {
                    let new_node = this.make_node(node.length/2);
                    for (let j = 0; j < i; j++) {
                        new_node[j] = node[j];
                    }
                    if (parent_node != null) {
                        parent_node[idx] = new_node;
                    }
                    else {
                        this.root = new_node;
                    }
                }

                return true;
            }
            else {
                return false;
            }
        };
    }
}

let foo = new IntegerSet();
let keep = new Array;
for (let i = 0; i < 5; i++) {
    keep.push(Math.floor(Math.random() * 2**32));
}
let remove = new Array;
for (let i = 0; i < 300; i++) {
    remove.push(Math.floor(Math.random() * 2**32));
}
for (let i = 0; i < keep.length; i++) {
    foo.insert(keep[i]);
}
for (let i = 0; i < remove.length; i++) {
    foo.insert(remove[i]);
}
for (let i = 0; i < remove.length; i++) {
    foo.remove(remove[i]);
}
console.log(foo.root);
for (let i = 0; i < keep.length; i++) {
    console.log(keep[i]);
    console.log(foo.lookup(keep[i]));
    console.log(foo.remove(keep[i]));
    console.log(foo.lookup(keep[i]));
    console.log(foo.remove(keep[i]));
}

A: You wrote:

One approach I am thinking that might work that fits these constraints is a sort of tree, like a B+tree. [...] I think it would be like a key-only B+tree (no values, and hence no leaves). But not entirely sure what this would look like (in JavaScript, if I had to pick a language).

Indeed, a key-only B(+)-tree would be a possible solution. It solves the problem of the wasted space you get from a sparse array solution. It is also a solution that works well when the data type happens to be string or float instead of number, which would be a problem for the sparse array solution.
The code I post below is similar to another B+ tree related answer I posted earlier on another question of yours, but which was not a search tree.
The idea is to use a B+ tree, taking into account the extra requirement about array sizes that are powers of 2. The actual data keys are found in the bottom level of the tree. The internal nodes repeat the smallest key that its subtree contains. This can be used for deciding which child to choose when walking from the root down the tree, in search for a bottom-level location where a key should be found or should be inserted.
The tree is kept compact by distributing children/keys to neighbors when a node gets full, only splitting a node when there is no room in the neighbors either. When a key is deleted, the affected node will merge with a neighbor when possible. Each node (except the root) is guaranteed to have at least half the use of the maximum (32) node capacity -- either for storing children or keys (at the bottom level).
Keys are located starting the search at the root. A child is selected using binary search so that the key of that child is the greatest key that is less or equal to the key were are locating. If the key is not found at the bottom level, we have at least the location where it should be, and it could be inserted there.
Implementation

class Node {
    constructor(capacity) {
        // Mimic fixed-size array (avoid accidentally growing it)
        this.children = Object.seal(Array(capacity).fill(null));
        this.childCount = 0; // Number of used slots in children array
        this.key = null; // Property for supporting a search
        // Maintain back-link to parent.
        this.parent = null;
        // Per level in the tree, maintain a doubly linked list
        this.prev = this.next = null;
    }
    setCapacity(capacity) {
        if (capacity < 1) return;
        // Here we make a new array, and copy the data into it
        let children = Object.seal(Array(capacity).fill(null));
        for (let i = 0; i < this.childCount; i++) children[i] = this.children[i];
        this.children = children;
    }
    isLeaf() {
        return !(this.children[0] instanceof Node);
    }
    index() {
        return this.parent.children.indexOf(this);
    }
    updateKey() {
        this.key = this.isLeaf() ? this.children[0] : this.children[0].key;
        for (let node = this.parent; node; node = node.parent) {
            node.key = node.children[0].key;
        }
    }
    wipe(start, end) {
        this.children.copyWithin(start, end, this.childCount);
        for (let i = this.childCount - end + start; i < this.childCount; i++) {
            this.children[i] = null;
        }
        this.childCount -= end - start;
        // Reduce allocated size if possible
        if (this.childCount * 2 <= this.children.length) this.setCapacity(this.children.length / 2);
        // Update key if first item changed
        if (start === 0) this.updateKey();
    }
    moveFrom(neighbor, target, start, count=1) {
        // Note: `start` can have two meanings:
        //   if neighbor is null, it is the key/Node to move to the target
        //   if neighbor is a Node, it is the index from where keys(s)/Node(s) have to be moved to the target
        // Make room in target node
        if (this.childCount + count > this.children.length) this.setCapacity(this.children.length * 2);
        this.children.copyWithin(target + count, target, Math.max(target + count, this.childCount));
        this.childCount += count;
        if (neighbor !== null) {
            // Copy the children
            for (let i = 0; i < count; i++) {
                this.children[target + i] = neighbor.children[start + i];
            }
            // Remove the original references
            neighbor.wipe(start, start + count);
        } else {
            this.children[target] = start; // start is key to insert
        }
        // Set parent link(s)
        if (!this.isLeaf()) {
            for (let i = 0; i < count; i++) {
                this.children[target + i].parent = this;
            }
        }
        // Update key if first item changed
        if (target === 0) this.updateKey();
    }
    moveToNext(count) {
        this.next.moveFrom(this, 0, this.childCount - count, count);
    }
    moveFromNext(count) {
        this.moveFrom(this.next, this.childCount, 0, count);
    }
    basicRemove(index) {
        if (!this.isLeaf()) {
            // Take node out of the level's linked list
            let prev = this.children[index].prev;
            let next = this.children[index].next;
            if (prev) prev.next = next;
            if (next) next.prev = prev;
        }
        this.wipe(index, index + 1);
    }
    basicInsert(index, value) { // value can be a key or a Node
        this.moveFrom(null, index, value);
        if (value instanceof Node) {
            // Insert node in the level's linked list
            if (index > 0) {
                value.prev = this.children[index-1];
                value.next = value.prev.next;
            } else if (this.childCount > 1) {
                value.next = this.children[1];
                value.prev = value.next.prev;
            }
            if (value.prev) value.prev.next = value;
            if (value.next) value.next.prev = value;
        }
    }
    pairWithSmallest() {
        return this.prev && (!this.next || this.next.childCount > this.prev.childCount)
            ? [this.prev, this] : [this, this.next];
    }
    toString() {
        return "[" + this.children.map(v => v??"-").join() + "]";
    }
}

class Tree {
    constructor(nodeCapacity=32) {
        this.nodeCapacity = nodeCapacity;
        this.root = new Node(1);
        this.first = this.root; // Head of doubly linked list at bottom level
    }
    locate(key) {
        let node = this.root;
        while (!node.isLeaf()) {
            // Binary search among keys
            let low = 0;
            let high = node.childCount;
            while (low < high) {
                let index = (low + high) >> 1;
                if (key >= node.children[index].key) {
                    low = index + 1;
                } else {
                    high = index;
                }
            }
            if (low) low--;
            node = node.children[low];
        }
        // Binary search in leaf
        let low = 0;
        let high = node.childCount;
        while (low < high) {
            let index = (low + high) >> 1;
            if (key > node.children[index]) {
                low = index + 1;
            } else {
                high = index;
            }
        }
        return [node, low];
    }
    has(key) {
        let [node, index] = this.locate(key);
        return index < node.childCount && node.children[index] === key;
    }
    remove(key) {
        let [node, index] = this.locate(key);
        if (index >= node.childCount || node.children[index] !== key) return; // not found
        while (true) {
            node.basicRemove(index);

            // Exit when node's fill ratio is fine
            if (!node.parent || node.childCount * 2 > this.nodeCapacity) return;
            // Node has potentially too few children, we should either merge or redistribute

            let [left, right] = node.pairWithSmallest();

            if (!left || !right) { // A node with no siblings? Must become the root!
                this.root = node;
                node.parent = null;
                return;
            }
            let sumCount = left.childCount + right.childCount;
            let childCount = sumCount >> 1;

            // Check whether to merge or to redistribute
            if (sumCount > this.nodeCapacity) { // redistribute
                // Move some data from the bigger to the smaller node
                let shift = childCount - node.childCount;
                if (!shift) { // Boundary case: when a redistribution would bring no improvement
                    console.assert(node.childCount * 2 === this.nodeCapacity && sumCount === this.nodeCapacity + 1);
                    return;
                }
                if (node === left) { // move some children from right to left
                    left.moveFromNext(shift);
                } else { // move some children from left to right
                    left.moveToNext(shift);
                }
                return;
            }

            // Merge:
            // Move all data from the right to the left
            left.moveFromNext(right.childCount);
            // Prepare to delete right node
            node = right.parent;
            index = right.index();
        }
    }
    insert(value) {  // value is a key
        let [node, index] = this.locate(value);
        if (index < node.childCount && node[index] === value) return; // already present
        while (node.childCount === this.nodeCapacity) { // No room here
            if (index === 0 && node.prev && node.prev.childCount < this.nodeCapacity) {
                return node.prev.basicInsert(node.prev.childCount, value);
            }
            // Check whether we can redistribute (to avoid a split)
            if (node !== this.root) {
                let [left, right] = node.pairWithSmallest();
                let joinedIndex = left === node ? index : left.childCount + index;
                let sumCount = left.childCount + right.childCount + 1;
                if (sumCount <= 2 * this.nodeCapacity) { // redistribute
                    let childCount = sumCount >> 1;
                    if (node === right) { // redistribute to the left
                        let insertInLeft = joinedIndex < childCount;
                        left.moveFromNext(childCount - left.childCount - +insertInLeft);
                    } else { // redistribute to the right
                        let insertInRight = index >= sumCount - childCount;
                        left.moveToNext(childCount - right.childCount - +insertInRight);
                    }
                    if (joinedIndex > left.childCount ||
                            joinedIndex === left.childCount && left.childCount > right.childCount) {
                        right.basicInsert(joinedIndex - left.childCount, value);
                    } else {
                        left.basicInsert(joinedIndex, value);
                    }
                    return;
                }
            }
            // Cannot redistribute: split node
            let childCount = node.childCount >> 1;
            // Create a new node that will later become the right sibling of this node
            let sibling = new Node(childCount);
            // Move half of node node's data to it
            sibling.moveFrom(node, 0, childCount, childCount);
            // Insert the value in either the current node or the new one
            if (index > node.childCount) {
                sibling.basicInsert(index - node.childCount, value);
            } else {
                node.basicInsert(index, value);
            }
            // Is this the root?
            if (!node.parent) {
                // ...then first create a parent, which is the new root
                this.root = new Node(2);
                this.root.basicInsert(0, node);
            }
            // Prepare for inserting the sibling node into the tree
            index = node.index() + 1;
            node = node.parent;
            value = sibling; // value is now a Node
        }
        node.basicInsert(index, value);
    }
    /* Below this point: these methods are optional */
    * [Symbol.iterator]() { // Make tree iterable
        let i = 0;
        for (let node = this.first; node; node = node.next) {
            for (let i = 0; i < node.childCount; i++) yield node.children[i];
        }
    }
    print() {
        console.log(this.root && this.root.toString());
    }
    verify() {
        // Raise an error when the tree violates one of the required properties
        if (!this.root) return; // An empty tree is fine.
        if (this.root.parent) throw "root should not have a parent";
        // Perform a breadth first traversal
        let q = [this.root];
        while (q.length) {
            if (q[0].isLeaf() && this.first !== q[0]) throw "this.first is not pointing to first leaf";
            let level = [];
            let last = null;
            for (let parent of q) {
                if (!(parent instanceof Node)) throw "parent is not instance of Node";
                if (parent.children.length > this.nodeCapacity) throw "node's children array is too large";
                if (parent.childCount > 0 && parent.childCount * 2 <= parent.children.length) throw "node's fill ratio is too low";
                for (let i = parent.childCount; i < parent.children.length; i++) {
                    if (parent.children[i] !== null) throw "child beyond childCount should be null but is not";
                }
                if (parent.isLeaf()) {
                    if (parent.children[0] !== parent.key) throw "key does not match with first child value";
                    for (let value of parent.children.slice(0, parent.childCount)) {
                        if (value === null) throw "leaf has a null as value";
                        if (value instanceof Node) throw "leaf has a Node as value";
                    }
                } else {
                    if (parent.children[0].key !== parent.key) throw "key does not match with first child's key";
                    for (let node of parent.children.slice(0, parent.childCount)) {
                        if (node === null) throw "internal node has a null as value";
                        if (!(node instanceof Node)) throw "internal node has a non-Node as value";
                        if (node.parent !== parent) throw "wrong parent";
                        if (node.prev !== last) throw "prev link incorrect";
                        if (last && last.next !== node) throw "next link incorrect";
                        if (last && last.children.length + node.children.length <= this.nodeCapacity) {
                            throw "two consecutive siblings have a total number of children that is too small";
                        }
                        if (node.childCount * 2 < this.nodeCapacity) {
                            throw "internal node is too small: " + node;
                        }
                        level.push(node);
                        last = node;
                    }
                }
            }
            if (last && last.next) throw "last node in level has a next reference";
            q = level;
        }
    }
    test(count=100, option=3) {
        // option:
        //     0 = always insert & delete at left side (offset 0)
        //     1 = always insert & delete at right side
        //     2 = always insert & delete at middle
        //     3 = insert & delete at random offsets
        // Create array to perform the same operations on it as on the tree
        let max = count*2;
        let arr = [];
        // Perform a series of insertions
        for (let i = 0; i < count; i++) {
            // Choose random value
            let key = Math.floor(Math.random() * max);
            // Perform same insertion in array and tree
            arr.push(key);
            this.insert(key);
            // Verify tree consistency and properties
            this.verify();
            // Verify the order of keys in the array is the same as in the tree
            if (arr.sort((a,b) => a-b)+"" !== [...this]+"") throw i + ": tree not same as array";
        }
        // Perform a series of has-calls
        for (let i = 0; i < count; i++) {
            // Choose random update index
            let key = Math.floor(Math.random() * max);
            // Perform same insertion in array and tree
            let has = arr.includes(key);
            if (has !== this.has(key)) {
                throw "has() returns inconsistent result";
            }
            if (!has) {
                this.remove(key); // should not alter the tree
                // Verify the order of keys in the array is the same as in the tree
                if (arr+"" !== [...this]+"") throw i + ": tree not same as array";
            }
        }
        // Perform a series of deletions
        for (let i = arr.length - 1; i >= 0; i--) {
            // Choose random deletion key
            let key = arr[Math.floor(Math.random() * i)];
            // Perform same deletion in array and tree
            arr.splice(arr.indexOf(key), 1);
            this.remove(key);
            // Verify tree consistency and properties
            this.verify();
            // Verify the order of keys in the array is the same as in the tree
            if (arr+"" !== [...this]+"") throw "tree not same as array";
        }
    }
}

// Perform 1000 insertions, 1000 updates, and 1000 deletions on a tree with node capacity of 8
new Tree(8).test(1000);
console.log("all tests completed");

Supported data types
The data type of the keys can be anything for which comparison operators work. So for strings or numbers it will work. In JavaScript it will also work for objects that have implemented either a valueOf or toString method. For instance, this is already the case for native Date objects. JavaScript will first try the valueOf method and in absence the toString method, which is also defined on the Object prototype.
Considerations
I stored one key in each node, as this is an in-memory solution. Historically, B(+)-trees are used for disk storage, where it is important to keep the number of block reads low. A standard B(+)-tree implementation stores the keys one level higher, in the parent, as an array. That way the search does not have to load each child record, while searching for the right one to choose.
Also, it then does not need to store the key of its first child, as we really only need the keys that separate two consecutive children.


text:
Q: Google One Tap descriptions We integrated Google One Tap on our site and have had some amazing results. Had a question on further integration:
When One Tap loads on the right hand side, is there a way to know its width/height? We want to display a 'Why sign up?' UI element below it, so our users know the value of a registration.

A: There are two container elements, the one used to load One Tap using HTML on a page:

A second, dynamic container renders the prompt within an iframe:

and height and width are available for the container.
You may also use data-prompt_parent_id with a container ID of your choosing (link) if that's helpful in managing position and size of elements on the page.

redpajama_set_name: RedPajamaStackExchange


text:
Q: Angularjs: change object property of specific index of nested ng-repeat I've nested ng-repeat like this:

    <md-input-container>
      <md-select ng-model="openCloseSet[0]" ng-init="openTime = openCloseSet[0]">
        <md-option ng-repeat="uiTime in time.avaiableTime" ng-value="uiTime.msValue">
        {{::uiTime.display}}
        </md-option>
      </md-select>
     </md-input-container>

    <md-input-container ng-if="$index === 0">
      <md-button ng-click="addSplitHours(time.uiDayMs ,$index +1, time)">
         Add
      </md-button>
    </md-input-container>

On clicking the Add button. It creates a new block of time.uiDayMs.
Here is the add function:
$scope.addSplitHours = addSplitHours;
function addSplitHours(index, time) {
    var newOpen = time.uiDayMs[time.uiDayMs.length - 1][1] + 900000;
    time.uiDayMs.push([newOpen, newOpen + 900000 * 4]);

    var closingtimeStarts = closingTime + 900000;
    var closingtimeEnds = avaiableClosingTimes[avaiableClosingTimes.length - 1].msValue;
    for (
        var msValue = closingtimeStarts;
        msValue <= closingtimeEnds;
        msValue += 900000
    ) {
        time.avaiableTime.push({
            msValue: msValue,
            display: moment(msValue)
                .utc()
                .format("h:mm A")
        });
    }
}

You can see I'm taking the next index number but unable to use it.
So my main question is how can I make the time.avaiableTime.push to only that specific index? Currently, It changes on each time.avaiableTime but I wanted to push on that specific index only.


text:
Q: Using python binding for flycapture to retrieve color image I am working with the CMLN-13S2C-CS CCD camera from PointGrey Systems. It uses FlyCapture API to grab images. I would like to grab these images and do some stuff in OpenCV with them using python.
I am aware of the following python binding: pyflycapture2. With this binding I am able to retrieve images. However, I cannot retrieve the images in color, which is what the camera should be able to do.
The videomode and framerate that the camera is able to handle are VIDEOMODE_1280x960Y8, and FRAMERATE_15, respectively. I think it has something to do with the pixel_format, which I think should be raw8.
Is anyone able to retrieve a color image using this or any existing python binding for flycapture? Note that I am working on Linux.

A: You don't need to use the predefined modes. The Context class has the set_format7_configuration(mode, x_offset, y_offset, width, height, pixel_format) method with which you can use your custom settings. Using this you can at least change the resolution of the grabbed image.
Usage example:
c.set_format7_configuration(fc2.MODE_0, 320, 240, 1280, 720, fc2.PIXEL_FORMAT_MONO8)

As for the coloring issue. I've so far managed to get a colored image using PIXEL_FORMAT_RGB8 and modifying the Image class in flycapture2.pyx as follows:
def __array__(self):
    cdef np.ndarray r
    cdef np.npy_intp shape[3]  # From 2 to 3
    cdef np.dtype dtype
    numberofdimensions = 2  # New variable
    if self.img.format == PIXEL_FORMAT_MONO8:
        dtype = np.dtype("uint8")
    elif self.img.format == PIXEL_FORMAT_MONO16:
        dtype = np.dtype("uint16")
    elif self.img.format == PIXEL_FORMAT_RGB8:  # New condition
        dtype = np.dtype("uint8")
        numberofdimensions = 3
        shape[2] = 3
    else:
        dtype = np.dtype("uint8")
    Py_INCREF(dtype)
    shape[0] = self.img.rows
    shape[1] = self.img.cols

    # nd value (numberofdimensions) was always 2; stride set to NULL
    r = PyArray_NewFromDescr(np.ndarray, dtype,
            numberofdimensions, shape, NULL,
            self.img.pData, np.NPY_DEFAULT, None)
    r.base = <PyObject *>self
    Py_INCREF(self)
    return r

This code is most likely not flawless (i.e I removed the stride stuff) for the simple reason that I have pretty much 0 experience with C and Cython but this way I at least managed to get a colored frame (now in the process of trying to get the PIXEL_FORMAT_RAW8 working).
And just as a reminder: the flycapture2.pyx is a Cython file so you need to recompile it before you can use it (I just run the pyflycap2 install script again).

A: I'm using the same camera with Matlab and also got an issues with "raw8" format. So, I've chose "rgb8", specifically, "F7_RGB_644x482_Mode1" and all things starts to work (not sure, how it should look at Python).
P.S. At the moment I'm trying to start work with Python and pyflycapture2, let's see, if I would be able to find workaround.
UPD: Okay, now I know the things. :)
Your (and mine) issue reasons are buried inside the pyflycapture2 itself, especially "Image" class definition. You can have a look here: https://github.com/jordens/pyflycapture2/blob/eec14acd761e89d8e63a0961174e7f5900180d54/src/flycapture2.pyx
if self.img.format == PIXEL_FORMAT_MONO8:
            dtype = np.dtype("uint8")
            stride[1] = 1
        elif self.img.format == PIXEL_FORMAT_MONO16:
            dtype = np.dtype("uint16")
            stride[1] = 2
        else:
            dtype = np.dtype("uint8")
            stride[1] = self.img.stride/self.img.cols

ANY image will be converted into grayscale, even if it was RGB initially. So, we need to update that file somehow.


text:
Q: How can we provide a custom domain name for our clients? We currently have a SaaS application that lives at app.ourcompany.com. I am trying to understand what it would take to let our clients access our application via a custom subdomain like clients.theirbrand.com.
I have done some research and there seems to be a few things in common with other companies that provide this.

*

*They have their clients create a CNAME record that points clients.theirbrand.com to something like clientaccess.ourcompany.com.

*Or the application has client subdomains (clientname.ourcompany.com) in which case they have the client create a CNAME that points clients.theirbrand.com to clientname.ourcompany.com
I tried taking one of our extra domains and pointing app.extra.com to app.ourcompany.com via CNAME but it just redirects to app.ourcompany.com.
My question revolves around what we need to do to facilitate this, specifically:

*

*What needs to be done on our clients end via DNS? (just CNAME?)

*What needs to be done our end via DNS?

*How would we incorporate SSL? (We currently use lets encrypt on app.ourcompany.com) We can secure our side but do clients have steps to take as well?

Update: We are using nginx to serve the application.

A: I know its a little late but I was stuck in a similar situation and thought it might be helpful for newbies like me :)
Have a look at: OpenResty
We have two requirements:

*

*allocate a subdomain to all new customers (e.g: trumptower.mibuilding.eu)

*allow customers to bring their own domain (my.trumptower.com)

The first one was pretty easy with Lets encrypt's wildcard subdomain ssl.
The second one was tricky. Since we needed to not only issue an SSL on the fly but also configure our gateway (haproxy at that time) and reload the configuration terminating all active sessions briefly. Mind you, HAproxy and nginx wasn't able to coup with dynamic configurations.
Openresty with lua plugin allows us to do everything above automatically and on-the-fly.
The module we used was:
lua-resty-auto-ssl

A: So I finally figured this out.
Step 1. Have your client setup a CNAME record that points their.domain.com to your app.saas.com
Step 2. Add their.domain.com to your nginx server block:
`server_name app.saas.com their.domain.com; and reload nginx
I am now working on setting up SSL for the extra domains and will comment when I figure it out exactly.
Edit: SSL is working with a SAN Let's Encrypt certificate installed on the server.


text:
Q: Exiting from virtual terminal and automatically going back to X disables keyboard and mouse When exiting from virtual terminal with automatic switch back to X the keyboard and mouse does not work any more.
Here is the sequence to reproduce the issue.
Hint: tty1 and tty2 are used by X for display manager and gnome session.

*

*Ctrl + Alt + F3 to switch from X to virtual terminal tty3

*Login

*Exit (switching back to X is performed automatically)

*Result: keyboard/mouse does not work any more

Does anyone have an idea how to fix this?
Thanks in advance

A: I observed similar issue with my Ubuntu 18.04 laptop.
I changed to virtual terminal using the following command from Ubuntu Terminal:
sudo chvt 2
Then I logged in to my virtual terminal using my credentials and if I logout from virtual terminal, my Keyboard no longer works.
This was resolved by using the following command to come out of virtual terminal:
sudo chvt 1
In Ubuntu 18.04, the GNOME/GUI runs on virtual terminal 1, so switching back to virtual terminal 1 restored the GUI for me.
Hope this helps for you as well. Thanks


text:
Q: Autoregressive modeling with excluding lags In terms of autoregressive modeling, has anyone ever seen it done with excluding some of the immediately preceding lags?
That is, has anyone ever seen it done with n=(not 1) under the summation sign??
Any pointers to it in the literature would be amazing.

A: Yes, this is completely acceptable. You can still think of it as an AR(n) process, with n=1 under the summation. It's just that certain autoregressive coefficients will have the value of zero. In fact, you can force this sparsity in a systematic way by adding an L1 penalty, akin to the Lasso Regression problem. For more down that path, you can check out this link for example:
http://www.stat.cmu.edu/~arinaldo/papers/arLasso.pdf


text:
Q: Is this sentence grammatically correct? "dared bid" After reading a text, I came across this sentence

Nobody dared bid on the priceless antique vase.

Is this sentence grammatically correct ?
Thanks guys

A: The verb 'dare', with the meaning in your example, can be followed either with a 'to infinitive' (e.g. 'dared to bid') or the bare form of a verb ('dared bid'). Either form is grammatical.

Dare also means 'to be brave enough or rude enough to do something'.
  With this meaning, it can be used as an ordinary main verb which can
  be followed by a to-infinitive or an infinitive without to. Less
  commonly, it can be used as a semi-modal verb followed by an
  infinitive without to.
Affirmative statement If Sally dares (to) go there again, she'll be in
  big trouble! (ordinary verb)
Negative statement He doesn't dare (to) go there. (ordinary verb)
No one dares (to) go there. (ordinary verb)
No one dare go there. (semi-modal verb)

Dare (Cambridge Dictionary)


text:
Q: How do I trigger a DIH import using DIH Commands Solr is set up correctly and I can import data using the DIH Data Import Handler manually - i.e. using the user interface.
I am having trouble triggering the import via HTTP Request - Is there a setting for turning this on or what else could I be missing. I am simply hitting the url:
https://url.net/solr/#/corename/dataimport//dataimport?command=full-import&commit=true

I don't know wny dataimport is in the url twice but i've tried it with it in only once and still doesn't work.
All this does is load up the data import UI in solr admin, and I can see the last successful import time - the one I did manually via the UI - I've tried to hit it using Chrome browser, postman and via a powershell script.
I think I'm missing something simple but not sure what...?

A: The url for the dataimport for in solr is like :
https://URL.net/solr/corename/dataimport?command=full-import&commit=true&indent=on&wt=json


text:
Q: How to add a div on button click? I have a button "Add" on click the button it should display two textbox along with two images ,on clicking the image calendar pop up occurs.The problem for me is when i click the add button nothing happens.can anyone teel whay i have done wrongly.Please provide an example if possible and is it possible do this in javascript instead of jquery.thanks in advance
This what i have tried
$("#btnAddAddress").click(function () {
    var addelement=$('

  <asp:Label ID="lblStartDate" runat="server" Text="Start Date"> </asp:Label> 	  <asp:TextBox ID="txtStartDate" runat="server" ></asp:TextBox> <asp:HyperLink ID="hypCalenStart" runat="server" ImageUrl="~/images/ico-cal.gif"> </asp:HyperLink> <ajax:CalendarExtender ID="StartDatePicker" runat="server" PopupButtonID="hypCalenStart" TargetControlID="txtStartDate"  SelectedDate= "<%# Datetime.Today()%>" Format="MM/dd/yyyy"> </ajax:CalendarExtender> 	  <asp:Label ID="lblEndDate" runat="server" Text="End Date"></asp:Label>

');
    $(this).after(addelement);
});

    <input type="button" id="btnAddAddress" name="btnAddAddress" value="Add"  />

Error: Unable to get value of the property '_behaviors': object is null or undefined

A: Well, one thing you can do is to add a class defined through CSS... for your specific case, you could add something like this:
$("#btnAddAddress").click(function(){
    $("#times").removeClass("hidden");
    $("#times").addClass("one");
});

[...]

Then, in your page, add the id "times" to the div that you want to appear, and have it initially with the "hidden" class instead of "one" ("hidden" is replaced by "one" when you click the button)... it's a little simple, but it should work.
display functionality seen here.


text:
Q: CUDA performance with Computer Vision Algorithm I'm moving my first step in the CUDA C programming world!
As first test I write simple algorithm to do gray conversion and thresholding on images (I am a fan of Computer Vision and OpenCV!).
I decided to compare my CUDA performance result with an analogous algorithm on the CPU and with the corresponding OpenCV (cpu) functions.
Here the result on a full hd video:
Frame Count: 4754
Frame Resolution: 1920x1080
Total time CPU: 67418.6 ms
Frame Avg CPU:  14.1814 ms

Frame Count: 4754
Frame Resolution: 1920x1080
Total time OpenCV: 23805.3 ms
Frame Avg OpenCV:  5.00742 ms

Frame Count: 4754
Frame Resolution: 1920x1080
==6149== NVPROF is profiling process 6149, command: ./OpenCV_test
Total time CUDA: 28018.2 ms
Frame Avg CUDA:  5.89361 ms

==6149== Profiling application: ./OpenCV_test
==6149== Profiling result:
Time(%)      Time     Calls       Avg       Min       Max  Name
55.45%  4.05731s      4754  853.45us  849.54us  1.1141ms doThreshold(unsigned char const *, unsigned char*, unsigned int, unsigned int, unsigned int)
34.03%  2.49028s      4754  523.83us  513.67us  1.3338ms  [CUDA memcpy HtoD]
10.52%  769.46ms      4754  161.85us  161.15us  301.06us  [CUDA memcpy DtoH]

==6149== API calls:
Time(%)      Time     Calls       Avg       Min       Max  Name
 80.11%  8.19501s      9508  861.91us  490.81us  2.7719ms  cudaMemcpy
 12.82%  1.31106s      9508  137.89us  66.639us  218.56ms  cudaMalloc
  5.74%  587.05ms      9508  61.742us  39.566us  2.0234ms  cudaFree
  1.21%  124.16ms      4754  26.116us  16.990us  365.86us  cudaLaunch
  0.06%  5.7645ms     23770     242ns      97ns  106.27us  cudaSetupArgument
  0.05%  5.4291ms      4754  1.1410us     602ns  10.150us  cudaConfigureCall
  0.01%  594.89us        83  7.1670us     249ns  282.44us  cuDeviceGetAttribute
  0.00%  45.536us         1  45.536us  45.536us  45.536us  cuDeviceTotalMem
  0.00%  35.649us         1  35.649us  35.649us  35.649us  cuDeviceGetName
  0.00%  1.8960us         2     948ns     345ns  1.5510us  cuDeviceGetCount
  0.00%     892ns         2     446ns     255ns     637ns  cuDeviceGet

As you can see OpenCV does much better than my cpu implementation and better than my Cuda algorithm! Where is the trick? My suspect is than OpenCV uses some special cpu hardware instruction set.
I expected something more with CUDA: people talk about speedup of 20x-30x in primitive image processing! I missed something?
Here some detail about my system configuration:

*

*Cpu Intel Core i7 5820k @4ghz

*GeForce GTX 970

*Linux Mint 17.2 Mate 64 bit

*Driver nVidia 352.55

*Cuda toolkit 7.5.18

Here some information on my OpenCV 3.0 build:

*

*Cuda enabled

*OpenCL disabled

*TBB disabled (to try to force single thread cpu execution)

*Intel IPP enabled

In the following the code executed for the test:
#include <iostream>
#include <numeric>
#include <string>
#include <stdlib.h>
#include <chrono>

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;
using namespace std::chrono;

const char* file = "PATH TO A VIDEO FILE";

__global__ void doThreshold(const uchar* bgrInput, uchar* output, uint inputSize, uint soglia, uint maxVal)
{
    uint i = blockIdx.x * blockDim.x + threadIdx.x;

    if (i < inputSize)
    {
        output[i] = 0.5f + ((bgrInput[3 * i] + bgrInput[3 * i + 1] + bgrInput[3 * i + 2]) / 3.0f); // gray conversion
        output[i] = output[i] > soglia ? maxVal : 0; // thresholding
    }

}

void cudaCvtThreshold(const Mat& mat, Mat& result, uint soglia, uint maxVal)
{
    if (mat.type() == CV_8UC3)
    {
        uint size = mat.rows * mat.cols;
        uint blockSize = 128; // no significant result varying this variable
        uint gridSize = ceil(size/(float)blockSize);
        uchar* d_bgrInput, *d_output;
        cudaMalloc((void**)&d_bgrInput, mat.channels() * size);
        cudaMalloc((void**)&d_output, size);
        cudaMemcpy(d_bgrInput, mat.data, mat.channels() * size, cudaMemcpyHostToDevice);

        doThreshold<<<gridSize, blockSize>>>(d_bgrInput, d_output, size, soglia, maxVal);

        result = Mat(mat.rows, mat.cols, CV_8UC1);
        cudaMemcpy(result.data, d_output, size, cudaMemcpyDeviceToHost);
        cudaFree(d_bgrInput);
        cudaFree(d_output);
    }
    else
        cerr << "Only CV_8UC3 matrix supported" << endl;

}

void cpuCvtThreshold(const Mat& mat, Mat& result, uint soglia, uint maxVal)
{
    if (mat.type() == CV_8UC3)
    {
        uint size = mat.rows * mat.cols;
        result = Mat(mat.rows, mat.cols, CV_8UC1);
        uchar* input = mat.data;
        uchar* output = result.data;
        for (uint i = 0; i < size; ++i)
        {
            output[i] = 0.5f + ((input[3 * i] + input[3 * i + 1] + input[3 * i + 2]) / 3.0f); // gray conversion
            output[i] = output[i] > soglia ? maxVal : 0; // thresholding
        }
    }
    else
        cerr << "Only CV_8UC3 matrix supported" << endl;
}

void cudaTest(const string src)
{
    VideoCapture cap(src);
    Mat frame, result;
    uint frameCount = cap.get(CAP_PROP_FRAME_COUNT);
    cout << "Frame Count: " << frameCount << endl;
    auto startTs = system_clock::now();
    cap >> frame;
    cout << "Frame Resolution: " << frame.cols << "x" << frame.rows << endl;

    while (not frame.empty()) {
        cudaCvtThreshold(frame, result, 127, 255);
        cap >> frame;
    }

    auto stopTs = system_clock::now();
    auto diff = stopTs - startTs;
    auto elapsed = chrono::duration_cast<chrono::microseconds>(diff).count() / (double)1e3;
    cout << "Total time CUDA: " << elapsed << " ms" << endl;
    cout << "Frame Avg CUDA:  " << elapsed / frameCount << " ms" << endl << endl;
}

void naiveCpu(const string src)
{
    VideoCapture cap(src);
    Mat frame, result;
    uint frameCount = cap.get(CAP_PROP_FRAME_COUNT);
    cout << "Frame Count: " << frameCount << endl;
    auto startTs = system_clock::now();
    cap >> frame;
    cout << "Frame Resolution: " << frame.cols << "x" << frame.rows << endl;

    while (not frame.empty()) {
        cpuCvtThreshold(frame, result, 127, 255);
        cap >> frame;
    }
    auto stopTs = system_clock::now();
    auto diff = stopTs - startTs;
    auto elapsed = chrono::duration_cast<chrono::microseconds>(diff).count() / (double)1e3;
    cout << "Total time CPU: " << elapsed << " ms" << endl;
    cout << "Frame Avg CPU:  " << elapsed / frameCount << " ms" << endl << endl;
}

void opencv(const string src)
{
    VideoCapture cap(src);
    Mat frame, result;
    uint frameCount = cap.get(CAP_PROP_FRAME_COUNT);
    cout << "Frame Count: " << frameCount << endl;
    auto startTs = system_clock::now();
    cap >> frame;
    cout << "Frame Resolution: " << frame.cols << "x" << frame.rows << endl;

    while (not frame.empty()) {
        cv::cvtColor(frame, result, COLOR_BGR2GRAY);
        threshold(result, result, 127, 255, THRESH_BINARY);
        cap >> frame;
    }
    auto stopTs = system_clock::now();
    auto diff = stopTs - startTs;
    auto elapsed = chrono::duration_cast<chrono::microseconds>(diff).count() / (double)1e3;
    cout << "Total time OpenCV: " << elapsed << " ms" << endl;
    cout << "Frame Avg OpenCV:  " << elapsed / frameCount << " ms" << endl << endl;
}

int main(void)
{
    naiveCpu(file);
    opencv(file);
    cudaTest(file);
    return 0;
}

EDIT:
Added / modified code
__global__ void doThreshold(const uchar* bgrInput, uchar* output, uint inputSize, uint soglia, uint maxVal)
{
    uint i = blockIdx.x * blockDim.x + threadIdx.x;

    if (i < inputSize)
    {
        uchar grayPix = 0.5f + ((bgrInput[3 * i] + bgrInput[3 * i + 1] + bgrInput[3 * i + 2]) / 3.0f); // gray conversion
        output[i] = grayPix > soglia ? maxVal : 0; // thresholding
    }

}

void cudaCvtThreshold(const Mat& mat, Mat& result, uint soglia, uint maxVal, uchar* d_bgrInput, uchar* d_output)
{
    uint size = mat.rows * mat.cols;
    uint blockSize = 128; // no significant result varying this variable
    uint gridSize = ceil(size/(float)blockSize);
    doThreshold<<<gridSize, blockSize>>>(d_bgrInput, d_output, size, soglia, maxVal);
}

void cudaTestOutMallocFree(const string src)
{
    VideoCapture cap(src);
    Mat frame;
    uint frameCount = cap.get(CAP_PROP_FRAME_COUNT);
    cout << "Frame Count: " << frameCount << endl;
    auto startTs = system_clock::now();
    cap >> frame;
    cout << "Frame Resolution: " << frame.cols << "x" << frame.rows << endl;
    uint size = frame.rows * frame.cols;

    Mat result(frame.rows, frame.cols, CV_8UC1);
    uchar* d_bgrInput, *d_output;
    cudaMalloc((void**)&d_bgrInput, frame.channels() * size);
    cudaMalloc((void**)&d_output, size);

    while (not frame.empty())
    {
        cudaMemcpy(d_bgrInput, frame.data, frame.channels() * size, cudaMemcpyHostToDevice);
        cudaCvtThreshold(frame, result, 127, 255, d_bgrInput, d_output);
        cudaMemcpy(result.data, d_output, size, cudaMemcpyDeviceToHost);
        cap >> frame;
    }

    cudaFree(d_bgrInput);
    cudaFree(d_output);

    auto stopTs = system_clock::now();
    auto diff = stopTs - startTs;
    auto elapsed = chrono::duration_cast<chrono::microseconds>(diff).count() / (double)1e3;
    cout << "Total time CUDA (out malloc-free): " << elapsed << " ms" << endl;
    cout << "Frame Avg CUDA (out malloc-free):  " << elapsed / frameCount << " ms" << endl << endl;
}

int main(void)
{
    naiveCpu(file);
    opencv(file);
    cudaTest(file);
    cudaTestOutMallocFree(file);
    return 0;
}

And results:
Frame Count: 4754
Frame Resolution: 1920x1080
Total time CPU: 70972.6 ms
Frame Avg CPU:  14.929 ms

Frame Count: 4754
Frame Resolution: 1920x1080
Total time OpenCV: 23475.4 ms
Frame Avg OpenCV:  4.93804 ms

Frame Count: 4754
Frame Resolution: 1920x1080
==4493== NVPROF is profiling process 4493, command: ./OpenCV_test
Total time CUDA: 27451.3 ms
Frame Avg CUDA:  5.77435 ms

Frame Count: 4754
Frame Resolution: 1920x1080
Total time CUDA (out malloc-free): 26137.3 ms
Frame Avg CUDA (out malloc-free):  5.49796 ms

==4493== Profiling application: ./OpenCV_test
==4493== Profiling result:
Time(%)      Time     Calls       Avg       Min       Max  Name
 53.74%  7.53280s      9508  792.26us  789.61us  896.17us  doThreshold(unsigned char const *, unsigned char*, unsigned int, unsigned int, unsigned int)
 35.57%  4.98604s      9508  524.40us  513.54us  979.37us  [CUDA memcpy HtoD]
 10.69%  1.49876s      9508  157.63us  157.09us  206.24us  [CUDA memcpy DtoH]

==4493== API calls:
Time(%)      Time     Calls       Avg       Min       Max  Name
 88.22%  15.7392s     19016  827.68us  482.18us  1.7570ms  cudaMemcpy
  7.07%  1.26081s      9510  132.58us  65.458us  198.86ms  cudaMalloc
  3.26%  582.24ms      9510  61.223us  39.675us  304.16us  cudaFree
  1.33%  236.64ms      9508  24.888us  13.497us  277.21us  cudaLaunch
  0.06%  10.667ms     47540     224ns      96ns  347.09us  cudaSetupArgument
  0.06%  9.9587ms      9508  1.0470us     504ns  9.4800us  cudaConfigureCall
  0.00%  428.88us        83  5.1670us     225ns  228.70us  cuDeviceGetAttribute
  0.00%  43.388us         1  43.388us  43.388us  43.388us  cuDeviceTotalMem
  0.00%  34.389us         1  34.389us  34.389us  34.389us  cuDeviceGetName
  0.00%  1.7010us         2     850ns     409ns  1.2920us  cuDeviceGetCount
  0.00%     821ns         2     410ns     225ns     596ns  cuDeviceGet

Better performances with single malloc and free, but small improvement...
EDIT2:
As suggested by Jez I modified the Cuda Kernel in order to process multiple pixel (8 in the following execution) inside each GPU thread:
Here the modified code:
__global__ void doThreshold(const uchar* bgrInput, uchar* output, uint inputSize, uint soglia, uint maxVal, uint pixelPerThread)
{
    uint i = pixelPerThread * (blockIdx.x * blockDim.x + threadIdx.x);

    if (i < inputSize)
    {
        for (uint j = 0; j < pixelPerThread; j++) {
            uchar grayPix = 0.5f + ( (bgrInput[3 * (i + j)] + bgrInput[3 * (i + j) + 1] + bgrInput[3 * (i + j) + 2]) / 3.0f ); // gray conversion
            output[i + j] = grayPix > soglia ? maxVal : 0; // thresholding
        }
    }
}

void cudaCvtThreshold(const Mat& mat, Mat& result, uint soglia, uint maxVal, uchar* d_bgrInput, uchar* d_output)
{
    uint size = mat.rows * mat.cols;
    uint pixelPerThread = 8;
    uint blockSize = 128; // no significant result varying this variable
    uint gridSize = ceil(size/(float)(blockSize * pixelPerThread));
    doThreshold<<<gridSize, blockSize>>>(d_bgrInput, d_output, size, soglia, maxVal, pixelPerThread);
}

Then the results:
Frame Count: 4754
Frame Resolution: 1920x1080
Total time OpenCV: 23628.8 ms
Frame Avg OpenCV:  4.97031 ms

Frame Count: 4754
Frame Resolution: 1920x1080
==13441== NVPROF is profiling process 13441, command: ./OpenCV_test
Total time CUDA (out malloc-free): 25655.5 ms
Frame Avg CUDA (out malloc-free):  5.39662 ms

==13441== Profiling application: ./OpenCV_test
==13441== Profiling result:
Time(%)      Time     Calls       Avg       Min       Max  Name
 49.30%  3.15853s      4754  664.39us  658.24us  779.04us  doThreshold(unsigned char const *, unsigned char*, unsigned int, unsigned int, unsigned int, unsigned int)
 38.69%  2.47838s      4754  521.32us  513.35us  870.69us  [CUDA memcpy HtoD]
 12.01%  769.53ms      4754  161.87us  161.31us  200.58us  [CUDA memcpy DtoH]

==13441== API calls:
Time(%)      Time     Calls       Avg       Min       Max  Name
 95.78%  7.26387s      9508  763.97us  491.11us  1.6589ms  cudaMemcpy
  2.51%  190.70ms         2  95.350ms  82.529us  190.62ms  cudaMalloc
  1.53%  116.31ms      4754  24.465us  16.844us  286.56us  cudaLaunch
  0.09%  6.7052ms     28524     235ns      98ns  233.19us  cudaSetupArgument
  0.08%  5.9538ms      4754  1.2520us     642ns  12.039us  cudaConfigureCall
  0.00%  263.87us        83  3.1790us     225ns  111.03us  cuDeviceGetAttribute
  0.00%  174.45us         2  87.227us  52.521us  121.93us  cudaFree
  0.00%  34.612us         1  34.612us  34.612us  34.612us  cuDeviceTotalMem
  0.00%  29.376us         1  29.376us  29.376us  29.376us  cuDeviceGetName
  0.00%  1.6950us         2     847ns     343ns  1.3520us  cuDeviceGetCount
  0.00%     745ns         2     372ns     217ns     528ns  cuDeviceGet

Notice that the average time for the kernel execution is now 664,39 us instead of 792,26 us
Not bad! :-)
But OpenCV (using Intel IPP) is still faster!
EDIT3:
I recompiled OpenCV WITHOUT IPP and the various SSE instructions. The OpenCV performances seem to be the same!!
Frame Count: 4754
Frame Resolution: 1920x1080
Total time OpenCV: 23541.7 ms
Frame Avg OpenCV:  4.95198 ms

A: There are two things going on here.
Overheads
You're spending roughly half of the GPU time allocating and copying memory to and from the GPU. The CPU-GPU connection is a relatively slow link, and straight away halves your performance compared to the situation where the data starts and ends on the GPU and memory is allocated once. There are some things you can do to help here, such as moving the allocations outside of the loop, and overlapping the data transfer for one frame with the calculation of the next, but the pattern of copy->execute->copy rarely produces great runtimes unless the execution is quite complex.
Kernel
Your kernel is expected to be memory bound. You are (ideally) moving 4 bytes/thread, with ~2 million threads (pixels) and a runtime of 853us you're getting about 10GB/s. The GTX 970's peak is 224GB/s. You're a long way off.
The problem here is that you're doing 8 bit transactions. The solution in this case would be to use shared memory. If you load data into shared memory in a high performance manner (eg. cast the pointers to int4s, making sure of alignment) at the start of the kernel, you can then read from that memory, then write back out with 32+ bits per thread. This means you're have to process multiple pixels a thread, but that's not a problem.
An alternative solution would be to find a library to do this operation. NPP, for example, covers a lot of image related tasks and may well be faster than hand-written code.

With a good memory access pattern I would expect this kernel to go >10x faster. Due to Amdahl's Law, you're going to be dominated by overhead once you've done this, so unless you can get rid of them the runtime is only going to be ~2x faster.


text:
Q: Is while true in a redux sage only for long polling or for other use cases? I would normally guess redux-saga while(true) would be used for long-polling and I see other posts regarding long polling.  However, I joined a project and I see around 44 sagas with while(true) which seems to imply there is no way it is for long polling on this project (I am guessing a typical project would be 1 or max 2 long polling to gather all info in one shot).  Here is an example...
 function* enrollAddContactSaga() {
  while (true) {
    const { username, appName } = yield take(ENROLL_ADD_CONTACT);
    const newUserId = uuidv4();
    yield put(enrolllNewContact(newUserId, username));
    const { contactAddSuccess, contactAddFailure } = yield race({
      contactAddSuccess: take(ENROLL_NEW_CONTACT_ADD_SUCCESS),
      contactAddFailure: take(ENROLL_NEW_CONTACT_ADD_FAILURE),
    });
    if (contactAddSuccess) {
      yield put(enrollCheckCredentialStatus({ username, appName }));
    } else {
      yield put(
        showAlert('Oops!', buildErrorMessage(contactAddFailure), 'error'),
      );
    }
  }
}

Can someone shed some light on this? What is while(true) for?
I really would think the framework would constantly call this and the only break it would get is during a remote call and once that returns, the saga returns and since it is never done, it calls the method yet again.
NOTE: I also do not see any return statements in the generator saga functions to ever make it complete either.

A: Basically, while(true) with no break is useful when you want a saga to run for the lifetime of your app (or until cancelled by a parent saga). Usually this is because this saga is responsible for listening for some events, and those events never stop being relevant.
In your specific code, the saga enters the loop, then immediately yields until an ENROLL_ADD_CONTACT action happens. The saga doesn't need to poll for this to happen, redux saga will be checking any actions that are dispatched and will wake your saga if and when it's necessary. If the action never happens, then your saga will remain paused forever. Assuming the action does happen though, your saga resumes execution at that time.
As the rest of the saga runs, it is going to do some other asynchronous things, and during that time it's not listening for more ENROLL_ADD_CONTACT actions. So hypothetically, if one of those actions happens during this time, it will be ignored. Eventually, the end of the loop is reached and it loops back to the top, at which point it starts listening for the action again.
In other words, the code you showed is implementing something very similar to takeLeading, just in a single saga instead of split into two. So a similar behavior could be achieved like this:
function* enrollAddContactSaga() {
  yield takeLeading(ENROLL_ADD_CONTACT, someOtherSaga);
}

function* someOtherSaga(action) {
  const { username, appName } = action;
  const newUserId = uuidv4();
  yield put(enrolllNewContact(newUserId, username));
  const { contactAddSuccess, contactAddFailure } = yield race({
    contactAddSuccess: take(ENROLL_NEW_CONTACT_ADD_SUCCESS),
    contactAddFailure: take(ENROLL_NEW_CONTACT_ADD_FAILURE),
  });
  if (contactAddSuccess) {
    yield put(enrollCheckCredentialStatus({ username, appName }));
  } else {
    yield put(
      showAlert('Oops!', buildErrorMessage(contactAddFailure), 'error'),
    );
  }
}


text:
Q: React Native API fetch error Request failed with status code 400 I am trying to load data when a React Native but I am getting an error stating:
- node_modules/axios/lib/core/createError.js:15:17 in createError
- node_modules/axios/lib/core/settle.js:16:9 in settle
- node_modules/axios/lib/adapters/xhr.js:50:6 in handleLoad
- node_modules/event-target-shim/dist/event-target-shim.js:818:39 in EventTarget.prototype.dispatchEvent
- node_modules/react-native/Libraries/Network/XMLHttpRequest.js:566:23 in setReadyState
- node_modules/react-native/Libraries/Network/XMLHttpRequest.js:388:25 in __didCompleteResponse
- node_modules/react-native/Libraries/vendor/emitter/EventEmitter.js:190:12 in emit
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:436:47 in __callFunction
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:111:26 in __guard$argument_0
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:384:10 in __guard
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:110:17 in __guard$argument_0
* [native code]:null in callFunctionReturnFlushedQueue

Here is my code:
getting api data:
import { useEffect, useState } from 'react';
import zomato from '../api/zomato';

export default () => {
    const [results, setResults] = useState([]);
    const [errorMessage, setErrorMessage] = useState('');

    const searchAPI = async () => {
        try {
            const response = await zomato.get(`/collections`);
            setResults(response.data);
            console.log(response.data);
        } catch(err) {
            setErrorMessage('Something went wrong, man');
        }
    }
    return [searchAPI, results, errorMessage];
}

Here is the screen where I am loading everything
const HomeScrn = () => {
    const [searchAPI, results, errorMessage] = useResults();

    useEffect(() => {
        searchAPI()
    }, [])

    return (
        <View>
            <View style={styles.header}>

                <Image source={Logo} style={{resizeMode:'stretch', width:50, height:50, alignSelf:'center', marginTop:30}}/>
                    <Icon
                        raised
                        name='location'
                        type='octicon'
                        color='#f50'
                        onPress={() => this.setState({ isModalVisible: !this.state.isModalVisible})}
                        containerStyle={{ alignSelf:'flex-end', marginRight:20, marginTop:-60 }}/>
            </View>
                <FlatList
                    style={{marginBottom: 160, marginTop:-10}}
                    showsVerticalScrollIndicator={false}
                    keyExtractor={item => item.id}
                    data={results}
                    renderItem={({ item }) =>
                    <TouchableHighlight onPress={()=> console.log('pressed!')}>
                        <View style={styles.container}>
                            <ImageBackground style={styles.imageURL} resizeMode="cover" source={{uri: item.collection.image_url}}>
                                <Text style={styles.collTitle}>{item.collection.title} </Text>
                            </ImageBackground>
                        </View>
                    </TouchableHighlight>}/>
        </View>
        )}

I don't understand what that is, am I retrieving that data incorrectly?

A: I've found the solution. I was calling the API incorrectly. Turns out there was a required param I needed to add to my code when I call the data from the API. Here is my updated code:
import { useEffect, useState } from 'react';
import zomato from '../api/zomato';

export default () => {
    const [results, setResults] = useState([]);
    const [errorMessage, setErrorMessage] = useState();

    const searchAPI = async (location) => {
        try {
            const response = await zomato.get(`/collections`, {
                params: {
                    'city_id': `${location}`
                }
            });
            setResults(response);
            console.log(response);
        } catch(err) {
            setErrorMessage(err);
            console.log(err)
        }
    }

    return [searchAPI, results, errorMessage];
}


text:
Q: In go, Manually Invoke an http.FileServer and/or What is an http Handler I'm an experienced programmer, but new to go.  Apologies in advance if this is an obvious question or well tread path.  I'm still getting my bearings in the language and its semantics.
I'm trying to create a web server in go that

*

*Examines the HTTP request

*Based on the results of the request, serves a specific static folder

i.e., something where the simplified pseudo code looks like
import (
    "io"
    "net/http"
    "fmt"
    "strings"
    "encoding/base64"
)

func examineRequest(request *http.Request) {
    //looks at request header
    if(request headers have one thing){
        return "foo"
    }
    return "bar"
}

func processRequest(responseWriter http.ResponseWriter, request *http.Request) {
    folderToServe = examineRequest(request);
    if folderToServe == "bar" {
        //serve static files from the ./static/bar folder

        //go freaks out if I try these
        //http.Handle("/", http.FileServer(http.Dir("./static/bar")))
        //http.FileServer(http.Dir("./static/bar")()

    }
    else if folderToServer == "foo" {
        //serve static files from the ./static/foo folder

        //go freaks out if I try these
        //http.Handle("/", http.FileServer(http.Dir("./static/foo")))
        //http.FileServer(http.Dir("./static/foo")()
    }
}

func main(){
    http.HandleFunc("/", processRequest)
    //http.Handle("/", http.FileServer(http.Dir("./static")))
}

Experienced go programmers may have already spotted the problem.  I'm performing my examination in processRequest, and because of that, its too late to to call Handle -- however, you can't register more than one handle for the same path in go, and nested handle calls freak go out.
I though the handler might be similar to an anonymous function in other languages and tried call it -- but go did like that either.
So -- is there a way to manually invoke the handler returned from the call to http.FileServer(http.Dir("./static"))?
Is that even the right question to be asking here?
What exactly is a handler in the context of the http module?

A: Use http.FileServer(http.Dir("./static/foo")).ServeHTTP(w, req).
//edit
http.FileServer returns an http.Handler which in turn provides the ServerHTTP method.


text:
Q: Check if String Contains Match in Enumerable.Range Filter List I want to check if a string contains a word or number from a list and remove it from the string.
I want to use Enumerable.Range() to create the filter list and use it to filter many different strings.
I'm trying to combine two previous answers:
https://stackoverflow.com/a/49733139/6806643
https://stackoverflow.com/a/49740832/6806643

The sentence I want to filter:

This is a A05B09 hello 02 100 test

Filter
A00B00-A100B100, 01-100, 000-100, hello
Should read:

This is a test

Old Way
For Loop - Works
http://rextester.com/BJL70824
New Way
Enumerable Range List - Does not work
http://rextester.com/ZSCM64375

C#
List<List<string>> filters = Enumerable.Range(0, 101)
       .SelectMany(a => Enumerable.Range(0, 101).Select(b => "A{0:00}B{1:00}"))
       .Select(i => Enumerable.Range(0, 10).Select(c => string.Empty).ToList())
           .SelectMany(a => Enumerable.Range(0, 101).Select(b => "{0:000}"))
           .SelectMany(a => Enumerable.Range(0, 101).Select(b => "{0:00}"))
           .SelectMany(a => Enumerable.Range(0, 1).Select(b => "hello"))
           .ToList();

List<string> matches = new List<string>();

// Sentence
string sentence = "This is a A05B09 hello 02 100 test";
string newSentence = string.Empty;

// Find Matches
for (int i = 0; i < filters.Count; i++)
{
    // Add to Matches List
    if (sentence.Contains(filters[i].ToString()))
    {
        matches.Add(filters[i]);
    }
}

// Filter Sentence
newSentence = Regex.Replace(
    sentence
,   @"(?<!\S)(" + string.Join("|", matches) + @")(?!\S)"
,   ""
,   RegexOptions.IgnoreCase
);

// Display New Sentence
Console.WriteLine(newSentence);

A: Your this line seems not meet your requirements..SelectMany(a => Enumerable.Range(0, 101).Select(b => "A{0:00}B{1:00}"))
Can you try this Linq?
List<string> filters = Enumerable.Range(0, 101)
                                 .SelectMany(a => Enumerable.Range(0, 101).Select(b => $"A{a:00}B{b:00}"))
                                 .Union(Enumerable.Range(0, 101).Select(b => $"{b:000}"))
                                 .Union(Enumerable.Range(0, 101).Select(b => $"{b:00}"))
                                 .Union(new List<string> {"hello"})
                                 .ToList();

This verion can give you expected result on rextester
List<string> filters = Enumerable.Range(0, 101)
                                 .SelectMany(a => Enumerable.Range(0, 101).Select(b => string.Format("A{0:00}B{1:00}", a, b)))
                                 .Union(Enumerable.Range(0, 101).Select(b => string.Format("{0:000}", b)))
                                 .Union(Enumerable.Range(0, 101).Select(b => string.Format("{0:00}", b)))
                                 .Union(new List<string> { "hello" })
                                 .ToList();

A: I think creating a list of all possible combinations is a very bad approach. You are creating huge lists which will make your process use a lot of RAM and be very slow without any good reason. Why not just create a good Regex? For example, with this expression, you get your desired string:
\b(A\d\dB\d\d|A100B100|0?\d\d|100|hello)\b\s*

That is assuming you don't want to replace stuff like A101B101 or 123.
If you want to replace those as well, the regex is a bit simpler:
\b(A\d\d\d?B\d\d\d?|\d\d\d?|hello)\b\s*


text:
Q: Is there a portable robust self-contained way to obfuscate email addresses in TeX? It is a well-known fact that spammers crawl web pages and automatically extract email addresses not only from HTML files, but
also from other formats, e.g., PDF.
It is therefore desirable to have an obfuscation method for email addresses in TeX
that works with commonly used formats (e.g., PDF, PostScript, DVI),
produces results that look identical to what one would get without obfuscation,
and does not allow any commonly used software (e.g., pdftotext)
to extract the unobfuscated email address.
(A use case I have a mind is uploading a paper on arXiv with an email address in it.)
Thus the desired properties of obfuscation can be summarized as follows.

*

*Portability: the end result must look exactly like the unobfuscated version
when compiled with any commonly used software: tex, tex+dvips, tex+dvipdfm(x),
pdftex, tex+dvips+ghostscript (directly or via a script such as ps2pdf).
In particular, when compiled by arXiv, all three resulting files (DVI, PostScript, and PDF) must have an email address in them that looks exactly like an unobfuscated email address, i.e., the reader of the paper should not be able to guess that obfuscation was used by merely looking at the paper (though copy-paste might fail).

*Robustness: none of the commonly used software, such as

*

*catdvi, dvi2tty, crudetype for DVI,

*ghostscript (directly or via a script such as ps2ascii), ps2txt, ps2a, pstotext for PostScript,

*pdftotext, pdfbox, pdf2txt.py, or ghostscript for PDF,

should be able to extract (after a possible removal of whitespace)
the unobfuscated email from any of the files produced in 1.

*Self-containedness: the method must not require any external files and must only use the current font.
(Otherwise one could just use a font with randomly remapped characters, which would be a very reliable obfuscation method,
but not a very practical one if one wants to publish a paper in journal.
For the same reason using other fonts (even in the same family) is also not acceptable because it easily breaks if the fonts are changed.)
Methods that are known not to work:

*

*Typesetting the email address in a nontrivial order, e.g., randomly permuting letters.
Fails with catdvi, dvipdfm+pdftotext, pdftex+pdftotext.

*Inserting in the middle of the email address some additional text typeset
in a microscopic font (cmr10 at 1sp, for example).
Fails with tex+dvipdfm+pdftotext.
It also exposes bugs in catdvi and pdftex 1.40.15, i.e., the latter is a noncompliant implementation of TeX.
Even though one can work around these bugs by using 8sp instead of 1sp, the method also fails with pdftex+pdftotext.

*Inserting horizontal microspaces such as 1sp or -1sp in the middle of the email address.  Same as 2.

*Raising or lowering individual letters by a microscopic amount (e.g., 1sp).
Works with catdvi, but fails with pdftotext.

*Replacing some period with the dot accent lowered by its height minus the height of the period.
Although this method does satisfy all of the above criteria,
and, in a certain sense, is a solution (which I currently use in my papers together with typesetting in a different order),
for pdftotext it merely replaces periods with spaces,
which is still vulnerable to automatic collection
(spam software is known to deobfuscate even more sophisticated variants such as "user at example dot com"
and periods replaced by spaces certainly do not present a problem), so it violates condition 2, if not in letter, then in spirit.
It also relies on rather subtle properties of Computer
Modern fonts, which means
it might break condition 1 if the publisher uses a more poorly
designed font.

*Inserting some additional white-colored text
that is typeset before the email address and overlaps with it.
Unlike the previous methods this one is somewhat
nonportable, but it works fine with most software
using color specials, and some special hacks for pdftex
(it does break some less commonly used software such as dvilj).
Unfortunately, this method totally fails when one prints the document
on a nonwhite paper or simply displays it on a nonwhite
background (which is not that uncommon, some people prefer light gray or similar colors as background).
Ostensibly, the problem could be solved by using
background-colored text, but I don't know
any reasonably portable way to do it,
though some programs might allow such hacks.

A: If you really want to hide the text you could extract the paths and draw them, the following's pretty poor, mostly as I ignored the distinction between move and line segments
but it could be improved to render essentially the same as the original text.
First use a bit of postscript to convert the text to a path;
/Times-Roman findfont 10 scalefont setfont

newpath
100 100 moveto
(someone@example.org)
true
charpath
flattenpath
{== == (move) ==}
{== == (line) ==}
{== == == ==(curve) ==}
{(close) ==}
pathforall
showpage

that produces
a path of the form
104.429482
103.061745
(line)
104.429482
102.952805
(line)
104.320549
102.795456
(line)

then a bit of editing you can render that path with tikz:

with a bit more care the individual path segments could be closed and filled to
produce essentially the original font rendering, but here I just stroke the entire
path.
\documentclass{article}
\usepackage{tikz}

\begin{document}

aaa

\fbox{%
\begin{tikzpicture}[xscale=-.03,yscale=.03,rotate=90]
\draw

(103.085953,103.098053)
--
(104.429482,103.061745)
--
(104.429482,102.952805)
--
(104.320549,102.795456)
--
(104.393173,102.529175)
--
(104.526314,101.839249)
--
(104.178329,100.876991)
--
(103.303818,100.495712)
--
(102.565483,100.762)
--
(101.887665,101.657692)
--
(101.56086,102.22657)
--
(100.822517,102.73494)
--
(100.308105,102.514038)
--
(100.120491,101.923973)
--
(100.432167,101.122093)
--
(101.488235,100.665169)
--
(101.488235,100.50782)
--
(99.9631424,100.50782)
--
(99.9631424,100.640961)
--
(100.072075,100.870934)
--
(99.9994583,101.318779)
--
(99.902626,102.032913)
--
(100.274818,103.019379)
--
(101.16143,103.424858)
--
(101.793861,103.234222)
--
(102.33551,102.601791)
--
(102.964912,101.536652)
--
(103.63063,101.113014)
--
(104.114784,101.321808)
--
(104.296341,101.875557)
--
(104.024,102.535225)
--
(103.085953,102.952805)
--
(103.085953,103.098053)
--
(104.526314,106.344925)
--
(103.884811,104.780495)
--
(102.22657,104.178329)
--
(100.562286,104.786552)
--
(99.902626,106.332825)
--
(100.589523,107.885147)
--
(102.299194,108.511528)
--
(103.89994,107.900284)
--
(104.526314,106.344925)
--
(104.247925,106.223892)
--
(103.609444,107.234566)
--
(101.960289,107.627945)
--
(100.65004,107.310211)
--
(100.181015,106.441757)
--
(100.810417,105.497658)
--
(102.698624,105.061913)
--
(103.827316,105.373589)
--
(104.247925,106.223892)
--
(99.9994583,109.044098)
--
(99.9994583,111.234909)
--
(100.144699,111.234909)
--
(100.268768,110.696281)
--
(100.653069,110.557091)
--
(103.424858,110.557091)
--
(103.594315,110.690231)
--
(104.005852,111.719063)
--
(103.754692,112.209274)
--
(102.977013,112.372673)
--
(100.846725,112.372673)
--
(100.302055,112.248611)
--
(100.144699,111.706963)
--
(99.9994583,111.706963)
--
(99.9994583,113.909866)
--
(100.144699,113.909866)
--
(100.317184,113.337959)
--
(100.931458,113.19574)
--
(103.412758,113.19574)
--
(104.005852,114.272987)
--
(103.77285,114.850952)
--
(102.928604,115.011322)
--
(100.858833,115.011322)
--
(100.317184,114.896339)
--
(100.144699,114.357712)
--
(99.9994583,114.357712)
--
(99.9994583,116.512207)
--
(100.144699,116.512207)
--
(100.168907,116.258026)
--
(100.749901,115.834389)
--
(102.771248,115.834389)
--
(104.084526,115.546921)
--
(104.526314,114.696625)
--
(103.691147,113.086807)
--
(104.526314,112.045868)
--
(104.381065,111.422516)
--
(103.763771,110.520775)
--
(104.502106,110.520775)
--
(104.526314,110.448151)
--
(104.078468,109.068306)
--
(103.909019,109.068306)
--
(103.957436,109.383011)
--
(103.328026,109.734024)
--
(100.834625,109.734024)
--
(100.296,109.597855)
--
(100.144699,109.044098)
--
(99.9994583,109.044098)
--
(101.609276,120.685036)
--
(100.813446,119.97998)
--
(100.580444,119.159943)
--
(101.367195,117.913239)
--
(102.722832,117.622742)
--
(102.722832,120.64872)
--
(103.464195,120.503471)
--
(103.957436,120.225082)
--
(104.526314,118.966278)
--
(103.851524,117.477493)
--
(102.105537,116.908615)
--
(100.495712,117.404877)
--
(99.902626,118.748405)
--
(100.326263,119.99511)
--
(101.548752,120.842384)
--
(101.609276,120.685036)
--
(103.037537,117.64695)
--
(103.890862,117.976784)
--
(104.1632,118.687889)
--
(103.924149,119.341499)
--
(103.037537,119.644096)
--
(103.037537,117.64695)
--
(104.526314,123.562737)
--
(103.884811,121.998306)
--
(102.22657,121.396133)
--
(100.562286,122.004356)
--
(99.902626,123.550629)
--
(100.589523,125.102959)
--
(102.299194,125.729332)
--
(103.89994,125.118088)
--
(104.526314,123.562737)
--
(104.247925,123.441696)
--
(103.609444,124.45237)
--
(101.960289,124.845749)
--
(100.65004,124.528023)
--
(100.181015,123.659569)
--
(100.810417,122.715462)
--
(102.698624,122.279724)
--
(103.827316,122.5914)
--
(104.247925,123.441696)
--
(99.9994583,126.286118)
--
(99.9994583,128.367981)
--
(100.144699,128.367981)
--
(100.280869,127.853569)
--
(100.653069,127.714378)
--
(103.424858,127.714378)
--
(103.866653,128.277206)
--
(103.981644,128.73111)
--
(103.748642,129.278809)
--
(103.025429,129.457336)
--
(100.967766,129.457336)
--
(100.338364,129.327225)
--
(100.144699,128.827942)
--
(99.9994583,128.827942)
--
(99.9994583,130.873489)
--
(100.144699,130.873489)
--
(100.308105,130.398422)
--
(100.798309,130.280411)
--
(103.049637,130.280411)
--
(104.132942,129.971756)
--
(104.526314,129.118423)
--
(104.362915,128.486008)
--
(103.727455,127.69017)
--
(104.502106,127.69017)
--
(104.526314,127.617546)
--
(104.078468,126.261909)
--
(103.909019,126.261909)
--
(103.957436,126.528191)
--
(103.824287,126.818687)
--
(103.328026,126.891312)
--
(100.883041,126.891312)
--
(100.320206,126.7733)
--
(100.144699,126.286118)
--
(99.9994583,126.286118)
--
(101.609276,135.121964)
--
(100.813446,134.416916)
--
(100.580444,133.596878)
--
(101.367195,132.350174)
--
(102.722832,132.059677)
--
(102.722832,135.085663)
--
(103.464195,134.940414)
--
(103.957436,134.662018)
--
(104.526314,133.403214)
--
(103.851524,131.914429)
--
(102.105537,131.345551)
--
(100.495712,131.841812)
--
(99.902626,133.185349)
--
(100.326263,134.432037)
--
(101.548752,135.279312)
--
(101.609276,135.121964)
--
(103.037537,132.083893)
--
(103.890862,132.413712)
--
(104.1632,133.124817)
--
(103.924149,133.778427)
--
(103.037537,134.081024)
--
(103.037537,132.083893)
--
(100.713585,142.32077)
--
(100.241531,140.38414)
--
(100.459404,139.225189)
--
(101.061569,138.317398)
--
(101.990547,137.724304)
--
(103.170677,137.515518)
--
(104.514214,137.754562)
--
(105.591461,138.423309)
--
(106.341904,140.287308)
--
(106.130081,141.379684)
--
(105.555145,142.278397)
--
(104.704849,142.883591)
--
(103.666939,143.107513)
--
(102.326431,142.717163)
--
(101.730316,141.848709)
--
(102.178162,141.461395)
--
(102.359718,141.473495)
--
(104.853119,142.115)
--
(104.853119,141.43718)
--
(104.477898,141.340347)
--
(104.998367,140.626221)
--
(104.550522,139.573181)
--
(103.63063,138.937729)
--
(102.517067,138.701691)
--
(101.736366,138.949829)
--
(101.415611,139.573181)
--
(102.117638,140.79567)
--
(101.603226,141.089188)
--
(101.403511,141.69136)
--
(102.108559,142.965302)
--
(103.763771,143.506943)
--
(104.898514,143.25882)
--
(105.812355,142.574951)
--
(106.423607,141.549149)
--
(106.644501,140.275208)
--
(106.378212,138.868134)
--
(105.642899,137.727341)
--
(104.553551,136.95874)
--
(103.206993,136.680344)
--
(101.890694,136.955704)
--
(100.828575,137.724304)
--
(100.12352,138.874176)
--
(99.8663101,140.311523)
--
(99.9813,141.270752)
--
(100.423088,142.429703)
--
(100.713585,142.32077)
--
(104.56263,140.771469)
--
(103.933228,141.170898)
--
(102.408134,140.735153)
--
(101.839249,139.996811)
--
(102.063171,139.564102)
--
(102.674416,139.403717)
--
(104.017952,139.875778)
--
(104.56263,140.771469)
--
(101.609276,148.769119)
--
(100.813446,148.064072)
--
(100.580444,147.244034)
--
(101.367195,145.99733)
--
(102.722832,145.706833)
--
(102.722832,148.732803)
--
(103.464195,148.58757)
--
(103.957436,148.309174)
--
(104.526314,147.050369)
--
(103.851524,145.561584)
--
(102.105537,144.992706)
--
(100.495712,145.488968)
--
(99.902626,146.832504)
--
(100.326263,148.079193)
--
(101.548752,148.926468)
--
(101.609276,148.769119)
--
(103.037537,145.731049)
--
(103.890862,146.060867)
--
(104.1632,146.771973)
--
(103.924149,147.425583)
--
(103.037537,147.72818)
--
(103.037537,145.731049)
--
(99.9994583,151.925217)
--
(99.9994583,153.910263)
--
(100.144699,153.910263)
--
(100.737793,153.099289)
--
(102.662315,151.840485)
--
(103.848495,152.651443)
--
(104.272133,153.450302)
--
(104.429482,153.450302)
--
(104.429482,151.901)
--
(104.272133,151.901)
--
(104.05426,152.28833)
--
(103.424858,151.925217)
--
(102.98912,151.63472)
--
(103.182785,151.489471)
--
(104.05426,151.041626)
--
(104.272133,151.465271)
--
(104.429482,151.465271)
--
(104.429482,149.431808)
--
(104.272133,149.431808)
--
(104.272133,149.516541)
--
(103.691147,150.266983)
--
(102.274986,151.198975)
--
(100.653069,150.073318)
--
(100.259689,149.728363)
--
(100.144699,149.359192)
--
(99.9994583,149.359192)
--
(99.9994583,150.787445)
--
(100.144699,150.787445)
--
(100.326263,150.388016)
--
(100.725693,150.58168)
--
(101.936081,151.368439)
--
(100.556236,152.26413)
--
(100.38678,152.324646)
--
(100.144699,151.925217)
--
(99.9994583,151.925217)
--
(100.653069,158.533951)
--
(100.459404,158.110306)
--
(101.02829,157.807709)
--
(102.952805,157.807709)
--
(103.957436,157.62616)
--
(104.526314,156.391556)
--
(104.1632,155.144852)
--
(103.424858,154.745422)
--
(103.001221,155.169067)
--
(103.412758,155.604797)
--
(103.570107,155.580597)
--
(103.800079,155.556381)
--
(104.142014,155.762161)
--
(104.284241,156.270523)
--
(104.078468,156.815201)
--
(103.473274,157.00885)
--
(102.86808,157.00885)
--
(102.253807,155.547318)
--
(101.80294,154.902771)
--
(100.955666,154.551758)
--
(100.199173,154.839233)
--
(99.902626,155.580597)
--
(100.616753,157.020966)
--
(100.066025,157.202515)
--
(99.902626,157.65036)
--
(100.38678,158.533951)
--
(100.653069,158.533951)
--
(101.209846,157.00885)
--
(100.689377,156.754669)
--
(100.471504,156.040543)
--
(100.695427,155.598755)
--
(101.234055,155.423248)
--
(101.270363,155.423248)
--
(102.008705,155.774261)
--
(102.638107,157.00885)
--
(101.209846,157.00885)
--
(99.9994583,158.78511)
--
(99.9994583,160.975906)
--
(100.144699,160.975906)
--
(100.268768,160.437286)
--
(100.653069,160.298096)
--
(103.424858,160.298096)
--
(103.594315,160.431244)
--
(104.005852,161.460068)
--
(103.754692,161.950272)
--
(102.977013,162.113678)
--
(100.846725,162.113678)
--
(100.302055,161.989609)
--
(100.144699,161.447968)
--
(99.9994583,161.447968)
--
(99.9994583,163.650879)
--
(100.144699,163.650879)
--
(100.317184,163.078964)
--
(100.931458,162.936752)
--
(103.412758,162.936752)
--
(104.005852,164.013992)
--
(103.77285,164.591949)
--
(102.928604,164.752335)
--
(100.858833,164.752335)
--
(100.317184,164.637344)
--
(100.144699,164.098724)
--
(99.9994583,164.098724)
--
(99.9994583,166.25322)
--
(100.144699,166.25322)
--
(100.168907,165.999039)
--
(100.749901,165.575394)
--
(102.771248,165.575394)
--
(104.084526,165.287933)
--
(104.526314,164.437637)
--
(103.691147,162.827805)
--
(104.526314,161.78688)
--
(104.381065,161.163528)
--
(103.763771,160.26178)
--
(104.502106,160.26178)
--
(104.526314,160.189163)
--
(104.078468,158.809311)
--
(103.909019,158.809311)
--
(103.957436,159.124008)
--
(103.328026,159.475021)
--
(100.834625,159.475021)
--
(100.296,159.338852)
--
(100.144699,158.78511)
--
(99.9994583,158.78511)
--
(97.8691635,166.455963)
--
(97.8691635,168.840424)
--
(98.03862,168.840424)
--
(98.1808395,168.126297)
--
(98.7769623,167.968948)
--
(100.326263,167.968948)
--
(99.902626,168.961472)
--
(100.631882,170.43512)
--
(102.432343,171.031235)
--
(103.933228,170.565231)
--
(104.526314,169.385101)
--
(103.739563,167.968948)
--
(104.502106,167.968948)
--
(104.526314,167.908432)
--
(104.017952,166.492264)
--
(103.860603,166.492264)
--
(103.872704,166.746445)
--
(103.766792,167.0672)
--
(103.315926,167.145874)
--
(98.7164383,167.145874)
--
(98.2020264,167.018784)
--
(98.03862,166.455963)
--
(97.8691635,166.455963)
--
(103.279617,167.968948)
--
(103.721405,168.298782)
--
(103.933228,168.973572)
--
(103.415779,169.854126)
--
(102.032913,170.18396)
--
(100.716614,169.854126)
--
(100.217323,168.997772)
--
(100.429146,168.310883)
--
(100.858833,167.968948)
--
(103.279617,167.968948)
--
(99.9994583,171.612228)
--
(99.9994583,173.936172)
--
(100.144699,173.936172)
--
(100.299026,173.330978)
--
(100.822517,173.19783)
--
(106.692917,173.19783)
--
(106.717125,173.161514)
--
(106.28138,171.588013)
--
(106.124031,171.588013)
--
(106.124031,171.648529)
--
(106.148239,171.963242)
--
(106.01812,172.287018)
--
(105.543045,172.374771)
--
(100.858833,172.374771)
--
(100.320206,172.223465)
--
(100.144699,171.612228)
--
(99.9994583,171.612228)
--
(101.609276,178.202805)
--
(100.813446,177.497742)
--
(100.580444,176.677704)
--
(101.367195,175.431)
--
(102.722832,175.140503)
--
(102.722832,178.166489)
--
(103.464195,178.02124)
--
(103.957436,177.742844)
--
(104.526314,176.484039)
--
(103.851524,174.99527)
--
(102.105537,174.426376)
--
(100.495712,174.922638)
--
(99.902626,176.266174)
--
(100.326263,177.512878)
--
(101.548752,178.360153)
--
(101.609276,178.202805)
--
(103.037537,175.164719)
--
(103.890862,175.494553)
--
(104.1632,176.205658)
--
(103.924149,176.859268)
--
(103.037537,177.161865)
--
(103.037537,175.164719)
--
(100.979874,179.858)
--
(100.423088,179.313339)
--
(99.8905182,179.845901)
--
(100.423088,180.402679)
--
(100.979874,179.858)
--
(104.526314,183.579956)
--
(103.884811,182.015533)
--
(102.22657,181.413361)
--
(100.562286,182.021576)
--
(99.902626,183.567856)
--
(100.589523,185.120178)
--
(102.299194,185.746552)
--
(103.89994,185.135315)
--
(104.526314,183.579956)
--
(104.247925,183.458923)
--
(103.609444,184.469589)
--
(101.960289,184.862976)
--
(100.65004,184.545242)
--
(100.181015,183.676788)
--
(100.810417,182.732681)
--
(102.698624,182.296951)
--
(103.827316,182.608627)
--
(104.247925,183.458923)
--
(99.9994583,186.170197)
--
(99.9994583,188.530457)
--
(100.144699,188.530457)
--
(100.320206,187.86171)
--
(100.883041,187.695282)
--
(103.098053,187.695282)
--
(103.615494,187.934341)
--
(103.896912,188.385208)
--
(103.751663,188.639389)
--
(103.558006,189.038818)
--
(104.005852,189.414047)
--
(104.526314,188.88147)
--
(104.329628,188.318634)
--
(103.594315,187.695282)
--
(104.502106,187.695282)
--
(104.526314,187.646866)
--
(103.993744,186.194397)
--
(103.836395,186.194397)
--
(103.872704,186.53331)
--
(103.279617,186.872223)
--
(100.822517,186.872223)
--
(100.347443,186.757233)
--
(100.144699,186.170197)
--
(99.9994583,186.170197)
--
(103.812187,194.074051)
--
(104.199509,194.074051)
--
(104.199509,193.323608)
--
(104.296341,192.778931)
--
(104.368965,192.561066)
--
(104.526314,191.774307)
--
(104.063339,190.60022)
--
(102.916496,190.128174)
--
(102.147896,190.33696)
--
(101.597168,191.048065)
--
(101.209846,190.624435)
--
(100.532028,190.16449)
--
(100.011559,190.684952)
--
(99.3579483,189.943588)
--
(98.8132706,189.728745)
--
(98.1354523,190.221985)
--
(97.8570633,191.423294)
--
(98.4864655,193.396225)
--
(99.5153,193.989319)
--
(100.259689,193.668564)
--
(100.568336,192.803131)
--
(100.62886,191.532227)
--
(100.895142,190.757584)
--
(101.249184,190.954269)
--
(101.512444,191.350662)
--
(101.488235,191.532227)
--
(101.464027,191.90744)
--
(101.851349,192.936279)
--
(102.98912,193.444641)
--
(103.812187,193.263092)
--
(103.812187,194.074051)
--
(99.9752502,190.902817)
--
(99.8542099,192.488434)
--
(99.7452698,193.435562)
--
(99.3700485,193.710922)
--
(98.68013,193.196518)
--
(98.4138412,191.846924)
--
(98.6105347,190.805984)
--
(99.1400757,190.418671)
--
(99.4547806,190.500366)
--
(99.9752502,190.902817)
--
(103.328026,190.951233)
--
(104.002823,191.141876)
--
(104.247925,191.677475)
--
(103.787979,192.391602)
--
(102.601791,192.694199)
--
(101.95121,192.497513)
--
(101.706108,191.955856)
--
(102.144875,191.226608)
--
(103.291718,190.951233)
--
(103.328026,190.951233)
;

\end{tikzpicture}}

bbb

\end{document}

A: Here's an even more "self-contained" way to do what David Carlisle suggested, made by following links from Can we extract the points making the character from the font file?  and playing with the code found there.  This compiled with pdflatex.

\immediate\write18{tex pgflibraryshapes.letters.dtx}
%\documentclass[border=10]{standalone}
\documentclass[landscape]{article}
\pagestyle{empty}
\thispagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{
  shapes.letters,
  decorations.pathmorphing,
  decorations.pathreplacing,
  decorations.text,
  decorations.footprints,
  fadings,
}

\pgfmathsetmacro{\emcm}{1em/1cm}
\pgfkeys{
  /pgf/letter/.cd,
%  load font={stikz}{italic},
  load font={stikz}{normal},
  size=1,
  load encoding=char,
  every letter/.append style={
    fill,
  },
  sentence width=.9\textwidth,
}

\begin{document}
\begin{tikzpicture}[every letter/.append style={path fading=west},scale=.1]
\node[letter=h] (1) {};
\node[letter=o,right of previous letter,at=(1.east)] (2) {};
\node[letter=l,right of previous letter,at=(2.east)] (3) {};
\node[letter=t,right of previous letter,at=(3.east)] (4) {};
\node[letter=z,right of previous letter,at=(4.east)] (5) {};
\node[letter=e,right of previous letter,at=(5.east)] (6) {};
\node[letter=r,right of previous letter,at=(6.east)] (7) {};
\node[letter=m,right of previous letter,at=(7.east)] (8) {};
\node[letter=a,right of previous letter,at=(8.east)] (9) {};
\node[letter=n,right of previous letter,at=(9.east)] (10) {};
\node[letter=n,right of previous letter,at=(10.east)] (11) {};
\node[letter=1,right of previous letter,at=(11.east)] (12) {};
\node[letter=7,right of previous letter,at=(12.east)] (13) {};
\node[letter=@,right of previous letter,at=(13.east)] (14) {};
\node[letter=g,right of previous letter,at=(14.east)] (15) {};
\node[letter=m,right of previous letter,at=(15.east)] (16) {};
\node[letter=a,right of previous letter,at=(16.east)] (17) {};
\node[letter=i,right of previous letter,at=(17.east)] (18) {};
\node[letter=l,right of previous letter,at=(18.east)] (19) {};
\node[letter=.,right of previous letter,at=(19.east)] (20) {};
\node[letter=c,right of previous letter,at=(20.east)] (21) {};
\node[letter=o,right of previous letter,at=(21.east)] (22) {};
\node[letter=m,right of previous letter,at=(22.east)] (23) {};
\node[above=23] (joe) {Hi, I'm Joe};
\node[below=23] (joe) {Corneli, Phd};
\end{tikzpicture}

\end{document}