I'm a bit confused on the best way to do the following:
Say I have the following sorted key value pairs
(K:V) (0 : .5)(0 : .7)(0 : .9) (1 : .2) (1 : .6) (1 : .8)
and so on..
I want to remove copy the minimum value of each key so I'll have 2 results
minimum by key
(0 : .5)(1 : .2)
remaining
(0 : .7)(0 : .9)(1 : .6)(1 : .8)
thrust::unique_by_key_copy would appear to be able to give me the minimum by key since (K:V) is sorted. However I'm not sure how to remove those that are chosen from original to get the remaining.
Any thoughts or advice greatly appreciated
I'm sure there are a number of ways to do this.
One possible approach is to use thrust::adjacent_difference to create a "flag array".
Then use thrust::copy_if (the stencil version) using the flag array (as the stencil) to select first the elements you want in result 1, then the elements you want in result 2 (using the inverse of the flag array, logically).
Here's a worked example:
$ cat t671.cu
#include <thrust/copy.h>
#include <thrust/adjacent_difference.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/iterator/zip_iterator.h>
#include <iostream>
struct is_zero
{
__host__ __device__
bool operator()(const int s_val) const {
return (!s_val);}
};
struct is_not_zero
{
__host__ __device__
bool operator()(const int s_val) const {
return (s_val);}
};
int main(){
int keys[] = {0, 0, 0, 1, 1, 1 };
float vals[] = {0.5f, 0.7f, 0.9f, 0.2f, 0.6f, 0.8f };
int my_size = sizeof(keys)/sizeof(keys[0]);
thrust::host_vector<int> h_keys(keys, keys+my_size);
thrust::host_vector<float> h_vals(vals, vals+my_size);
thrust::device_vector<int> d_keys = h_keys;
thrust::device_vector<float> d_vals = h_vals;
thrust::device_vector<int> flags(my_size);
thrust::device_vector<int> d_keys1(my_size);
thrust::device_vector<float> d_vals1(my_size);
thrust::device_vector<int> d_keys2(my_size);
thrust::device_vector<float> d_vals2(my_size);
thrust::adjacent_difference(d_keys.begin(), d_keys.end(), flags.begin());
flags[0] = 1; // first element is always included
int len1 = thrust::copy_if(thrust::make_zip_iterator(thrust::make_tuple(d_keys.begin(), d_vals.begin())), thrust::make_zip_iterator(thrust::make_tuple(d_keys.end(), d_vals.end())), flags.begin(), thrust::make_zip_iterator(thrust::make_tuple(d_keys1.begin(), d_vals1.begin())), is_zero()) - thrust::make_zip_iterator(thrust::make_tuple(d_keys1.begin(), d_vals1.begin()));
int len2 = thrust::copy_if(thrust::make_zip_iterator(thrust::make_tuple(d_keys.begin(), d_vals.begin())), thrust::make_zip_iterator(thrust::make_tuple(d_keys.end(), d_vals.end())), flags.begin(), thrust::make_zip_iterator(thrust::make_tuple(d_keys2.begin(), d_vals2.begin())), is_not_zero()) - thrust::make_zip_iterator(thrust::make_tuple(d_keys2.begin(), d_vals2.begin()));
thrust::host_vector<int> h_keys1(len1);
thrust::host_vector<float> h_vals1(len1);
thrust::copy_n(d_keys1.begin(), len1, h_keys1.begin());
thrust::copy_n(d_vals1.begin(), len1, h_vals1.begin());
thrust::host_vector<int> h_keys2(len2);
thrust::host_vector<float> h_vals2(len2);
thrust::copy_n(d_keys2.begin(), len2, h_keys2.begin());
thrust::copy_n(d_vals2.begin(), len2, h_vals2.begin());
std::cout << std::endl << "Input keys:" << std::endl;
thrust::copy(h_keys.begin(), h_keys.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl << "Input values:" << std::endl;
thrust::copy(h_vals.begin(), h_vals.end(), std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl << "Output keys 1:" << std::endl;
thrust::copy(h_keys1.begin(), h_keys1.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl << "Output values 1:" << std::endl;
thrust::copy(h_vals1.begin(), h_vals1.end(), std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl << "Output keys 2:" << std::endl;
thrust::copy(h_keys2.begin(), h_keys2.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl << "Output values 2:" << std::endl;
thrust::copy(h_vals2.begin(), h_vals2.end(), std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl;
return 0;
}
$ nvcc -arch=sm_20 -o t671 t671.cu
$ ./t671
Input keys:
0,0,0,1,1,1,
Input values:
0.5,0.7,0.9,0.2,0.6,0.8,
Output keys 1:
0,0,1,1,
Output values 1:
0.7,0.9,0.6,0.8,
Output keys 2:
0,1,
Output values 2:
0.5,0.2,
$
Related
here is the json I want to parse:
{"jsonrpc":"2.0","method":"subscription","params":{"channel":"book.BTC-PERPETUAL.raw","data":{"type":"change","timestamp":1635513739435,"prev_change_id":6807100702,"instrument_name":"BTC-PERPETUAL","change_id":6807100703,"bids":[["new",60772.0,50.0], "demo"],"asks":[]}}}
and here is my code to get the values from a child:
boost::property_tree::ptree pt;
boost::property_tree::read_json(ss, pt);
std::cout << "\njsonrpc: " << pt.get<std::string>("jsonrpc") << std::endl;
std::cout << "\nmethod: " << pt.get<std::string>("method") << std::endl;
std::cout << "\nparams: " << pt.get<std::string>("params") << std::endl;
std::cout << "\nparams.channel: " << pt.get<std::string>("params.channel") << std::endl;
std::cout << "\nparams.data: " << pt.get<std::string>("params.data") << std::endl;
std::cout << "\nparams.data.timestamp: " << pt.get<std::string>("params.data.timestamp") << std::endl;
std::cout << "\nparams.data.instrument_name: " << pt.get<std::string>("params.data.instrument_name") << std::endl;
but when I tried to parse the array values like ("params.data.bids") it return nothing
I need help in parsing an array
You should use a JSON Library:
Live On Compiler Explorer
#include <boost/json.hpp>
#include <boost/json/src.hpp> // header-only for Compiler Explorer
#include <iostream>
namespace json = boost::json;
int main() {
auto req = json::parse(R"({
"jsonrpc": "2.0",
"method": "subscription",
"params": {
"channel": "book.BTC-PERPETUAL.raw",
"data": {
"type": "change",
"timestamp": 1635513739435,
"prev_change_id": 6807100702,
"instrument_name": "BTC-PERPETUAL",
"change_id": 6807100703,
"bids": [
["new", 60772.0, 50.0], "demo"],
"asks": []
}
}
})") .as_object();
auto& params = req["params"].as_object();
auto& data = params["data"].as_object();
std::cout << "jsonrpc: " << req["jsonrpc"].as_string() << "\n";
std::cout << "methdo: " << req["method"].as_string() << "\n";
std::cout << "params.channel: " << params["channel"].as_string() << "\n";
std::cout << "params.data: " << params["data"] << "\n";
std::cout << "params.data.timestamp: " << data["timestamp"] << "\n";
std::cout << "params.data.instrument_name: " << data["instrument_name"] << "\n";
}
Prints
jsonrpc: "2.0"
methdo: "subscription"
params.channel: "book.BTC-PERPETUAL.raw"
params.data: {"type":"change","timestamp":1635513739435,"prev_change_id":6807100702,"instrument_name":"BTC-PERPETUAL","change_id":6807100703,"bids":[["new",6.0772E4,5E1],"demo"],"asks":[]}
params.data.timestamp: 1635513739435
params.data.instrument_name: "BTC-PERPETUAL"
bid: ["new",6.0772E4,5E1]
bid: "demo"
Adding the asks/bids:
for (auto& bid : data["bids"].as_array()) {
std::cout << "bid: " << bid << "\n";
}
for (auto& ask : data["asks"].as_array()) {
std::cout << "ask: " << ask << "\n";
}
Prints
bid: ["new",6.0772E4,5E1]
bid: "demo"
Alternative / Bonus
You can also use value_to conversion to your own types:
struct request {
std::string jsonrpc, method;
struct params_t {
std::string channel;
struct data_t {
std::string type;
size_t timestamp, prev_change_id, change_id;
std::string instrument_name;
std::vector<json::value> bids, asks;
} data;
} params;
};
See it Live
Or flattened:
struct request {
using values = std::vector<json::value>;
std::string jsonrpc, method, channel, type, instrument_name;
size_t timestamp, prev_change_id, change_id;
values bids, asks;
friend request tag_invoke(json::value_to_tag<request>, json::value const& v)
{
auto& params = v.at("params");
auto& data = params.at("data");
return request{
value_to<std::string>(v.at("jsonrpc")),
value_to<std::string>(v.at("method")),
value_to<std::string>(params.at("channel")),
value_to<std::string>(data.at("type")),
value_to<std::string>(data.at("instrument_name")),
value_to<size_t>(data.at("timestamp")),
value_to<size_t>(data.at("prev_change_id")),
value_to<size_t>(data.at("change_id")),
value_to<values>(data.at("bids")),
value_to<values>(data.at("asks")),
};
}
};
See it Live As Well
#include <boost/json.hpp>
#include <boost/json/src.hpp> // header-only for Compiler Explorer
#include <iostream>
namespace json = boost::json;
struct request {
using values = std::vector<json::value>;
std::string jsonrpc, method, channel, type, instrument_name;
size_t timestamp, prev_change_id, change_id;
values bids, asks;
friend request tag_invoke(json::value_to_tag<request>, json::value const& v)
{
auto& params = v.at("params");
auto& data = params.at("data");
return request{
value_to<std::string>(v.at("jsonrpc")),
value_to<std::string>(v.at("method")),
value_to<std::string>(params.at("channel")),
value_to<std::string>(data.at("type")),
value_to<std::string>(data.at("instrument_name")),
value_to<size_t>(data.at("timestamp")),
value_to<size_t>(data.at("prev_change_id")),
value_to<size_t>(data.at("change_id")),
value_to<values>(data.at("bids")),
value_to<values>(data.at("asks")),
};
}
};
int main() {
auto req = value_to<request>(json::parse(R"({
"jsonrpc": "2.0",
"method": "subscription",
"params": {
"channel": "book.BTC-PERPETUAL.raw",
"data": {
"type": "change",
"timestamp": 1635513739435,
"prev_change_id": 6807100702,
"instrument_name": "BTC-PERPETUAL",
"change_id": 6807100703,
"bids": [
["new", 60772.0, 50.0], "demo"],
"asks": []
}
}
})"));
std::cout << "jsonrpc: " << req.jsonrpc << "\n";
std::cout << "methdo: " << req.method << "\n";
std::cout << "params.channel: " << req.channel << "\n";
std::cout << "data.timestamp: " << req.timestamp << "\n";
std::cout << "data.instrument_name: " << req.instrument_name << "\n";
for (auto& bid : req.bids) std::cout << "bid: " << bid << "\n";
for (auto& ask : req.asks) std::cout << "ask: " << ask << "\n";
}
I am referring to sample code on Crypto++ wiki at CCM Mode. I have done few modifications for testing purposes and now it is throwing:
terminate called after throwing an instance of 'HashVerificationFilter::HashVerificationFailed'
what(): HashVerificationFilter: message hash or MAC not valid
Aborted (core dumped)
I have seen 'message hash or MAC not valid' exception after decryption. But I would like to pass byte array instead of string, so I think I have to use sizeof() operator instead of size(). The code is below.
When pass key and iv, sizeof function is giving their sizes as 8 instead 16 bytes.
Is the error because of AuthenticatedDecryptionFilter::DEFAULT_FLAGS?
Here is the code:
#include <iostream>
#include <cstdio>
//#include "libcryptoWrapperGCM.h"
using std::cout;
using std::endl;
using std::cerr;
#include <string>
#include <stdint.h>
using std::string;
#include "hex.h"
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
#include "osrng.h"
using CryptoPP::AutoSeededRandomPool;
#include "cryptlib.h"
using CryptoPP::BufferedTransformation;
using CryptoPP::AuthenticatedSymmetricCipher;
#include "filters.h"
using CryptoPP::Redirector;
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::AuthenticatedDecryptionFilter;
#include "aes.h"
using CryptoPP::AES;
#include "gcm.h"
using CryptoPP::GCM;
#include "assert.h"
void GCM_Encode(byte key[], byte iv[], string pdata, string cipher, const int TAG_SIZE)
{
// Encrypted, with Tag
string encoded;
cout << "key size= " << sizeof(key) << endl;
cout << "IV size= " << sizeof(iv) << endl;
/*********************************\
\*********************************/
try
{
GCM< AES >::Encryption e;
e.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
StringSource ss1( pdata, true,
new AuthenticatedEncryptionFilter( e,
new StringSink( cipher ), false, TAG_SIZE
) // AuthenticatedEncryptionFilter
); // StringSource
cout << "Encoded value: " << cipher << endl;
}
catch( CryptoPP::Exception& e )
{
cerr << e.what() << endl;
exit(1);
}
}
/*********************************\
\*********************************/
void GCM_Decode(byte key[], byte iv[], string cipher, string rpdata, const int TAG_SIZE)
{
try
{
GCM< AES >::Decryption d;
d.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
AuthenticatedDecryptionFilter df( d,
new StringSink( rpdata ),
AuthenticatedDecryptionFilter::DEFAULT_FLAGS, TAG_SIZE
); // AuthenticatedDecryptionFilter
// The StringSource dtor will be called immediately
// after construction below. This will cause the
// destruction of objects it owns. To stop the
// behavior so we can get the decoding result from
// the DecryptionFilter, we must use a redirector
// or manually Put(...) into the filter without
// using a StringSource.
StringSource ss2( cipher, true,
new Redirector( df /*, PASS_EVERYTHING */ )
); // StringSource
// If the object does not throw, here's the only
// opportunity to check the data's integrity
if( true == df.GetLastResult() ) {
cout << "recovered text: " << rpdata << endl;
}
}
catch( CryptoPP::Exception& e )
{
cerr << e.what() << endl;
exit(1);
}
}
int main()
{
byte key[]= {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
byte iv[] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f};
string pdata = "Authenticated Encryption";
const int TAG_SIZE = 12;
string rpdata, cipher;
//void GCM_Encode(byte key[], byte iv[], string pdata, string cipher, const int TAG_SIZE)
GCM_Encode( key, iv, pdata, cipher, TAG_SIZE);
cout << "======INT MAIN======" << endl;
cout << "Encryption complete" << endl;
cout << "cipher= " << cipher << endl;
//void GCM_Decode(byte key[], byte iv[], string cipher, string rpdata, const int TAG_SIZE)
GCM_Decode( key, iv, cipher, rpdata, TAG_SIZE);
cout << "Decryption complete" << endl;
cout << "rpdata= " << rpdata << endl;
return 0;
}
GDB output is,
Encryption complete
cipher=
HashVerificationFilter: message hash or MAC not valid
[Inferior 1 (process 16632) exited with code 01]
Compilation command
g++ -g3 -O3 -fPIC GCM_Test2.cpp -o GCMTest3 -lcryptopp -pthread -lrt -lc
Include path added using,
export CPLUS_INCLUDE_PATH=/usr/local/include/cryptopp
No output on locate raise.c
Problem is that both functions GCM_Encode were interpreting wrong size of key and iv.
cout << "sizeof(key)= " << sizeof(key) << endl;
cout << "sizeof(iv)= " << sizeof(iv) << endl;
is 8 and not 16. So idea is to convert it to string and get its size using .size()
std::string key1( reinterpret_cast<char const*>(key), sizeof(key) )
std::string iv1( reinterpret_cast<char const*>(iv), sizeof(iv) )
But remember to provide original byte array to SetKeyWithIV function as it does not accept string as its argument.
e.SetKeyWithIV( key, key1.size(), iv, iv1.size() )
I have a JSON string, in which value is actually a string, but I need to access it like JSON array. {"data" : "[A,B,C]"}.
Is there any way to parse VALUE as Indexed array using RapidJSON so that I get a document like: {"0" : "A", "1" : "B", "2" : "C"}
RapidJSON Should be fully in compliance With RFC7159 / ECMA-404.
No there is no way, you need to do it manually.
For example using regex:
#include <iostream>
#include <iterator>
#include <string>
#include <regex>
static std::regex value_regex("[\\s]*([\\w\\s]+),?", std::regex::optimize);
std::string parse(const std::string& value) {
if (value.at(0) != '[' || value.at(value.size() - 1) != ']') {
throw std::invalid_argument("Error in Parse [must start with '[' and end with ']']: " + value);
}
std::string result("{");
std::sregex_iterator next(++value.begin(), --value.end(), value_regex, std::regex_constants::match_continuous);
std::sregex_iterator end;
size_t len = 0, cont = 0;
while (next != end) {
if (cont) {
result.append(", \"").append(std::to_string(cont)).append("\":\"").append(next->str(1)).append(1, '\"');
} else {
result.append(1, '\"').append(std::to_string(cont)).append("\":\"").append(next->str(1)).append(1, '\"');
}
len += next->length(0);
++next;
++cont;
}
if (len != value.size() - 2) {
throw std::invalid_argument("Error in Parse [" + std::to_string(len) + "]: " + value);
}
result.append(1, '}');
return result;
}
int main() {
// Tests
try {
std::string value("[A,B,C,D,E]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[ A, B X, Z]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[A,BaaayyX, Z]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[A,B,C,]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
// Errors
try {
std::string value("A,B,C");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("A,B,C]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[A,B,C");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[,A,B,C]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::exception& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::exception& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::exception& err) {
std::cout << err.what() << std::endl;
}
}
Output:
[A,B,C,D,E] -> {"0":"A", "1":"B", "2":"C", "3":"D", "4":"E"}
[ A, B X, Z] -> {"0":"A", "1":"B X", "2":"Z"}
[A,BaaayyX, Z] -> {"0":"A", "1":"BaaayyX", "2":"Z"}
[A,B,C,] -> {"0":"A", "1":"B", "2":"C"}
[] -> {}
A,B,C -> Error in Parse [must start with '[' and end with ']']: A,B,C
A,B,C] -> Error in Parse [must start with '[' and end with ']']: A,B,C]
[A,B,C -> Error in Parse [must start with '[' and end with ']']: [A,B,C
[,A,B,C] -> Error in Parse [0]: [,A,B,C]
-> basic_string
[ -> Error in Parse [must start with '[' and end with ']']: [
] -> Error in Parse [must start with '[' and end with ']']: ]
You can customize your regex to become more flexible or more strict.
I have noticed that whenever I use dark background images for tesseract I am getting a segmentation fault. I was trying to extract symbols using this code
#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>
#include <iostream>
#include <map>
#include <bits/stdc++.h>
using namespace std;
int main()
{
char *outText;
map<pair<char*,char*>,float> matrix;
set<char> allChars;
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
// Initialize tesseract-ocr with English, without specifying tessdata path
if (api->Init(NULL, "eng")) {
fprintf(stderr, "Could not initialize tesseract.\n");
exit(1);
}
int a[256][256];
for(int i=0;i<256;i++){
for(int j=0;j<256;j++){
a[i][j]=0;
}
}
// Open input image with leptonica library
string images[] = {List of images};
for (int ii=0;ii<7;ii++){
Pix *image = pixRead((const char*) images[ii].c_str());
cout << images[ii] << endl;
api->Init(NULL, "eng");
api->SetImage(image);
string valid_set = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890~`!##$%^&*()_-+=,./<>/:;'[]{}|";
api->SetVariable("tessedit_char_whitelist", valid_set.c_str());
api->SetVariable("save_blob_choices", "T");
//api->SetRectangle(37, 128,648, 523);
//api->SetRectangle(30, 86, 590, 100);
//api->SetRectangle(30,100,430,30);
api->Recognize(NULL);
tesseract::ResultIterator* ri = api->GetIterator();
tesseract::PageIteratorLevel level = tesseract::RIL_SYMBOL;
if(ri != 0) {
do {
const char* symbol = ri->GetUTF8Text(level);
//cout << symbol << endl;
if(ri!=0){
float conf = ri->Confidence(level);
}
//cout << "err" << endl;
if(symbol != 0) {
//printf("symbol %s, conf: %f", symbol, conf);
bool indent = false;
tesseract::ChoiceIterator ci(*ri);
do {
const char* choice = ci.GetUTF8Text();
if (indent) //printf("\t\t ");
// printf("\t- ");
//cout << symbol<<" Look up "<<choice << endl;
matrix[make_pair(strdup(symbol), strdup(choice))]=ci.Confidence();
//printf("%s conf: %f\n", choice, ci.Confidence());
indent = true;
} while(ci.Next());
}
//printf("---------------------------------------------\n");
delete[] symbol;
} while((ri->Next(level)));
}
int count = 0;
for(map<pair<char*,char*>,float>::iterator it = matrix.begin();it!=matrix.end();it++){
allChars.insert((strdup)(it->first.first)[0]);
allChars.insert((strdup)(it->first.second)[0]);
//cout<<it->first.first<<" "<<it->first.second<<endl;
//cout << (strdup)(it->first.first)[0]<<" "<<(strdup)(it->first.second)[0]<<endl;
a[(strdup)(it->first.first)[0]][(strdup)(it->first.second)[0]]+=it->second;
count++;
}
// cout << count << endl;
for(set<char>::iterator it = allChars.begin();it!=allChars.end();it++){
//cout << *it << endl;
}
for(int i=0;i<256;i++){
for(int j=0;j<256;j++){
if(a[i][j]!=0){
///cout << i << " " <<j<<endl;
//cout << a[i][j]<<endl;
}
//cout << a[i][j] << endl;
}
}
api->End();
pixDestroy(&image);
}
return 0;
}`
Specifically in the code where
float conf = ri->Confidence(level);
So what can be the solution to this problem? Should we train with more dark images?
Edit:
Sample Image
I have a custom class myClass which has members weight and config. I'd like to run an inclusive scan on a bunch of myClasses, but only on the weights. Basically what I want is to take:
[ {configA, weightA}, {configB, weightB}, {configC, weightC}, ...]
to:
[ {configA, weightA}, {configB, weight A + weightB}, {configC, weight A + weight B + weightC}, ...]
Is there a simple way to do this using Thrust's fancy iterators? Since the binaryOp is required to be associative, I don't see how to do this with just overloading operator+.
inclusive_scan requires an associative operator, but it needn't be commutative. If you create a binary function which copies the config member of its second parameter to the result, it should work out:
#include <iostream>
#include <thrust/device_vector.h>
#include <thrust/scan.h>
struct my_struct
{
__host__ __device__
my_struct() {}
__host__ __device__
my_struct(const my_struct &other)
: config(other.config), weight(other.weight)
{}
__host__ __device__
my_struct(char c, double w)
: config(c), weight(w)
{}
char config;
double weight;
};
struct functor
{
__host__ __device__
my_struct operator()(my_struct a, my_struct b)
{
my_struct result;
result.config = b.config;
result.weight = a.weight + b.weight;
return result;
}
};
int main()
{
thrust::device_vector<my_struct> vec(3);
vec[0] = my_struct('a', 1);
vec[1] = my_struct('b', 2);
vec[2] = my_struct('c', 3);
std::cout << "input: ";
for(int i = 0; i < vec.size(); ++i)
{
my_struct x = vec[i];
std::cout << "{" << x.config << ", " << x.weight << "} ";
}
std::cout << std::endl;
thrust::inclusive_scan(vec.begin(), vec.end(), vec.begin(), functor());
std::cout << "result: ";
for(int i = 0; i < vec.size(); ++i)
{
my_struct x = vec[i];
std::cout << "{" << x.config << ", " << x.weight << "} ";
}
std::cout << std::endl;
return 0;
}
The output:
$ nvcc -arch=sm_20 test.cu -run
input: {a, 1} {b, 2} {c, 3}
result: {a, 1} {b, 3} {c, 6}