I'd like to use a set of thrust operations to selectively copy the elements of one vector A into a new vector B based on a predicate on elements in a third vector C.
Here's an example case: I want to copy elements (in order) from A when the corresponding element in B is 1 to C and don't if it is 0. I want |C| < |A| if there are 0s in B. We can pre-determine the size of C by a reduction on B. e.g:
A = [2, 3, 6, 0, 11]
B = [1, 0, 1, 1, 0]
C = [2, 6, 0]
Any help is greatly appreciated
This algorithm is known as stream compaction. It is implemented in thrust::copy_if.
The following example is taken from the Thrust documentation.
#include <thrust/copy.h>
...
struct is_even
{
__host__ __device__
bool operator()(const int x)
{
return (x % 2) == 0;
}
};
...
int N = 6;
int data[N] = { 0, 1, 2, 3, 4, 5};
int stencil[N] = {-2, 0, -1, 0, 1, 2};
int result[4];
thrust::copy_if(data, data + N, stencil, result, is_even());
// data remains = { 0, 1, 2, 3, 4, 5};
// stencil remains = {-2, 0, -1, 0, 1, 2};
// result is now { 0, 1, 3, 5}
Although Abator had given the right function to use. Let me try a complete example.
//~~~START:Wed, 06-Oct-2021, 21:41:22 IST
//~~~Author:Rajesh Pandian M | mrprajesh.co.in
//~~CompiledWith: nvcc a.cu -std=c++14 --expt-extended-lambda
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/copy.h>
#include <stdio.h>
int main(void) {
const int N=5;
int A[]={2, 3, 6, 0, 11}; //Data
int B[]={1, 0, 1, 1, 0 }; //Stencil
thrust::device_vector<int> dA(A, A + N);
thrust::device_vector<int> dB(B, B + N);
// Allocates memory based on #number of 1's
thrust::device_vector<int> dC(thrust::count(B, B+N,1));
//Condition on the stencil elements. If 1 is seen copy, else do not!
thrust::copy_if( dA.begin()
,dA.end()
,dB.begin()
,dC.begin()
,[] __host__ __device__ (const int& x){
return 1 == x;
});
//Prints
thrust::for_each(dC.begin(), dC.end(),
[] __host__ __device__(const int& x){ printf("%d ",x);});
return 0;
}
I am looking to dynamically insert a spectrum input field to have a more customized color picker in my template. The issue I've encountered is that the object I want to bind data to is null from inside of spectrum functions. I'm wondering what the best way to go about integrating spectrum into a polymer template is.
As you will see, when editMode is initiated, spectrum is instantiated and the div is inserted into the HTML. On change(), I want to take whatever color is selected and bind it to the document object. My console.log returns that the document is indeed null. Inside of the editMode function, before going into spectrum, document is a polymer object as expected. I tried making document a global var but that doesn't make a difference because it's no longer the binded object so I can't access any of its properties, save it, etc.
Does spectrum need to be a custom element? Any insight?
<script>
Polymer({
is: 'image-view',
behaviors: [Test.LayoutBehavior],
properties: {
/**
* #doctype Image
*/
document: {
type: Object,
observer: '_documentChanged'
},
edit: {
type: Boolean,
value: false
}
},
_canEdit: function(doc) {
return doc && doc.type !== 'Root' && this.hasPermission(doc, 'Write');
},
_editMode: function() {
this.edit = true;
$(".spectrum-div").html(
"<label>Brand Text Color</label><input type='text' id='full'/>"
);
$("#full").spectrum({
color: "#ECC",
showInput: true,
className: "full-spectrum",
showInitial: true,
showPalette: true,
showSelectionPalette: true,
maxSelectionSize: 10,
preferredFormat: "hex",
move: function (color) {
},
show: function () {
},
beforeShow: function () {
},
hide: function () {
},
change: function(color) {
if (this.document != null) {
console.log('THIS DOCUMENT IS NOT NULL');
console.log(this.document.properties["image:brand_text_color"]);
} else console.log('Sorry, document is null.');
var col = color.toHexString();
//$("#brand-text-color").val(col);
//document.getElementById("brand-text-color").value = col;
this.document.properties["image:brand_text_color"] = col;
},
palette: [
["rgb(0, 0, 0)", "rgb(67, 67, 67)", "rgb(102, 102, 102)",
"rgb(204, 204, 204)", "rgb(217, 217, 217)","rgb(255, 255, 255)"],
["rgb(152, 0, 0)", "rgb(255, 0, 0)", "rgb(255, 153, 0)", "rgb(255, 255, 0)", "rgb(0, 255, 0)",
"rgb(0, 255, 255)", "rgb(74, 134, 232)", "rgb(0, 0, 255)", "rgb(153, 0, 255)", "rgb(255, 0, 255)"],
["rgb(230, 184, 175)", "rgb(244, 204, 204)", "rgb(252, 229, 205)", "rgb(255, 242, 204)", "rgb(217, 234, 211)",
"rgb(208, 224, 227)", "rgb(201, 218, 248)", "rgb(207, 226, 243)", "rgb(217, 210, 233)", "rgb(234, 209, 220)",
"rgb(221, 126, 107)", "rgb(234, 153, 153)", "rgb(249, 203, 156)", "rgb(255, 229, 153)", "rgb(182, 215, 168)",
"rgb(162, 196, 201)", "rgb(164, 194, 244)", "rgb(159, 197, 232)", "rgb(180, 167, 214)", "rgb(213, 166, 189)",
"rgb(204, 65, 37)", "rgb(224, 102, 102)", "rgb(246, 178, 107)", "rgb(255, 217, 102)", "rgb(147, 196, 125)",
"rgb(118, 165, 175)", "rgb(109, 158, 235)", "rgb(111, 168, 220)", "rgb(142, 124, 195)", "rgb(194, 123, 160)",
"rgb(166, 28, 0)", "rgb(204, 0, 0)", "rgb(230, 145, 56)", "rgb(241, 194, 50)", "rgb(106, 168, 79)",
"rgb(69, 129, 142)", "rgb(60, 120, 216)", "rgb(61, 133, 198)", "rgb(103, 78, 167)", "rgb(166, 77, 121)",
"rgb(91, 15, 0)", "rgb(102, 0, 0)", "rgb(120, 63, 4)", "rgb(127, 96, 0)", "rgb(39, 78, 19)",
"rgb(12, 52, 61)", "rgb(28, 69, 135)", "rgb(7, 55, 99)", "rgb(32, 18, 77)", "rgb(76, 17, 48)"]
]
});
},
_documentChanged: function() {
if (this.document) {
this.edit = false;
}
},
_isAdmin: function(user) {
return user.isAdministrator;
}
});
</script>
First you can place the input field into your element's local DOM, and hide it when not in edit mode:
<label hidden$="[[!edit]]" for="full">Brand Text Color</label>
<iron-input bind-value="{{document.prop}}">
<input hidden$="[[!edit]]" type="text" id="full"/>
</iron-input>
(Note that I also added an iron-input, since you will need value-binding below.)
That way you can access it from JavaScript by id, via this.$.full.
Finally, you can initialize spectrum from Polymer's attached callback:
Polymer({
properties: {
document: {
type: Object,
// initialize with an object holding all required keys,
// for proper change notification
value: function() {
return {
// document properties here
prop: null
};
},
observer: '_syncDocument'
},
...
},
...
attached() {
$(this.$.full).spectrum({
...
});
},
_syncDocument(newValue) {
// window.document[???] = newValue.prop;
}
...
});
Now I'm not sure what you're trying to achieve with the document. Is it the window.document? In that case you'd need to sync your element.document.value to window.document.[propertyName] manually, in an observer on your element.document.
PS: Don't forget to include iron-input, or work around my quick implementation with something else.