I'm trying to create a Node.js C++ Addon that generates the Fibonacci sequence to compare its speed with a normal Node.js module, but I'm having trouble setting a certain index of an array. I've got this so far:
#include <node.h>
namespace demo {
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::Value;
using v8::Number;
using v8::Array;
void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
int next, first = 0, second = 0, c = 0, n = args[0]->NumberValue();
Local<Array> arr = Array::New(isolate, n);
for (; c < n; c++) {
if ( c <= 1 ) next = c;
else {
next = first + second;
first = second;
second = next;
}
// How to set arr[c]?????
}
args.GetReturnValue().Set(arr);
}
void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "fib", Method);
}
NODE_MODULE(addon, init)
}
On line 26, how should I set arr[c]? v8:Array doesn't provide a subscript operator.
how should I set arr[c]? v8:Array doesn't provide a subscript operator.
It doesn't, but v8::Array already inherits the function member Set from v8::Object, with an overload that takes an integer (uint32_t) for the key. Use it to populate each element of the array:
void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
int next, first = 0, second = 0, c = 0, n = args[0]->NumberValue();
Local<Array> arr = Array::New(isolate, n);
int i = 0;
for (; c < n; c++) {
if ( c <= 1 ) next = c;
else {
next = first + second;
first = second;
second = next;
}
arr->Set(i++, Number::New(isolate, next));
}
args.GetReturnValue().Set(arr);
}
Related
So, the issue essentially is in findEl function. when I call it, it doesnt actually return the node i asked for.
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
struct gameElements {
char element[50];
char power[50];
int coordinates[2][2];
int pcoordinates[3][2];
gameElements *next;
};
using p_elements = gameElements*;
p_elements test(p_elements &p, char element[50], int parr[3][2], int x, int y) {
p_elements newEl = new gameElements;
strcpy(newEl->element, element);
newEl->coordinates[0][0] = y;
newEl->coordinates[0][1] = x;
newEl->coordinates[1][0] = y;
newEl->coordinates[1][1] = x + 1;
newEl->next = NULL;
for (int n = 0; n < 3; n++) {
for (int i = 0; i < 2; i++) {
newEl->pcoordinates[n][i] = parr[n][i];
}
}
if (p == NULL) {
p = newEl;
} else {
p_elements tmp = p;
while (tmp->next != NULL) {
tmp = tmp->next;
}
tmp->next = newEl;
}
return p;
}
p_elements findEl(p_elements &p,char element[50]){
p_elements x=p;
if(x==NULL){
return NULL;
}else if(strcmp(x->element,element)==0){
return x;
}else{
while(x!=NULL){
if(strcmp(x->element,element)==0){
return x;
}else x = x->next;
}return NULL;
}
}
int main() {
p_elements elements = new gameElements;
elements=NULL;
char p[50] = "Power";
char a[50] = "Artifact";
int doorTonlvl[3][2] = { { 5, 96 }, { 6, 96 }, { 7, 96 } };
int vDoor[3][2] = { { 11, 54 }, { 12, 54 }, { 13, 54 } };
elements = test(elements, a, doorTonlvl, 4, 3);
elements = test(elements, p, vDoor, 57, 8);
p_elements artifact = findEl(elements, a);
cout << artifact->element << endl;
return 0;
}
This current code return nothing when I'm trying to find "char a[50]", while if i try to find "char p[50]" it returns a.
ps: I'm forced to use string.h library due to assignment
EDIT:
added includes.
Current code return nothing(the program gets executed without printing anything in the terminal). Expected artifact->element which in this case is "char a"
I think the issue could be in test(..) function, in this case my linked list has only 2 nodes. when I try find the first node by using findEl() it doesnt print anything in the terminal, but instead of if i to try find second node by using same function and just swapping parameter findEl(elements,a) to findEl(elements,p) it prints out first node (a) rather than second, which is what i was looking for in this case)
Apparently the issue was in the while loop in findEl(..), it was checking if the next node was null, therefore exist whlie loop if true
This is my python function:
if __name__ == "__main__":
file = open("data_input.txt", "r")
contents = file.read()
e = ast.literal_eval(contents)
neighbour_num= 4
new_data = 300
result = np.ndarray((4,4),dtype='int32',buffer=np.zeros((4,4),dtype='int32'))
c_module.mmult_wrapper(e, new_data, neighbour_num, result)
This is my C++ function, where i want to use dict as array
void mmult(double new_data, double neighbour_num, double e[100], int32_t result[16]) {
double distances[100];
unsigned distances_front = 0;
unsigned distances_back = 0;
double keys[100];
unsigned keys_front = 0;
unsigned keys_back = 0;
for(int i=0;i<(int)100; i=i+1) {
double temp_distance=(new_data-e[i]);
double sq_tmp=(temp_distance*temp_distance);
double sqrt=(sq_tmp/2);
double temp=0;
while(sqrt!=temp) {
temp = sqrt;
sqrt = (((sq_tmp/temp)+temp)/2);
}
distances[distances_front++] = (sqrt);
keys[keys_front++] = (e[i-1]);
}
for(int i=0; i<(int)(keys_front - keys_back); i=i+1) {
for(int j=(i+1); j<(int)(distances_front - distances_back); j=j+1) {
if(distances[i]>distances[j]) {
distances[i] = distances[j];
distances[j] = distances[i];
keys[i] = keys[j];
keys[j] = keys[i];
}
}
}
for(int i=0; i<(int)neighbour_num; i=i+1) {
result[i] = keys[i];
}
}
this is the wrapper function i have
#include <Python.h>
#include <numpy/arrayobject.h>
#include "spyc.h"
#include "caller.h"
static PyObject* mmult_wrapper(PyObject* self, PyObject* args) {
int32_t e;
int32_t new_data;
int32_t neighbour_num;
int32_t result;
int res = PyArg_ParseTuple(args, "Oi", &e_obj, &d);
if (!res)
return NULL;
/* call function */
mmult_caller(e,d);
}
My objective to accept the dict values from python function and convert it to array values suitable for C in the wrapper. I have no prior knowledge of C\C++ and i am stuck. Any help will be greatly helpful. thanks
you will likely need to include dictobject.h, floatobject.h, , if not already pulled in via other headers. Here is a way to grab all the values from a dict of floating point numbera to a vector. Depending on what's actually in the dict and how that's structured you may want to look at keys and other pieces.
Note that this is C++ and thus should be compiled as such.
//returns true on success
bool dictToVector(PyObject * srcDict, std::vector<double> & destVector) {
destVector.clear();
if(PyDict_Check(srcDict)) {
Py_ssize_t numItems = PyDict_Size(srcDict);
destVector.reserve(numItems);
Py_ssize_t iteratorPPOS = 0;
PyObject * currentVal;
while(PyDict_Next(srcDict, &iteratorPPOS, NULL, ¤tVal) {
// might be worth checking PyFloat_Check...
destVector.push_back(PyFloat_AsDouble(currentVal));
}
return (numItems == destVector.size());
}
else { // not a dict return with failure
return false;
}
}
Your wrapper will be similar at the end in that it will need to copy the result of mmult into the of result type numpy.ndarray.
Usage of the above something like:
PyObject* mmult_wrapper(PyObject * e, PyObject * new_data, PyObject * neighbour_num, PyObject * result) {
int32_t Cresult[16];
std::vector<double> Ce;
bool noErrorSoFar = dictToVector(e,Ce);
if(Ce.size() == 100) {
mmult(PyFloat_AsDouble(new_data) , PyFloat_AsDouble( neighbour_num), Ce.data(), Cresult);
}
else { // not 100 doubles in the data read!
noErrorSoFar = false;
}
... //some stuff to copy Cresult to the python, and return something meaningful?
}
This is a function for finding all Longest common sequence for X and Y sequence.
But this program is in c++ but I want to write it in C.
Is there any way to use array instead of the set?
For eg. if input is
X = < A, A, T, C, C, >
Y = < A, C, A, C, G, >
then the output should be
< A, C, C, >
< A, A, C, >
m and n are size of sequence X and Y respectively.
/* source : https://www.geeksforgeeks.org/printing-longest-common-subsequence-set-2-printing/ */
/* Returns set containing all LCS for X[0..m-1], Y[0..n-1] */
set<string> findLCS(string X, string Y, int m, int n)
{
// construct a set to store possible LCS
set<string> s;
// If we reaches end of either string, return
// a empty set
if (m == 0 || n == 0)
{
s.insert("");
return s;
}
// If the last characters of X and Y are same
if (X[m - 1] == Y[n - 1])
{
// recurse for X[0..m-2] and Y[0..n-2] in
// the matrix
set<string> tmp = findLCS(X, Y, m - 1, n - 1);
// append current character to all possible LCS
// of substring X[0..m-2] and Y[0..n-2].
for (string str : tmp)
s.insert(str + X[m - 1]);
}
// If the last characters of X and Y are not same
else
{
// If LCS can be constructed from top side of
// the matrix, recurse for X[0..m-2] and Y[0..n-1]
if (L[m - 1][n] >= L[m][n - 1])
s = findLCS(X, Y, m - 1, n);
// If LCS can be constructed from left side of
// the matrix, recurse for X[0..m-1] and Y[0..n-2]
if (L[m][n - 1] >= L[m - 1][n])
{
set<string> tmp = findLCS(X, Y, m, n - 1);
// merge two sets if L[m-1][n] == L[m][n-1]
// Note s will be empty if L[m-1][n] != L[m][n-1]
s.insert(tmp.begin(), tmp.end());
}
}
return s;
}
Here is an example for a self-made C unordered_set using arrays.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Buckets 1000
struct Node {
char *key;
struct Node *next;
};
void initNode(struct Node **node, const char *str) {
*node = (struct Node *) malloc(sizeof(struct Node));
size_t l = strlen(str);
(*node)->key = (char *) malloc(l * sizeof(char));
strncpy((*node)->key, str, l);
(*node)->next = NULL;
}
void freeNode(struct Node *node) {
if (node->next) {
freeNode(node->next);
}
free(node->key);
free(node);
}
struct Set {
struct Node *buckets[Buckets];
};
void initSet(struct Set *set) {
for (unsigned int i = 0; i < Buckets; ++i) {
set->buckets[i] = NULL;
}
}
void freeSet(struct Set *set) {
for (unsigned int i = 0; i < Buckets; ++i) {
if (set->buckets[i]) {
free(set->buckets[i]);
}
}
}
unsigned int hash(const char *str) {
unsigned int sum = 0;
for (; *str; ++str) {
sum += *str;
}
return sum % Buckets;
}
int insert(struct Set *set, const char *str) {
const unsigned int h = hash(str);
if (!set->buckets[h]) {
initNode(&set->buckets[h], str);
return 1;
}
struct Node *node = set->buckets[h];
while (node->next && strcmp(str, node->key)) node = node->next;
if (!strcmp(str, node->key)) return 0;
initNode(&node->next, str);
return 1;
}
int main() {
struct Set set;
initSet(&set);
printf("%d", insert(&set, "Text"));
printf("%d", insert(&set, "Text2"));
printf("%d", insert(&set, "Text"));
freeSet(&set);
}
how to make tail recursion optimization enabled, when function more and vals call each other?
now, when I set n = 5, but when I set n = 50000000, it will occur error.
using Cb = std::function<void(bool, int)>;
using Read = std::function<void(bool, Cb)>;
using Sink = std::function<void(Read&)>;
using Through = std::function<Read(Read&)>;
int main() {
int n = 5;
Read vals = [&](bool abort, Cb cb) {
if (n-- <= 0) {
return;
}
cb(false, n); // call `more` function
};
Sink logInt = [&](Read &read) {
Cb more;
more = [&](bool abort, int val) {
cout << val << endl;
read(false, more); // call `vals` function
};
read(false, more);
};
logInt(vals);
return 0;
}
whole real code example
i have found following code on online for suffix tree
#include <stdio.h>
#define E 0
struct suffix_tree_node;
struct suffix_tree_link {
// 0 is e - global index of during string's end
unsigned long start;
unsigned long end;
suffix_tree_link(suffix_tree_node* source, suffix_tree_node* target,
unsigned long start, unsigned long end) {
this->source = source;
this->target = target;
this->start = start;
this->end = end;
}
suffix_tree_node* source;
suffix_tree_node* target;
suffix_tree_link* next_link;
};
struct suffix_tree_node {
suffix_tree_link* first_link;
suffix_tree_node* parent_node;
suffix_tree_node* suffix_link_node;
// other constructors?
suffix_tree_node() {
parent_node = suffix_link_node = NULL;
first_link = NULL;
}
void add_target(unsigned long start, unsigned long end, suffix_tree_node* target) {
suffix_tree_link* link;
for(link = first_link; link != NULL; link = link->next_link);
link = new suffix_tree_link(this, target, start, end);
}
};
class suffix_tree {
suffix_tree_node* root;
const char* string;
void ukkonen() {
root->add_target(1, E, new suffix_tree_node);
unsigned long e = 1, j_i = 1, i = 1;
for( int i = 0; string[i] != '\0'; i++) {
e++;
for() {
j_star = j;
}
j_i = j_star;
}
}
public:
suffix_tree(const char* string) {
root = new suffix_tree_node();
this->string = string;
ukkonen();
}
};
int main() {
suffix_tree("foof");
return 0;
}
everything is clear almost in this code,because i have read about suffix tree many times before,but i did not understand this fragment:
void ukkonen() {
root->add_target(1, E, new suffix_tree_node);
unsigned long e = 1, j_i = 1, i = 1;
for( int i = 0; string[i] != '\0'; i++) {
e++;
for() {
j_star = j;
}
j_i = j_star;
}
}
what does this code do?
also what is for()? or j_start?
here is a link for this code.
You are looking at a work-in-progress. The code you posted hasn't been completely written yet, and does not compile.
A later version of that file can be found here.