My class has 2 properties (String) that are two types of people's document numbers. To verify if the documents has valid numbers, a calculation is realized (verifiers digits). Below an example how is realized a consistensy of one of them:
Number: 973.345.650-02 (The punctuations must be ignored)
FIRST VERIFIER DIGIT CALCULATION
9 * 10 = 90
7 * 9 = 63
3 * 8 = 24
3 * 7 = 21
4 * 6 = 24
5 * 5 = 25
6 * 4 = 24
5 * 3 = 15
0 * 2 = 0
----------
Sum = 286
286 % 11 = 0
If rest < 2 then first digit = 0
Or if rest >= 2 then first digit = 11 - rest
In this case, rest < 2 (0), then first verifier digit = 0
SECOND VERIFIER DIGIT CALCULATION
9 * 11 = 99
7 * 10 = 70
3 * 9 = 27
3 * 8 = 24
4 * 7 = 28
5 * 6 = 30
6 * 5 = 30
5 * 4 = 20
0 * 3 = 0
0 * 2 = 0 ==> FIRST VERIFIER DIGIT
----------
Sum = 328
328 % 11 = 9
Same rule of first verifier digit
If rest < 2 then first digit = 0
Or if rest >= 2 then first digit = 11 - rest
The rest is greater than 2 (9), then second verifiter digit = 11 - 9 ==> 2
JAVA METHOD
public static boolean isValidCPF(String cpf) {
cpf = cpf.replaceAll("[./-]", "");
if (cpf.length() < 11) {
return false;
}
int equalDigits = 0;
char compareChar = cpf.charAt(0);
for (int i = 1; i <= 9; i++) {
if (compareChar == cpf.charAt(i)) {
equalDigits++;
} else {
break;
}
}
if (equalDigits == 9) {
return false;
}
int[] digit = new int[2];
int sum = 0, multiply = 2;
for (int k = 8; k <= 9; k++) {
for (int i = k; i >= 0; i--) {
sum += Character.getNumericValue(cpf.charAt(i)) * multiply++ ;
}
digit[k-8] = (sum % 11) < 2 ? 0 : 11 - (sum % 11);
sum = 0;
multiply = 2;
}
if (cpf.equals(cpf.substring(0 , 9) + digit[0] + digit[1])) {
return true;
}
return false;
}
I guess that OCL "sequence" must be used in this case (loop through digits) converting each one to Integer for calculation and using "body" in constraint, but I don't know how.
I want to apply the contraint to UML model in Papyrus (that's I know how to do).
Thanks in advance.
You must think declaratively in aggregates so to emulate
for (int i = 1; i <= 9; i++) {
if (compareChar == cpf.charAt(i)) {
equalDigits++;
} else {
break;
}
}
you might try something like
Sequence{2..10}->select(i | cpf->at(i) = compareChar)->size()
NB OCL indexes start at 1.
I am writing some code for an Arduino Uno that involves copying parts of arrays. The use of memcpy causes an entirely unrelated variable to occasionally appear corrupted in the serial output. Here is the code necessary to show the issue.
byte cchar[8][8];
byte fbold[16][16];
void setup() {
Serial.begin(9600);
}
void loop() {
for (byte i = 0; i < 8; i++) {
memcpy(cchar + i*8, fbold + 16 * i , 8);
Serial.println(i);
Serial.println(i);
}
delay(500);
}
I believe that this should output the following on repeat:
1
1
2
2
3
3
4
4
5
5
6
6
7
7
but oddly, it is more like this: (taken directly from serial monitor)
0
0
1
1
2
2ff
4
5
4
4
5
5
6
6
7
7
0
0
1
1
2
2
3
3
4
4
5
5ff
7
07
7
With the memcpy command removed, it outputs as I would expect.
The logical conclusion would be that my memcpy is corrupting i.
But why though? i is supposedly never more than 7, cchar is 64 bytes long, and I'm only copying 8 bytes, right? So how would I be copying outside of cchar?
the problems is pointer arithmetic. sizeof(*cchar) is 8 so address of cchar + 1 is 8 bytes after address of cchar
this works
byte cchar[8][8];
byte fbold[16][16];
void setup() {
Serial.begin(115200);
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
fbold[i][j] = j;
}
}
for (int i = 0; i < 8; i++) {
memcpy(cchar + i, fbold + i, 8);
for (int j = 0; j < 8; j++) {
Serial.print(cchar[i][j]);
Serial.print(',');
}
Serial.println();
}
}
void loop() {
}
We know that a b-based standard positional number system uses digits,
0, 1, 2, ..., b-1. But a bijective number system uses digits, 1, 2, ..., b. So a 4-based standard number system sequence looks like,
0
1
2
3
10
11
12
13
20
21
22
23
30
31
32
33 (base-4, 16th number standard)
100 (base-4, 17th number standard)
101
.
.
.
On the other hand bijective number system for 4-based looks like,
λ (base-4, 1st number, empty-string)
1
2
3
4
11
12
13
14
21
22
23
24
31
32
33 (base-4, 16th number bijective)
34 (base-4, 17th number bijective)
41
.
.
.
Example:
34152 (in bijective base-5) = 3×54 + 4×53 + 1×52 + 5×51 + 2×1 = 2427 (in decimal).
119A (in bijective base-10, with "A" representing the digit value ten) = 1×103 + 1×102 + 9×101 + 10×1 = 1200 (in decimal).
I wonder if there is any easy way to find n'th position bijective value in same base.
For example,
lets say in base-4 5th positional value = 10 (standard) but 5th positional value = 11 (bijective). Any pseudocode is ok to understand the concept.
If a number in the standard base-n system contains no zeros, the number has the same representation as bijective base-n.
So you need to look for zeros in the standard number. When you find a zero, replace it with the maximum symbol in the bijective and decrement the element to the left.
Simple example:
10 decimal -> A bijective because 0 becomes A and 1 decrements to zero
20 decimal -> 1A bijective because 0 becomes A and 2 decrements to 1
As a special case you must handle sequences of zero.
Simple example:
200 decimal -> 19A bijective (i.e. step 1: 1A0 step 2: 19A)
You can also look at it like this
200 decimal is constructed as 2*100 + 0*10 + 0*1 = 200 decimal
For bijective you can't have zero so you'll do:
19A bijective is constructed as 1*100 + 9*10 + 10*1 = 200 decimal
To finish a bit more complex example:
110 decimal -> AA bijective (i.e. step 1: 10A step 2: AA)
This routine implements the conversion. (Which resolved to #4386427's method.) If you want the other version, where 100 (base 4 std) -> 41 (base 4 bij') then compile with -D NO_EMPTY_STRING
#include <stdio.h>
#include <string.h>
void print_be_digits(const char *prefix, const unsigned char *le_num, size_t len)
{
size_t i;
printf("%s", prefix);
for(i=0; i<len; i++)
{
printf("%d ", (int)le_num[len-i-1]);
}
printf("\n");
}
void nth_bij(int n, int k)
{
ssize_t i;
size_t std_len;
size_t bij_len;
size_t work;
unsigned char le_std_digits[256];
unsigned char le_bij_digits[256];
//convert to standard radix-k digits
work = n;
for(std_len = 0; work; std_len++)
{
le_std_digits[std_len] = work % k;
work /= k;
}
print_be_digits(" std: ", le_std_digits, std_len);
//convert standard to bij
memcpy(le_bij_digits, le_std_digits, std_len);
bij_len = std_len;
#ifdef NO_EMPTY_STRING
// Step 1: increment LSd
le_bij_digits[0]++;
#endif
// Step 2: borrow on zeros
// scan back from the end
for(i=bij_len-1; i>= 0; i--)
{
//if we find a zero, borrow, and ripple toward MSd as necessary
if(le_bij_digits[i] == 0)
{
size_t j;
//Ripple borrow toward MSd, as necessary
for(j=i+1; j<bij_len; j++)
{
le_bij_digits[j-1] = k; //k is the radix
if(--le_bij_digits[j])
{
break;
}
}//end ripple
//adjust bij_len if we rippled to the end
if(j == bij_len)
{
bij_len--;
}
}
}//end scan
print_be_digits(" bij: ", le_bij_digits, bij_len);
}
Simple driver:
int main(int argc, char *argv[])
{
printf("Test: 16 decimal (->base 4): \n");
nth_bij(16,4);
printf("\n");
printf("Test: 8 decimal (->base 2): \n");
nth_bij(8,2);
printf("\n");
printf("Test: 13 decimal (->base 2): \n");
nth_bij(13,2);
printf("\n");
printf("Test: 2427 decimal (->base 5): \n");
nth_bij(2427, 5);
printf("\n");
printf("Test: 1200 decimal (->base 10): \n");
nth_bij(1200, 10);
printf("\n");
}
Compiling for my version:
$ gcc -D NO_EMPTY_STRING bij.c
$ ./a.exe
Test: 16 decimal (->base 4):
std: 1 0 0
bij: 4 1
Test: 8 decimal (->base 2):
std: 1 0 0 0
bij: 1 2 1
Test: 13 decimal (->base 2):
std: 1 1 0 1
bij: 2 2 2
Test: 2427 decimal (->base 5):
std: 3 4 2 0 2
bij: 3 4 1 5 3
Test: 1200 decimal (->base 10):
std: 1 2 0 0
bij: 1 1 10 1
Compiling for #4386427's version:
$ gcc bij.c
$ ./a.exe
Test: 16 decimal (->base 4):
std: 1 0 0
bij: 3 4
Test: 8 decimal (->base 2):
std: 1 0 0 0
bij: 1 1 2
Test: 13 decimal (->base 2):
std: 1 1 0 1
bij: 2 2 1
Test: 2427 decimal (->base 5):
std: 3 4 2 0 2
bij: 3 4 1 5 2
Test: 1200 decimal (->base 10):
std: 1 2 0 0
bij: 1 1 9 10
See DFS image Here
I am using stack to print sequence of dfs. According to input and that image of graph, sequence is 1 2 4 8 5 6 3 7 . But My code is giving output as 1 2 4 8 7 6 5 3 . Can anyone explain how can i fix it??
Input:
8 10
1 3
1 2
2 5
2 4
3 7
3 6
4 8
5 8
6 8
7 8
Correct Output:
Sequence: 1 2 4 8 5 6 3 7
My Code :
#include <bits/stdc++.h>
using namespace std;
vector<int>edges[100];
stack<int>q;
vector<int>item;
int level[100],parent[100],visited[100],tn;
void dfs(int s)
{
int j,k,fr;
q.push(s);
level[s]=0;
for(j=1;j<=tn;j++)
{
visited[j]=0;
}
visited[s]=1;
while(!q.empty())
{
fr=q.top();
q.pop();
item.push_back(fr);
for(k=0;k<edges[fr].size();k++)
{
if(visited[edges[fr][k]]==0)
{
q.push(edges[fr][k]);
//cout<<"Pushed="<<fr<<"="<<edges[fr][k];
visited[edges[fr][k]]=1;
}
}
//cout<<endl;
}
}
int main()
{
int i,e,p,n,u,v,f,m;
cin>>tn>>e;
for(i=1;i<=e;i++)
{
cin>>u>>v;
edges[u].push_back(v);
edges[v].push_back(u);
}
dfs(1);
cout<<"Sequence="<<endl;
for(m=0;m<item.size();m++)
{
cout<<item[m];
}
return 0;
}
My Code is showing this output: 1 2 4 8 7 6 5 3
The marking of the nodes as visited in the implementation contains a bug; the function can be rewritten as follows.
void dfs(int s)
{
int j, k, fr;
q.push(s);
level[s] = 0;
for (j = 1; j <= tn; j++)
{
visited[j] = 0;
}
while (!q.empty())
{
fr = q.top();
q.pop();
if (0 == visited[fr])
{
visited[fr] = 1;
item.push_back(fr);
for (k = 0; k < edges[fr].size(); k++)
{
q.push(edges[fr][k]);
}
}
}
}
In this version, a node gets marked only if it is taken from the stack. Note that a check whether the node has been already visited is necessary, as a node on the stack might be visited by a later iteration. This implementation yields the sequence
1 2 4 8 7 3 6 5
which, however, is not the one described as desired solution. However, note that without additional tie-breaking rules, the DFS algorithm permits some ambiguity in the sequence of visits. The sequence
1 2 4 8 5 6 3 7
can be generated by pushing a neighbor with smallest id to the stack last, causing it to be visited in the next iteration.
I'm trying to create a function that extracts a column from a big.matrix object in Rcpp (so that it can be analyzed in cpp before bringing the results to R), but I can't figure out how to get it to recognise NA's (they are now presented as -2147483648 - as shown in my minimal example below). It would be even better if I could access the function GetMatrixCols (src/bigmemory.cpp) straight from Rcpp, but I've yet to discover a way to do that.
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(BH, bigmemory)]]
#include <bigmemory/MatrixAccessor.hpp>
#include <bigmemory/isna.hpp>
using namespace Rcpp;
//Logic for extracting column from a Big Matrix object
template <typename T>
NumericVector GetColumn_logic(XPtr<BigMatrix> pMat, MatrixAccessor<T> mat, int cn) {
NumericVector nv(pMat->nrow());
for(int i = 0; i < pMat->nrow(); i++) {
if(isna(mat[cn][i])) {
nv[i] = NA_INTEGER;
} else {
nv[i] = mat[cn][i];
}
}
return nv;
}
//' Extract Column from a Big Matrix.
//'
//' #param pBigMat A bigmemory object address.
//' #param colNum Column Number to extract. Indexing starts from zero.
//' #export
// [[Rcpp::export]]
NumericVector GetColumn(SEXP pBigMat, int colNum) {
XPtr<BigMatrix> xpMat(pBigMat);
switch(xpMat->matrix_type()) {
case 1: return GetColumn_logic(xpMat, MatrixAccessor<char>(*xpMat), colNum);
case 2: return GetColumn_logic(xpMat, MatrixAccessor<short>(*xpMat), colNum);
case 4: return GetColumn_logic(xpMat, MatrixAccessor<int>(*xpMat), colNum);
case 6: return GetColumn_logic(xpMat, MatrixAccessor<float>(*xpMat), colNum);
case 8: return GetColumn_logic(xpMat, MatrixAccessor<double>(*xpMat), colNum);
default: throw Rcpp::exception("Unknown type detected for big.matrix object!");
}
}
/*** R
bm <- bigmemory::as.big.matrix(as.matrix(reshape2::melt(matrix(c(1:4,NA,6:20),4,5))))
bigmemory:::CGetType(bm#address)
bigmemory:::GetCols.bm(bm, 3)
GetColumn(bm#address, 2)
*/
That's a great one! Stay with me for a moment:
tl;dr: It works once fixed:
R> sourceCpp("/tmp/bigmemEx.cpp")
R> bm <- bigmemory::as.big.matrix(as.matrix(reshape2::melt(matrix(c(1:4,NA,6:20),4,5))))
R> bigmemory:::CGetType(bm#address)
[1] 4
R> bigmemory:::GetCols.bm(bm, 3)
[1] 1 2 3 4 NA 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
R> GetColumn(bm#address, 2)
[1] 1 2 3 4 NA 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
R>
The trouble starts at the inside. When you create your matrix as
matrix(c(1:4,NA,6:20),4,5)
what do you get? Integer!
R> matrix(c(1:4,NA,6:20),4,5)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 NA 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20
R> class(matrix(c(1:4,NA,6:20),4,5))
[1] "matrix"
R> typeof(matrix(c(1:4,NA,6:20),4,5))
[1] "integer"
R>
Not a problem per se, but a problem once you remember that the IEEE 754standard has NaN defined for floating point only (correct if I'm wrong).
The other issue is that you reflexively used NumericVector in your, but operate on integers. Now R has NaN, and even NA, for floating point and integer, but 'normal libraries' outside of R do not. And a bigmemory by design represents things outside of R, you're stuck.
The fix is simple enough: use IntegerVector (or equivalently convert your integer data on input). Below is my altered version of your code.
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(BH, bigmemory)]]
#include <bigmemory/MatrixAccessor.hpp>
#include <bigmemory/isna.hpp>
using namespace Rcpp;
//Logic for extracting column from a Big Matrix object
template <typename T>
IntegerVector GetColumn_logic(XPtr<BigMatrix> pMat, MatrixAccessor<T> mat, int cn) {
IntegerVector nv(pMat->nrow());
for(int i = 0; i < pMat->nrow(); i++) {
if(isna(mat[cn][i])) {
nv[i] = NA_INTEGER;
} else {
nv[i] = mat[cn][i];
}
}
return nv;
}
//' Extract Column from a Big Matrix.
//'
//' #param pBigMat A bigmemory object address.
//' #param colNum Column Number to extract. Indexing starts from zero.
//' #export
// [[Rcpp::export]]
IntegerVector GetColumn(SEXP pBigMat, int colNum) {
XPtr<BigMatrix> xpMat(pBigMat);
switch(xpMat->matrix_type()) {
case 1: return GetColumn_logic(xpMat, MatrixAccessor<char>(*xpMat), colNum);
case 2: return GetColumn_logic(xpMat, MatrixAccessor<short>(*xpMat), colNum);
case 4: return GetColumn_logic(xpMat, MatrixAccessor<int>(*xpMat), colNum);
case 6: return GetColumn_logic(xpMat, MatrixAccessor<float>(*xpMat), colNum);
case 8: return GetColumn_logic(xpMat, MatrixAccessor<double>(*xpMat), colNum);
default: throw Rcpp::exception("Unknown type detected for big.matrix object!");
}
}
/*** R
bm <- bigmemory::as.big.matrix(as.matrix(reshape2::melt(matrix(c(1:4,NA,6:20),4,5))))
bigmemory:::CGetType(bm#address)
bigmemory:::GetCols.bm(bm, 3)
GetColumn(bm#address, 2)
*/
Accessing a column of a big.matrix in Rcpp is not difficult,
you can for example get an std vector, an Armadillo vector or an Eigen vector
with the following code (there may exist cleaner code):
// [[Rcpp::depends(RcppEigen, RcppArmadillo, bigmemory, BH)]]
#include <RcppArmadillo.h>
#include <RcppEigen.h>
#include <bigmemory/BigMatrix.h>
#include <bigmemory/MatrixAccessor.hpp>
using namespace Rcpp;
using namespace arma;
using namespace Eigen;
using namespace std;
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
ListOf<IntegerVector> AccessVector(SEXP pBigMat, int j) {
XPtr<BigMatrix> xpMat(pBigMat);
MatrixAccessor<int> macc(*xpMat);
int n = xpMat->nrow();
// Bigmemory
cout << "Bigmemory:";
for (int i = 0; i < n; i++) {
cout << macc[j][i] << ' ';
}
cout << endl;
// STD VECTOR
vector<int> stdvec(macc[j], macc[j] + n);
// ARMA VECTOR
Row<int> armavec(macc[j], n); // Replace Row by Col if you want
// EIGEN VECTOR
VectorXi eigenvec(n);
memcpy(&(eigenvec(0)), macc[j], n * sizeof(int));
return(List::create(_["Std vector"] = stdvec,
_["Arma vector"] = armavec,
_["Eigen vector"] = eigenvec));
}
AccessVector(bm#address, 2) gets you:
Bigmemory:1 2 3 4 -2147483648 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
$`Std vector`
[1] 1 2 3 4 NA 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
$`Arma vector`
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
[1,] 1 2 3 4 NA 6 7 8 9 10 11 12 13 14 15
[,16] [,17] [,18] [,19] [,20]
[1,] 16 17 18 19 20
$`Eigen vector`
[1] 1 2 3 4 NA 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
You can see that C doesn't know about NAs but when returning to R, you keep them.
So, it depends on what operations you want to do in Rcpp on the columns. I think if you use directly Eigen or Armadillo operations, it should be OK, but you will certainly get lots of NAs in your result.
Maybe it would be clearer if you say what are these operations you want to do.