How to use & (AND) operator in a signal in Circom - circuit

I'm trying to use & operator on a signal and get another signal in Circom circuit compiler language like so:
pragma circom 2.0.0;
template MAIN() {
signal input a;
signal output x;
signal v;
v <== 168;
x <== v & 31;
}
component main = MAIN();
I'm getting this error:
error[T3001]: Non quadratic constraints are not allowed!
┌─ "/Users/ilia/compiling/main-circom/main.circom":146:5
│
146 │ x <== v & 31; // 0b00011111
│ ^^^^^^^^^^^^ found here
│
= call trace:
->MAIN
How can I generate a constraint for x signal so that it is quadratic?

I did it with Num2Bits:
// the code bellow is a quadratic equivalent of:
// x <== v & 31; // 0b00011111
component num2Bits = Num2Bits(8);
num2Bits.in <== v;
signal vbits[8];
for(k = 0; k < 8; k++) {
vbits[k] <== num2Bits.out[k];
}
var lc1=0;
var e2 = 1;
for (var i = 0; i<5; i++) {
lc1 += vbits[i] * e2;
e2 = e2 + e2;
}
lc1 ==> x;

Related

A OS homework problem about executing threads using semaphores

I'm doing my os homework, and the requirement is to implement parallel merge sort using Pthread and using semaphore to lock and unlock them.
You can only look at the function names Multi____ and ignore Single_____, because I've already finished the single thread part.
I encountered a problem in the multithreaded part. I signal the master thread (sem[1]) in line 227, and it should go into the function 'void *MultiPartition'.
In this function, it gives value to arg[id * 2] and arg[id * 2 + 1].
For example, arg[1] will gives value to arg[2] and arg[3], and then it signals thread[2] and thread[3] to start by sem_post.
And doesn't seem to work.
So I use cout << "partition id = " << id << ", head = " << head << ", mid = " << mid << ", tail = " << tail << "\n"; in line 111 to check out what happens.
It looks really weird. It sometimes outputs
partition id = 1, head = 0, mid = 7, tail = 15
partition id = 2, head = 0, mid = 3, tail = 7
and it was stuck, but the program didn't exit. Means I need to press Ctrl^C to exit program.
Sometimes it outputs
partition id = 1, head = 0, mid = 7, tail = 15
partition id = 2, head = 0, mid = 3, tail = 7
partition id = 3, head = 8, mid = 11, tail = 15
partition id = 4, head = 0, mid = 1, tail = 3
and was stuck, too.
I'm curious where other threads going?
And if id = 4 is displayed, it will runs bubble id = 8 usually.
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
#include <fstream>
#include <sys/time.h>
#include <unistd.h>
using namespace std;
//Pthread_create, pthread_exit *don't use pthread_join
//sem_init, sem_wait, sem_post, sem_getvalue, sem_destroy
//Enter input file name: test.txt
//MT sorting used x secs
//ST sorting used x secs
// g++ -o os_hw3.out os_hw3.cpp -pthread
typedef struct{
int head;
int mid;
int tail;
int id;
}arguments;
//declare global variables
sem_t sem[16]; // use id = 1 ~ 15
sem_t final; // the final semaphore signal that indicate all threads finished.
int* s1, * s2; // two array for single and multiple
arguments arg[16];
void swap(int* x, int* y) {
int temp;
temp = *x;
*x = *y;
*y = temp;
}
void *MultiMerge(void* argid) {
int id = *(int*)argid;
sem_wait(&sem[id]);
sem_wait(&sem[id]);
int head = arg[id].head, mid = arg[id].mid, tail = arg[id].tail;
//cout << "merge id = " << id << ", head = " << head << ", mid = " << mid << ", tail = " << tail << "\n";
int lenA = mid - head + 1;
int lenB = tail - (mid + 1) + 1;
int A[lenA];
int B[lenB];
for (int i = 0; i < lenA; i++) {
A[i] = *(s1 + head + i);
}
for (int j = 0; j < lenB; j++) {
B[j] = *(s1 + mid + 1 + j);
}
int i = 0, j = 0, k = 0;
while (i < lenA && j < lenB) {
if (A[i] < B[j]) {
*(s1 + head + k) = A[i];
i++;
}
else {
*(s1 + head + k) = B[j];
j++;
}
k++;
}
while (i < lenA) {
*(s1 + head + k) = A[i];
i++;
k++;
}
while (j < lenA) {
*(s1 + head + k) = B[j];
j++;
k++;
}
sem_post(&sem[id / 2]); // signal the upper level
if (id == 1) {
fstream fout;
fout.open("output1.txt", ios::out);
for (i = 0; i < arg[1].tail + 1; i++)
fout << *(s2 + i);
fout.close();
sem_post(&final);
}
}
void *MultiBubble(void *argid) {
int id = *(int*)argid;
sem_wait(&sem[id]);
//cout << "bubble id = " << id << ", head = " << arg[id].head << ", tail = " << arg[id].tail << "\n";
for (int i = arg[id].tail; i > 0; --i) {
for (int j = arg[id].head; j < i; ++j) {
if (*(s2 + j) > * (s2 + j + 1)) {
swap((s2 + j), (s2 + j + 1));
}
}
}
for (int i = arg[id].head; i <= arg[id].tail; i++) {
cout << *(s2 + i) << " ";
}
cout << "\n";
sem_post(&sem[id / 2]);
}
void *MultiPartition(void* argid) {
int id = *(int*)argid;
sem_wait(&sem[id]);
int head = arg[id].head, mid = arg[id].mid, tail = arg[id].tail;
cout << "partition id = " << id << ", head = " << head << ", mid = " << mid << ", tail = " << tail << "\n";
arg[id * 2].head = arg[id].head;
arg[id * 2].tail = arg[id].mid;
arg[id * 2].mid = (arg[id * 2].head + arg[id * 2].tail) / 2;
arg[id * 2 + 1].head = arg[id].mid + 1;
arg[id * 2 + 1].tail = arg[id].tail;
arg[id * 2 + 1].mid = (arg[id * 2 + 1].head + arg[id * 2 + 1].tail) / 2;
sem_post(&sem[id * 2]);
sem_post(&sem[id * 2 + 1]);
}
void SingleMerge(int* s1, int head, int mid, int tail) {
int lenA = mid - head + 1;
int lenB = tail - (mid + 1) + 1;
int A[lenA];
int B[lenB];
for (int i = 0; i < lenA; i++) {
A[i] = *(s1 + head + i);
}
for (int j = 0; j < lenB; j++) {
B[j] = *(s1 + mid + 1 + j);
}
int i = 0, j = 0, k = 0;
while (i < lenA && j < lenB) {
if (A[i] < B[j]) {
*(s1 + head + k) = A[i];
i++;
}
else {
*(s1 + head + k) = B[j];
j++;
}
k++;
}
while (i < lenA) {
*(s1 + head + k) = A[i];
i++;
k++;
}
while (j < lenA) {
*(s1 + head + k) = B[j];
j++;
k++;
}
}
int SingleBubble(int* s1, int head, int tail) {
for (int i = tail; i > 0; --i) {
for (int j = head; j < i; ++j) {
if (*(s1 + j) > *(s1 + j + 1)) {
swap((s1 + j), (s1 + j + 1));
}
}
}
}
void SinglePartition(int* s1, int head, int tail, int times) {
if (head <= tail) {
int mid = (head + tail) / 2;
if (times < 3) {
SinglePartition(s1, head, mid, ++times);
SinglePartition(s1, mid + 1, tail, ++times);
}
else {
SingleBubble(s1, head, tail);
}
SingleMerge(s1, head, mid, tail);
}
}
int main() {
char filename[100];
int num;
struct timeval Tstart, Tend;
cout << "Enter the input file name: ";
cin >> filename;
fstream file, fout;
file.open(filename, ios::in);
if (!file) {
cout << "Read File Error.\n";
return -1;
}
else {
file >> num;
s1 = new int[num];
s2 = new int[num];
for (int i = 0; i < num; i++) {
file >> *(s1 + i);
*(s2 + i) = *(s1 + i);
}
file.close();
}
//SINGLE THREAD
gettimeofday(&Tstart, 0);
SinglePartition(s1, 0, num - 1, 0);
gettimeofday(&Tend, 0);
fout.open("output2.txt", ios::out);
for (int i = 0; i < num; i++)
fout << *(s1 + i) << " ";
fout.close();
double Tdifference = (Tend.tv_sec - Tstart.tv_sec) + (Tend.tv_usec - Tstart.tv_usec) / 1000000.0;
cout << "Single thread cost " << Tdifference << " s\n";
//MULTI THREAD
gettimeofday(&Tstart, 0);
arg[1].head = 0;
arg[1].tail = num - 1;
arg[1].mid = (arg[1].head + arg[1].tail) / 2;
pthread_t thread[16];
sem_init(&final, 0, 0);
sem_post(&sem[1]);
for (int i = 1; i < 16; i++){
arg[i].id = i;
sem_init(&sem[i], 0, 0);
if (i < 8) {
if(i == 1)
sem_post(&sem[1]); // call the master thread
pthread_create(&thread[i], NULL, MultiPartition, &arg[i].id);
}
else
pthread_create(&thread[i], NULL, MultiBubble, &arg[i].id);
}
for (int i = 7; i > 0; i--) {
pthread_create(&thread[i], NULL, MultiMerge, &arg[i].id);
}
sem_wait(&final);
gettimeofday(&Tend, 0);
Tdifference = (Tend.tv_sec - Tstart.tv_sec) + (Tend.tv_usec - Tstart.tv_usec) / 1000000.0;
cout << "Multi thread cost " << Tdifference << " s\n";
delete s1, s2;
for (int i = 0; i < 16; i++)
sem_destroy(&sem[i]);
sem_destroy(&final);
return 0;
}
I fixed it myself.
for (int i = 7; i > 0; i--) {
pthread_create(&thread[i], NULL, MultiMerge, &arg[i].id);
}
The above part will confront the following part.
for (int i = 1; i < 16; i++){
arg[i].id = i;
sem_init(&sem[i], 0, 0);
if (i < 8) {
if(i == 1)
sem_post(&sem[1]); // call the master thread
pthread_create(&thread[i], NULL, MultiPartition, &arg[i].id);
}
MultiMerge and MultiPartition both have
sem_wait(&sem[id]);
So if sem[id]'s value != 0, it doesn't know which function to do, in my opinion.
I delete
for (int i = 7; i > 0; i--) {
pthread_create(&thread[i], NULL, MultiMerge, &arg[i].id);
}
and add
MultiMerge(&arg[id].id);
in the bottom of MultiPartition to call MultiMerge, this can fixed my problem.

Getting segmentaition fault with subset dp problem

Given a set of numbers, check whether it can be partitioned into two subsets such that the sum of elements in both subsets is same or not
I am getting segmentation fault in C++(g++ 5.4) with a this problem.
This is where i submitted my solution in C++
https://practice.geeksforgeeks.org/problems/subset-sum-problem/0
I am checking if the array can be divided into two parts with equal sum. So I am just checking if there exists a subset with sum equal to half the sum of the array
I have implemented the below logic with dynamic programming
Let dp[i][j] denote yes or no whether a subset with sum j is possible to form with elements in the range [0, i](both inclusive) where i is 0-based index. I have done nothing new with this traditional problem. But I am getting segmentation fault. The program is giving correct output for small test cases. What mistake have I made
I haven't used any comments because I have done nothing new. Hope it is understandable.
#include <iostream>
#include <bits/stdc++.h>
#include<cstdio>
#define ll long long int
using namespace std;
bool isVowel(char c){
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
bool isLower(char c){
return 97 <= c && c <= 122;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cout << setprecision(10);
ll t, n;
cin >> t;
while (t--) {
cin >> n;
ll a[n];
ll sum = 0;
for (ll i = 0; i < n; i++) {
cin >> a[i];
sum += a[i];
}
if (sum % 2) {
cout << "NO" << '\n';
continue;
}
sum /= 2;
ll dp[n][sum + 1];
for (ll i = 0; i < n; i++) {
for(ll j = 0; j < sum + 1; j++) {
dp[i][j] = 0;
}
}
for (ll i = 0; i < n; i++) {
dp[i][a[i]] = 1;
dp[i][0] = 1;
}
for (ll i = 1; i < n; i++) {
for (ll j = 1; j < sum + 1; j++){
if (j - a[i] > 0) {
dp[i][j] = dp[i - 1][j - a[i]];
}
dp[i][j] |= dp[i - 1][j];
}
}
cout << (dp[n - 1][sum] ? "YES" : "NO") << '\n';
}
}
The segmentation fault is due to
ll dp[n][sum + 1];
Even though the constraints say 1 <= N<= 100, 0 <= arr[i]<= 1000, the test cases used are probably much larger, so ll dp[n][sum + 1] will end up taking some serious stack memory, use
bool dp[n][sum + 1];
It should work fine.
On a side note, avoid using ll randomly, use them according to the constraints.

exchange the value of two variables

Write appropriate C++ code to exchange the value of two variables (for example first Variable and second Variable)
while
a.Using one additional variable
b. Without using any additional variable
The a.answer:
int a = 1, b = 5, c;
c = a;
a = b;
b = c;
std::cout << a << b;
system("pause");
The b.answer:
int a = 1, b = 5;
a = a + b;
b = a - b;
a = a - b;
std::cout << a << b;
system("pause");
You can write:
int a = 1, b = 5;
std::swap(a, b);

C/C++: 'Attempted to read or write protected memory" exception

My code compiles but throws the following exception:
An unhandled exception of type 'System, Access Violation Exception' occured Additional Information: Attempted to read or write protected memory. . .
the error is related to s=s+a[z][r]*b[f][h]
Here a copy of the code:
#include"stdafx.h"
#include"iostream"
using namespace std;
int main()
{
int **a, **b;
int z, r, f, h, a_r, a_c, b_r, b_c, s = 0;
cout << "Enter the size of the matrix(nxm) :" << endl;
cin >> a_r >> a_c;
cout << "enter the size of the mask :" << endl;
cin >> b_r >> b_c;
a = (int **) malloc(10 * a_r);
for (int i = 0; i < a_c; i++)
{
a[i] = (int *) malloc(10 * a_c);
}
b = (int **) malloc(10 * b_r);
for (int i = 0; i < b_c; i++)
{
b[i] = (int *) malloc(10 * b_c);
}
for (int i = 0; i < a_r; i++)
{
for (int j = 0; j < a_c; j++)
{
a[i][j] = i + j;
}
}
for (int i = 0; i < b_r; i++)
{
for (int j = 0; j < b_c; j++)
{
b[i][j] = i + j;
}
}
int k = 1, d = 1;
for (int i = 0; i < a_r; i++)
{
for (int j = 0; j < a_c; j++)
{
for (int n = -1; n <= 1; n++)
{
for (int e = -1; e <= 1; e++)
{
z = i + n;
r = j + e;
f = k + n;
h = d + e;
if (z < 0 || z > a_r || r < 0 || r > a_c)
{
s = s + 0;
} else {
s = s + a[z][r] * b[f][h]; // runtime error occurs here
}
}
}
a[i][j] = s;
s = 0;
}
}
return 0;
}
Here is one problem:
if (z < 0 || z > a_r || r < 0 || r > a_c)
This should read:
if (z < 0 || z >= a_r || r < 0 || r >= a_c)
Otherwise you're potentially accessing out-of-bounds elements.

How to use calcCovarMatrix on IplImage?

There's a single-channel grayscale IplImage whose covariance matrix is to be calculated. There does happen to be a similar question on SO but no one has answered it and the code is significantly different.
Here's the code that's throwing an "unhandled exception":
int calcCovar( IplImage *src, float* dst, int w )
{
// Input matrix size
int rows = w;
int cols = w;
int i,j;
CvScalar se;
float *a;
a = (float*)malloc( w * w * sizeof(float) );
long int k=0;
//image pixels into 1D array
for(i = 0; i < w; ++i)
{
for(j = 0; j < w; ++j)
{
se = cvGet2D(src, i, j);
a[k++] = (float)se.val[0];
}
}
CvMat input = cvMat(w,w,CV_32FC1, a); //Is this the right way to format input pixels??
// Covariance matrix is N x N,
// where N is input matrix column size
const int n = w;
// Output variables passed by reference
CvMat* output = cvCreateMat(n, n, CV_32FC1);
CvMat* meanvec = cvCreateMat(1, rows, CV_32FC1);
// Calculate covariance matrix - error is here!!
cvCalcCovarMatrix((const void **) &input, rows, output, meanvec, CV_COVAR_NORMAL);
k = 0;
//Show result
cout << "Covariance matrix:" << endl;
for(i=0; i<n; i++) {
for(j=0; j<n; j++) {
cout << "(" << i << "," << j << "): ";
printf ("%f ", cvGetReal2D(output,i,j) / (rows - 1));
dst[k++] = cvGetReal2D(output,i,j) / (rows - 1);
//cout << "\t";
}
cout << endl;
}
return(0);
}
read in the manual about this function. if you store your values in the single matrix 'input', the second function parameter must not be 'rows'. The second parameter is used to say how many matrices you passes in the first parameter. You have passed just one matrix, 'input'. Segfault is no surprise.

Resources