I got the following code:
p = B[m] & B[m + 5] & B[m + 6] & B[m + 11];
m -= d * (l > 0) * 11 + !d * (c % 5 > 0);
p += m ^ M ? B[m] & B[m + 5] & B[m + 6] & B[m + 11] : 0;
I know it's hard to read, but here's a TL;DR for it : I check multiple bits (all are related to m) in a bitset, then i change the value of variable m and i check again (other bits). Is there a way i can acces those bits in less code, or to template the check (cuz are the same formulas for bits)?
B[m] & B[m + 5] & B[m + 6] & B[m + 11]
Thank you :D.
I suggest using a function to precompute a helper bitset for that:
bitset<99> prepare_bitset(const bitset<99>& B)
{
return B & (B<<5) & (B<<6) & (B<<11);
}
Then you can just use it like this:
auto HB = prepare_bitset(B);
p = HB[m];
m -= d * (l > 0) * 11 + !d * (c % 5 > 0);
p += m ^ M ? HB[m] : 0;
UPD: Another option is to just define HB in place:
auto HB = B & (B<<5) & (B<<6) & (B<<11);
p = HB[m];
m -= d * (l > 0) * 11 + !d * (c % 5 > 0);
p += m ^ M ? HB[m] : 0;
Make a function that takes B and m.
So p = yourFunc(B, m) and p += m ^M ? yourFunc(B, m) : 0
The function is something like:
TYPEOFP yourFunc(TYPEOFB b, TYPEOFM m) {
return b[m] & b[m + 5] & b[m + 6] & b[m + 11];
}
I don't know your types, so you need to fill it in.
I wouldn't recommend a macro, but if you want that it's
#define yourMACRO(b, m) ((b)[(m)] & (b)[(m) + 5] & (b)[(m) + 6] & (b)[(m) + 11])
All of those extra parens are to protect you if you ever pass in an expression for b or m. The macro will fail if you pass in something with side-effects (like ++m).
EDIT: From your comments, you said you can't write outside the function.
It's unorthodox, but you can do the #define in the function and #undef it at the end of the function.
Depending on the version of C++ you have, you might have lambdas, which let you make function expressions.
If you are desperate, you can define an inner class or struct with a static function: C++ can we have functions inside functions?
Related
I Have this formula:
(n - 1)! ((n (n - 1))/2 + ((n - 1) (n - 2))/4)
2<=n<=100000
I would like to modulate the result of this from this formula by any modulo, but for the moment let's assume that it is constant, MOD = 999999997. Unfortunately I can't just calculate the result and modulate it, because unfortunately I don't have variables larger than 2^64 at my disposal, so the main question is. What factors to modulate by MOD to get the results%MOD ?
Now let's assume that n=19. What is in brackets is equal to 247.5
18! = 6402373705728000.
(6402373705728000 * 247.5)mod999999997 = 921442488.
Unfortunately, in case I modulate 18! first, the result will be wrong, because (18!)mod999999997 = 724935119. (724935119 * 247.5)mod9999997 = 421442490.
How to solve this problem?
I think the sum could be break down. The only tricky part here is that (n - 1)(n - 2)/4 may have a .5 decimal., as n(n-1) / 2 will always be integer.
S = (n - 1)! * ((n (n - 1))/2 + ((n - 1) (n - 2))/4)
= [(n-1)! * (n*(n-1)/2)] + [(n-1)! * (n-1)(n-2)/4]
= A + B
A is easy to do. With B, if (n-1)(n-2) % 4 == 0 then there's nothing else either, else you can simplified to X/2, as (n-1)(n-2) is also divisible by 2.
If n = 2, it's trivial, else if n > 2 there's always a 2 in the representation of (N-1)! = 1x2x3x ... xN. In that case, simply calculate ((N-1)!/2) = 1x3x4x5x ... xN.
Late example:
N = 19
MOD = 999999997
--> 18! % MOD = 724935119 (1)
(18!/2) % MOD = 862467558 (2)
n(n-1)/2 = 171 (3)
(n-1)(n-2)/2 = 153 (4)
--> S = (1)*(3) + (2)*(4) = 255921441723
S % MOD = 921442488
On another note, if mod is some prime number, like 1e9+7, you can just apply Fermat's little theorem to calculate multiplicative inverse as such:
(a/b) % P = [(a%P) * ((b^(P-2)) % P)] % P (with P as prime, a and b are co-prime to P)
You will have to use 2 mathematical formulas here:
(a + b) mod c == (a mod c + b mod c) mod c
and
(a * b) mod c == (a mod c * b mod c) mod c
But those are only valid for integers. The nice part here is that formula can only be integer for n >= 2, provided you compute it as:
(((n - 1)! * n * (n - 1))/2) + (((n - 1)! * (n - 1) * (n - 2))/4)
1st part is integer | 2nd part is too
for n == 2, first part boils down to 1 and second is 0
for n > 2 either n or n-1 is even so first part is integer, and again eithe n-1 of n-2 is even and (n-1)! is also even so second part is integer. As your formula can be rewritten to only use additions and multiplications it can be computed.
Here is a possible C++ code (before unsigned long long is required):
#include <iostream>
template<class T>
class Modop {
T mod;
public:
Modop(T mod) : mod(mod) {}
T add(T a, T b) {
return ((a % mod) + (b % mod)) % mod;
}
T mul(T a, T b) {
return ((a % mod) * (b % mod)) % mod;
}
int fact_2(T n) {
T cr = 1;
for (T i = 3; i <= n; ++i) {
cr = mul(cr, i);
}
return cr;
}
};
template<class T>
T formula(T n, T mod) {
Modop<T> op = mod;
if (n == 2) {
return 1;
}
T second, first = op.mul(op.fact_2(n - 1), op.mul(n, n - 1));
if (n % 2 == 0) {
second = op.mul(op.fact_2(n - 1), op.mul((n - 2)/ 2, n - 1));
}
else {
second = op.mul(op.fact_2(n - 1), op.mul(n- 2, (n - 1) / 2));
}
return op.add(first, second);
}
int main() {
std::cout << formula(19ull, 999999997ull) << std::endl;
return 0;
}
First of All , for n=2 we can say that the result is 1.
Then, the expression is equal to: (n*(n-1)(n-1)!)/2 + (((n-1)(n-2)/2)^2)*(n-3)! .
lemma: For every two consecutive integer number , one of them is even.
By lemma we can understand that n*(n-1) is even and also (n-1)*(n-2) is even too. So we know that the answer is an integer number.
First we calculate (n*(n-1)(n-1)!)/2 modulo MOD. We can calculate (n(n-1))/2 that can be saved in a long long variable like x, and we get the mod of it modulo MOD:
x = (n*(n-1))/2;
x %= MOD;
After that for: i (n-1 -> 1) we do:
x = (x*i)%MOD;
And we know that both of 'x' and 'i' are less than MOD and the result of
multiplication can be save in a long long variable.
And likewise we do the same for (((n-1)(n-2)/2)^2)(n-3)! .
We calculate (n-1)*(n-2)/2 that can be save in a long long variable like y, and we get the mod of it modulo MOD:
y = ((n-1)*(n-2))/2;
y %= MOD;
And after that we replace (y^2)%MOD on y because we know that y is less than MOD and y*y can be save in a long long variable:
y = (y*y)%MOD;
Then like before for: i (n-3 -> 1) we do:
y = (y*i)%MOD;
And finally the answer is (x+y)%MOD
Is there a canonical way of declaring a function by parts in Sympy? I tried
import sympy
import sympy.functions.special.delta_functions as special
sympy.init_printing()
x = sympy.symbols('x', real=True)
V = x*x * (special.Heaviside(x + 1) - special.Heaviside(x - 1)) \
+ (1 + 2*sympy.log(x)) * special.Heaviside(x - 1) \
+ (1 + 2*sympy.log(-x)) * special.Heaviside(-x - 1)
which defines a differentiable function, but
print(V.diff(x).simplify())
# Prints: (x*(x**2*(-DiracDelta(x - 1) + DiracDelta(x + 1)) - 2*x*(Heaviside(x - 1) - Heaviside(x + 1)) - (2*log(-x) + 1)*DiracDelta(x + 1) + (2*log(x) + 1)*DiracDelta(x - 1)) + 2*Heaviside(-x - 1) + 2*Heaviside(x - 1))/x
Is there a way to somehow tell Sympy to simplify DiracDelta(x - a)*f(x) to DiracDelta(x - a)*f(a)?
Piecewise-defined functions are implemented by Piecewise class. Your function would be expressed as
V = sympy.Piecewise((1 + 2*sympy.log(-x), x < -1),
(x**2, x < 1),
(1 + 2*sympy.log(x), True))
print(V.diff(x))
which prints Piecewise((2/x, x < -1), (2*x, x < 1), (2/x, True))
The (expr, cond) pairs in Piecewise are processed in the order given: the first cond that evaluates to True (if the preceding evaluated to False) causes the corresponding expr to be returned.
This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 7 years ago.
Suppose we have this expression:
#define cube(x) x * x * x
And then we call it:
int n = 3, v;
v = cube(n + 1); // v = 10
v = cube((n + 1)); // v = 64
v = cube(n); // v = 27
So the question is: why first operation do not make v = 64?
Macros are not evaluated (in the sense of the common interpretation of evaluation), they are expanded at compile time.
Before the file is compiled, there is another program called the C Preprocessor that replaces the macro invocation literally/textually and prepares the file for actual compilation, so for your macro
#define cube(x) x * x * x when you do this
This
v = cube(n + 1);
is replaced with this (expaned is the correct term)
v = n + 1 * n + 1 * n + 1;
// Simplifies to
v = n + n + n + 1;
// and again
v = 3 * n + 1;
which for n = 3 gives you 10 exactly the observed result.
Note, that when you add parentheses
v = cube((n + 1));
then, the expansion is
v = (n + 1) * (n + 1) * (n + 1);
which is what you would expect cube() to do, so prevent this you should redefine your macro like this
#define cube(x) ((x) * (x) * (x))
If you are using gcc try
gcc -E source.c
and check the result to verify how the macro was expanded.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
So this RT code creates a 3D image, with blur, through raw code. How is that actually done without any modelling tools?
I am currently working to understand how RT work and different ways to implement them, so this was kind of cool to see such a small amount of code producing a pretty impressive 3D image.
#include <stdlib.h> // card > aek.ppm
#include <stdio.h>
#include <math.h>
#include <fstream>
typedef int i;
typedef float f;
struct v {
f x, y, z;
v operator+(v r) {
return v(x + r.x, y + r.y, z + r.z);
}
v operator*(f r) {
return v(x * r, y * r, z * r);
}
f operator%(v r) {
return x * r.x + y * r.y + z * r.z;
}
v() {}
v operator^(v r) {
return v(y * r.z - z * r.y, z * r.x - x * r.z, x * r.y - y * r.x);
}
v(f a, f b, f c) {x = a; y = b; z = c;}
v operator!() {
return*this * (1 / sqrt(*this % *this));
}
};
i G[] = {247570, 280596, 280600, 249748, 18578, 18577, 231184, 16, 16};
f R()
{
return(f)rand() / RAND_MAX;
}
i T(v o, v d, f&t, v&n)
{
t = 1e9; i m = 0;
f p = -o.z / d.z;
if(.01 < p)t = p, n = v(0, 0, 1), m = 1;
for(i k = 19; k--;)
for(i j = 9; j--;)if(G[j] & 1 << k) {
v p = o + v(-k, 0, -j - 4);
f b = p % d, c = p % p - 1, q = b * b - c;
if(q > 0) {
f s = -b - sqrt(q);
if(s < t && s > .01)
t = s, n = !(p + d * t), m = 2;
}
}
return m;
} v S(v o, v d)
{
f t;
v n;
i m = T(o, d, t, n);
if(!m)return v(.7, .6, 1) * pow(1 - d.z, 4);
v h = o + d * t, l = !(v(9 + R(), 9 + R(), 16) + h * -1), r = d + n * (n % d * -2);
f b = l % n; if(b < 0 || T(h, l, t, n))b = 0;
f p = pow(l % r * (b > 0), 99);
if(m & 1) {
h = h * .2;
return((i)(ceil(h.x) + ceil(h.y)) & 1 ? v(3, 1, 1) : v(3, 3, 3)) * (b * .2 + .1);
} return v(p, p, p) + S(h, r) * .5;
} i
main()
{
FILE * pFile;
pFile = fopen("d:\\myfile3.ppm", "w");
fprintf(pFile,"P6 512 512 255 ");
v g = !v(-6, -16, 0), a = !(v(0, 0, 1) ^ g) * .002, b = !(g ^ a) * .002, c = (a + b) * -256 + g;
for(i y = 512; y--;)
for(i x = 512; x--;) {
v p(13, 13, 13);
for(i r = 64; r--;) {
v t = a * (R() - .5) * 99 + b * (R() - .5) * 99;
p = S(v(17, 16, 8) + t, !(t * -1 + (a * (R() + x) + b * (y + R()) + c) * 16)) * 3.5 + p;
}
fprintf(pFile, "%c%c%c", (i)p.x, (i)p.y, (i)p.z);
}
}
My dear friend that's Paul Heckbert code's right?
You could at least mention it.
For people thinking this code is unreadable, here is why:
This guy made a code that could fit on a credit card, that was the goal :)
His website: http://www.cs.cmu.edu/~ph/
Edit: Knowing the source of this code may help you understand it. Even if it'snot your main motivation...
If you are really interested in raytracing, start with other sources.
Take a look at this website http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-1-writing-a-simple-raytracer/source-code/ (Plus it talk about your code)
This code is not really special. It is basically a ray tracer that was obfuscated into a form that makes it fit on a business card (see https://www.cs.cmu.edu/~ph/).
How is that actually done without any modelling tools?
You don't need tools to render anything. You could even create a complete game of WoW (or what's hip at the moment) without any modelling tool. Modelling tools just make your live easier w.r.t. certain kinds of scenes (read: very complex ones).
You could always hardcode these data, or hack them manually into some external file.
You could also use parametric generators; Perlin Noise is one of the more popular examples thereof.
In a ray tracer, it happens that it is very simple to start out without modelling tools, as it is very simple to calculate geometric intersections between the rendering primitive "ray" and any finite geometric primitive. E.g., intersection a non-approximated, "perfect" sphere is just a few lines of code.
tl;dr: Data is just data. How you create and crunch it is completely up to you.
what will be the output of following code
int x,a=3;
x=+ +a+ + +a+ + +5;
printf("%d %d",x,a);
ouput is: 11 3. I want to know how? and what does + sign after a means?
I think DrYap has it right.
x = + + a + + + a + + + 5;
is the same as:
x = + (+ a) + (+ (+ a)) + (+ (+ 5));
The key points here are:
1) c, c++ don't have + as a postfix operator, so we know we have to interpret it as a prefix
2) monadic + binds more tightly (is higher precedence) than dyadic +
Funny isn't it ? If these were - signs it wouldn't look so strange. Monadic +/- is just a leading sign, or to put it another way, "+x" is the same as "0+x".
The + after a just gets seen as a + before the next value. If you use consistent spacing it is the same as:
x = + + a + + + a + + + 5;
But not all the +s are necessary so it will act the same as doing:
x = a + a + 5;
The value of a is unchanged because you have never used the incrementing operator which is ++ with no white space between the two + symbols. + and ++ are two separate operators.
Since the + operators are never two next to each other but always separated by a white space the statement
x=+ +a+ + +a+ + +5; is actually read as
x=+ (nothing)+a+(nothing) +(nothing) +a+(nothing) +(nothing) +5;
so basically the final equation becomes of the sort
x=a+a+5; and hence the result.
The code seems to be equivalent to:
x= (+(+(a)))+ (+ (+(a)))+ (+(+(5)));
I.e. x = a + a + 5. Which is 11. You know that you can put + or - sign before number, right? Now those + merely indicate sign of variable. Since sign is +, variable remains unchanged I.e. "+5" means "5", so "+a" means "a", and "+ +a" means "+(+a)" which means "a". In same fashion you could write x = + + + 3 + + + + 3 + + + + 5. Or x = - + + - 3 + - + - 3 - - + 5;.
x=+ +a+ + +a+ + +5 : This is equivalent to
x = x=+ +a+ + +a+ + +5 or
we can write it as x = + (+ a) + (+ (+ a)) + (+ (+ 5))
and the +'s are only indicating the signs which will be finally evaluated as
x = a + a + 5.