I cannot for the life of me figure out what's going on. Here's the error I get:
alloc static vecs
a.out: malloc.c:2451: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed. Aborted (core dumped)
The error occurs in the function Halton in class qmc, which I've included the relevant bits to below. As you can see, the first print statement "alloc static vecs" executes, but the statement std::vector<double> H(s); appears not to, since the print statement immediately following it does not execute.
Now, I should mention that when I replace the statement static std::vector<int> bases = FirstPrimes(s); in Halton with static std::vector<int> bases = {2,3,5,7,11,13}; (the RHS is the return array of FirstPrimes(), just hardcoded) then there is no error.
There are more functions in Halton (it returns a std::vector) but I've omitted them for brevity. I'll add them if anyone wants to try to run it themselves, just ask!
I'm using g++ 4.6 and Ubuntu 12.04, and the compilation command is g++ -std=c++0x scratch.cpp QMC.cpp.
main (scratch.cpp):
#include <iostream>
#include <vector>
#include "QMC.h"
int main() {
QMC qmc;
std::vector<double> halton = qmc.Halton(6,1);
}
QMC.h:
#ifndef QMC_H
#define QMC_H
#include <iostream>
#include <cmath>
#include <vector>
class QMC {
public:
QMC();
bool isPrime(int n);
std::vector<int> ChangeBase(int n, int radix);
std::vector<int> NextChangeBase(std::vector<int>& a_in, int radix);
double RadicalInverse(std::vector<int>& a, int b);
std::vector<int> FirstPrimes(int n);
std::vector<double> Halton(int s, int n = 0);
};
#endif
QMC.cpp:
#include "QMC.h"
QMC::QMC(){}
std::vector<double> QMC::Halton(int s, int n) {
static std::vector<std::vector<int> > newBases(s);
static std::vector<int> bases = FirstPrimes(s);
/* replacing the statement immediately above with
static std::vector<int> bases = {2,3,5,7,11,13}; fixes it */
std::cout << "alloc static vecs \n";
std::vector<double> H(s);
std::cout << "alloc H \n";
// ...there's more to this function, but the error occurs just above this.
}
std::vector<int> QMC::FirstPrimes(int n) {
std::vector<int> primes(n);
primes[0] = 2;
int testNum = 3;
for (int countOfPrimes = 1; countOfPrimes <= n; ++countOfPrimes) {
while (isPrime(testNum) == false)
testNum = testNum + 2;
primes[countOfPrimes] = testNum;
testNum = testNum + 2;
}
return primes;
}
bool QMC::isPrime(int n) {
if (n == 1) return false; // 1 is not prime
else if (n < 4) return true; // 2 & 3 are prime
else if (n % 2 == 0) return false; // even numbers are not prime
else if (n < 9) return true; // 5 & 7 are prime
else if (n % 3 == 0) return false; // multiples of 3 (> 3) are not prime
else
{
int r = floor(sqrt((double)n));
int f = 5;
while (f <= r)
{
if (n % f == 0) return false;
if (n % (f + 2) == 0) return false;
f += 6;
}
return true;
}
}
FirstPrimes has a buffer overflow. The relevant lines:
std::vector<int> primes(n);
primes[0] = 2;
for (int countOfPrimes = 1; countOfPrimes <= n; ++countOfPrimes)
primes[countOfPrimes] = testNum;
For a vector of size n, the valud indices are 0 through n-1. On the last loop iteration you do an out-of-bounds access.
I'd suggest changing both of the [ ] to .at( ), as well as fixing the logic error. This would also prevent trouble if you happened to call this function with n == 0.
Related
I am now trying to make a program to find the Absolute Euler Pseudoprimes ('AEPSP' in short, not Euler-Jacobi Pseudoprimes), with the definition that n is an AEPSP if
a(n-1)/2 ≡ ±1 (mod n)
for all positive integers a satisfying that the GCD of a and n is 1.
I used a C++ code to generate AEPSPs, which is based on a code to generate Carmichael numbers:
#include <iostream>
#include <cmath>
#include <algorithm>
#include <numeric>
using namespace std;
unsigned int bm(unsigned int a, unsigned int n, unsigned int p){
unsigned long long b;
switch (n) {
case 0:
return 1;
case 1:
return a % p;
default:
b = bm(a,n/2,p);
b = (b*b) % p;
if (n % 2 == 1) b = (b*a) % p;
return b;
}
}
int numc(unsigned int n){
int a, s;
int found = 0;
if (n % 2 == 0) return 0;
s = sqrt(n);
a = 2;
while (a < n) {
if (a > s && !found) {
return 0;
}
if (gcd(a, n) > 1) {
found = 1;
}
else {
if (bm(a, (n-1)/2, n) != 1) {
return 0;
}
}
a++;
}
return 1;
}
int main(void) {
unsigned int n;
for (n = 3; n < 1e9; n += 2){
if (numc(n)) printf("%u\n",n);
}
return 0;
}
Yet, the program is very slow. It generates AEPSPs up to 1.5e6 in 20 minutes. Does anyone have any ideas on optimizing the program?
Any help is most appreciated. :)
I've come up with a different algorithm, based on sieving for primes upfront while simultaneously marking off non-squarefree numbers. I've applied a few optimizations to pack the information into memory a bit tighter, to help with cache-friendliness as well. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define PRIME_BIT (1UL << 31)
#define SQUARE_BIT (1UL << 30)
#define FACTOR_MASK (SQUARE_BIT - 1)
void sieve(uint64_t size, uint32_t *buffer) {
for (uint64_t i = 3; i * i < size; i += 2) {
if (buffer[i/2] & PRIME_BIT) {
for (uint64_t j = i * i; j < size; j += 2 * i) {
buffer[j/2] &= SQUARE_BIT;
buffer[j/2] |= i;
}
for (uint64_t j = i * i; j < size; j += 2 * i * i) {
buffer[j/2] |= SQUARE_BIT;
}
}
}
}
int main(int argc, char **argv) {
if (argc < 2) {
printf("Usage: prog LIMIT\n");
return 1;
}
uint64_t size = atoi(argv[1]);
uint32_t *buffer = malloc(size * sizeof(uint32_t) / 2);
memset(buffer, 0x80, size * sizeof(uint32_t) / 2);
sieve(size, buffer);
for (uint64_t i = 5; i < size; i += 4) {
if (buffer[i/2] & PRIME_BIT)
continue;
if (buffer[i/2] & SQUARE_BIT)
continue;
uint64_t num = i;
uint64_t factor;
while (num > 1) {
if (buffer[num/2] & PRIME_BIT)
factor = num;
else
factor = buffer[num/2] & FACTOR_MASK;
if ((i / 2) % (factor - 1) != 0) {
break;
}
num /= factor;
}
if (num == 1)
printf("Found pseudo-prime: %ld\n", i);
}
}
This produces the pseudo-primes up to 1.5e6 in about 8ms on my machine, and for 2e9 it takes 1.8sec.
The time complexity of the solution is O(n log n) - the sieve is O(n log n), and for each number we either do constant time checks or do a divisibility test for each of its factors, which there are at most log n. So, the main loop is also O(n log n), resulting in O(n log n) overall.
Among the given input of two numbers, check if the second number is exactly the next prime number of the first number. If so return "YES" else "NO".
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int nextPrime(int x){
int y =x;
for(int i=2; i <=sqrt(y); i++){
if(y%i == 0){
y = y+2;
nextPrime(y);
return (y);
}
}
return y;
}
int main()
{
int n,m, x(0);
cin >> n >> m;
x = n+2;
if(n = 2 && m == 3){
cout << "YES\n";
exit(0);
}
nextPrime(x) == m ? cout << "YES\n" : cout << "NO\n";
return 0;
}
Where is my code running wrong? It only returns true if next number is either +2 or +4.
Maybe it has something to do with return statement.
I can tell you two things you are doing wrong:
Enter 2 4 and you will check 4, 6, 8, 10, 12, 14, 16, 18, ... for primality forever.
The other thing is
y = y+2;
nextPrime(y);
return (y);
should just be
return nextPrime(y + 2);
Beyond that your loop is highly inefficient:
for(int i=2; i <=sqrt(y); i++){
Handle even numbers as special case and then use
for(int i=3; i * i <= y; i += 2){
Using a different primality test would also be faster. For example Miller-Rabin primality test:
#include <iostream>
#include <cstdint>
#include <array>
#include <ranges>
#include <cassert>
#include <bitset>
#include <bit>
// square and multiply algorithm for a^d mod n
uint32_t pow_n(uint32_t a, uint32_t d, uint32_t n) {
if (d == 0) __builtin_unreachable();
unsigned shift = std::countl_zero(d) + 1;
uint32_t t = a;
int32_t m = d << shift;
for (unsigned i = 32 - shift; i > 0; --i) {
t = ((uint64_t)t * t) % n;
if (m < 0) t = ((uint64_t)t * a) % n;
m <<= 1;
}
return t;
}
bool test(uint32_t n, unsigned s, uint32_t d, uint32_t a) {
uint32_t x = pow_n(a, d, n);
//std::cout << " x = " << x << std::endl;
if (x == 1 || x == n - 1) return true;
for (unsigned i = 1; i < s; ++i) {
x = ((uint64_t)x * x) % n;
if (x == n - 1) return true;
}
return false;
}
bool is_prime(uint32_t n) {
static const std::array witnesses{2u, 3u, 5u, 7u, 11u};
static const std::array bounds{
2'047u, 1'373'653u, 25'326'001u, 3'215'031'751u, UINT_MAX
};
static_assert(witnesses.size() == bounds.size());
if (n == 2) return true; // 2 is prime
if (n % 2 == 0) return false; // other even numbers are not
if (n <= witnesses.back()) { // I know the first few primes
return (std::ranges::find(witnesses, n) != std::end(witnesses));
}
// write n = 2^s * d + 1 with d odd
unsigned s = 0;
uint32_t d = n - 1;
while (d % 2 == 0) {
++s;
d /= 2;
}
// test widtnesses until the bounds say it's a sure thing
auto it = bounds.cbegin();
for (auto a : witnesses) {
//std::cout << a << " ";
if (!test(n, s, d, a)) return false;
if (n < *it++) return true;
}
return true;
}
And yes, that is an awful lot of code but it runs very few times.
Something to do with the return statement
I would say so
y = y+2;
nextPrime(y);
return (y);
can be replaced with
return nextPrime(y + 2);
Your version calls nextPrime but fails to do anything with the return value, instead it just returns y.
It would be more usual to code the nextPrime function with another loop, instead of writing a recursive function.
I need to convert this recursive function into tail recursive function but i am getting the wrong output can any help me out with this.
Here is the function definition:
f(n) = 3f(n − 1) - f(n − 2) + n,
with initial conditions f(0) = 1 and f(1) = 2.
#include <iostream>
using namespace std;
int headRecursion(int n) {
if(n == 0) {
return 1;
}
if (n == 1) {
return 2;
}
return 3 * headRecursion(n - 1) - headRecursion(n - 2) + n;
}
int main(){
cout << endl << headRecursion(3);
return 0;
}
This is kind of an interesting problem. We can start with how to implement as a loop:
int minus2 = 1;
int minus1 = 2;
if (n == 0) return minus2;
if (n == 1) return minus1;
for( int i = 2; i <= n; i++)
{
int next = minus1 * 3 - minus2 + i;
minus2 = minus1;
minus1 = next;
}
return minus1;
The takeaway is we need to count UP. In order to make this tail recursive we need to pass in our accumulators (there is no reason to do this other than to show off, but it adds nothing to readability or efficiency)
int tailRecursive(int minus2, int minus1, int step, int n)
{
if (step == n) return minus1;
return tailRecursive(minus1, minus1*3 - minus2 + step+1, step+1, n);
}
you can use an intermediate to set it up and handle the n==0 case.
int calcIt(int n) {
if (n == 0) return 1;
// step must start with 1, since we handled 0 above
return tailRecursive(1, 2, 1, n);
}
Something along these lines:
std::pair<int, int> next_result(std::pair<int, int> prev_result, int n) {
return {3*prev_result.first - prev_result.second + n, prev_result.first};
}
std::pair<int, int> tailRecursion(int n) {
if (n == 0) {
return {1, 0};
}
if (n == 1) {
return {2, 1};
}
return next_result(tailRecursion(n-1), n);
}
int compute(int n) {
return tailRecursion(n).first;
}
int main(){
std::cout << compute(3) << std::endl;
}
Demo
The key is that you need a function that computes a pair {f(n), f(n-1)} given the previously computed pair {f(n-1), f(n-2)}
I am getting two warning (narrowing conversion && control may reach end of non-void function) with the following code. The code compiles however, when I run it it gives this message : Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
The code is compiled using CLion on Ubuntu
// calculate F(n) mod m
#include <iostream>
#include <cmath>
long long Fiobonacci(long long n) { // Fast calculation of Fibonacci number using 'fast doubling'
if (n == 0)
return 0;
else if (n % 2 == 0)
return Fiobonacci(n / 2) * (2 * Fiobonacci(n / 2 + 1) - Fiobonacci(n / 2));
else
return std::pow(Fiobonacci((n + 1) / 2), 2) + std::pow(Fiobonacci((n - 1) / 2), 2);
}
long long GetPissanoPeriod(long long m){
for (long long i = 0; i <= 6 * m ; ++i){
if (Fiobonacci(i) % m == 0){ // if an element is zero it might be followed by a 1
if(Fiobonacci(i+1) % m == 1)
return i+1;
}
}
}
int main() {
long long n, m;
std::cin >> n >> m;
long long period = GetPissanoPeriod(m);
long long res = Fiobonacci(n % period) % m;
std::cout << res << 'n';
}
See the modified code below.
#include <iostream>
#include <cmath>
using namespace std;
long long pow2(long long x)
{
return x * x;
}
long long Fibonacci(long long n) { // Fast calculation of Fibonacci number using 'fast doubling'
if (n == 0)
return 0;
else if(n <= 2)
return 1;
else if (n % 2 == 0)
return Fibonacci(n / 2) * (2 * Fibonacci(n / 2 + 1) - Fibonacci(n / 2));
else
return pow2(Fibonacci((n/2 + 1) / 2), 2) + pow2(Fibonacci((n / 2)), 2);
}
long long GetPisanoPeriod(long long m){
for (long long i = 2; i <= m * m ; ++i){
if (Fibonacci(i) % m == 0){ // if an element is zero it might be followed by a 1
if(Fibonacci(i+1) % m == 1){
return i - 1;
}
}
}
return 1;
}
int main() {
long long n, m;
std::cin >> n >> m;
long long period = GetPisanoPeriod(m);
long long res = Fibonacci(n % period) % m;
std::cout << "res" << res<<endl;
}
control may reach end of non-void function error is due to not returning value from GetPisanoPeriod. as pointed out by #JaMiT
The segmentation fault was due to the incorrect termination condition of function Fibonacci.
Fibonacci series is defined as below.
Fn = Fn-1 + Fn-2
with seed values
F0 = 0 and F1 = 1
Meaning there should be a termination condition for n = 0 and n = 1.
For n = 2 You don't have to call recursion can simply return 1.
Other than that, There were corrections in Fibonacci calculation formula as you can see.
In GetPisanoPeriod The control has to start from 2. otherwise it would always return 0.
/* Dynamic Programming implementation of LCS problem */
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<set>
using namespace std;
/* Returns length of LCS for X[0..m-1], Y[0..n-1] */
int** lcs( char *X, char *Y, int m,int n)
{
int **L;
L = new int*[m];
/* Following steps build L[m+1][n+1] in bottom up fashion. Note
that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1] */
for (int i=0; i<=m; i++)
{
L[i] = new int[n];
for (int j=0; j<=n; j++)
{
if (i == 0 || j == 0)
L[i][j] = 0;
else if (X[i-1] == Y[j-1])
L[i][j] = L[i-1][j-1] + 1;
else
L[i][j] = max(L[i-1][j], L[i][j-1]);
}
}
return L;
}
void printlcs(char *X, char *Y,int m,int n,int *L[],string str)
{
if(n==0 || m==0)
{ cout<<str<<endl;
return ;
}
if(X[m-1]==Y[n-1])
{ str= str + X[m-1];
//cout<<X[m-1];
m--;
n--;
printlcs(X,Y,m,n,L,str);
}else if(L[m-1][n]==L[m][n-1]){
string str1=str;
printlcs(X,Y,m-1,n,L,str);
printlcs(X,Y,m,n-1,L,str1);
}
else if(L[m-1][n]<L[m][n-1])
{
n--;
printlcs(X,Y,m,n,L,str);
}
else
{
m--;
printlcs(X,Y,m,n,L,str);
}
}
/* Driver program to test above function */
int main()
{
char X[] = "afbecd";
char Y[] = "fabced";
int m = strlen(X);
int n = strlen(Y);
int **L;
L=lcs(X, Y,m,n);
string str="";
printlcs(X,Y,m,n,(int **)L,str);
return 0;
}
This is the program for print all possible longest common sub-sequences. If we give input char X[] = "afbecd";char Y[] = "fabced"; then it was showing following error, while for input char X[] = "afbec";char Y[] = "fabce" it is working fine.
solution: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.
Can please anyone figure out why this strange behaviour is occuring. Thanks
In lcs function you have out of array bounds during iteration over L array in for loop. L is array of length m:
int **L;
L = new int*[m];
in this loop:
for (int i=0; i<=m; i++)
{
L[i] = new int[n];
you access L[m] element when i == m. It's Undefined Behavior, as arrays indexed from 0 and this is access to the m + 1 element.
Same problem is in the next loop during access to n + 1 element in L[i] array of length n:
for (int j=0; j<=n; j++)
{
// Code skipped
L[i][j] = 0;