while loops in Stata - loops

I am trying to create some loop to avoid having too many line code.
Here is my current code. There are many redundancy, any way I can write it with a single loop? Many thanks!
replace WTP_ph = +87.5 if WTP_ph == -76
replace WTP_ph = +62.5 if WTP_ph == -50
replace WTP_ph = +37.5 if WTP_ph == -25
replace WTP_ph = +12.5 if WTP_ph == 0
replace WTP_ph = -12.5 if WTP_ph == +25
replace WTP_ph = -37.5 if WTP_ph == +50
replace WTP_ph = -62.5 if WTP_ph == +75
replace WTP_ph = -87.5 if WTP_ph == +76
replace WTP_pe = +87.5 if WTP_pe == -76
replace WTP_pe = +62.5 if WTP_pe == -50
replace WTP_pe = +37.5 if WTP_pe == -25
replace WTP_pe = +12.5 if WTP_pe == 0
replace WTP_pe = -12.5 if WTP_pe == +25
replace WTP_pe = -37.5 if WTP_pe == +50
replace WTP_pe = -62.5 if WTP_pe == +75
replace WTP_pe = -87.5 if WTP_pe == +76
replace WTP_pa = +87.5 if WTP_pa == -76
replace WTP_pa = +62.5 if WTP_pa == -50
replace WTP_pa = +37.5 if WTP_pa == -25
replace WTP_pa = +12.5 if WTP_pa == 0
replace WTP_pa = -12.5 if WTP_pa == +25
replace WTP_pa = -37.5 if WTP_pa == +50
replace WTP_pa = -62.5 if WTP_pa == +75
replace WTP_pa = -87.5 if WTP_pa == +76

This is a start
foreach v in WTP_ph WTP_pe WTP_pa {
replace `v' = 87.5 if `v' == -76
replace `v' = 62.5 if `v' == -50
replace `v' = 37.5 if `v' == -25
replace `v' = 12.5 if `v' == 0
replace `v' = -12.5 if `v' == 25
replace `v' = -37.5 if `v' == 50
replace `v' = -62.5 if `v' == 75
replace `v' = -87.5 if `v' == 76
}
Then we notice a pattern in the mapping, except that the outermost statements are different, so we could go
foreach v in WTP_ph WTP_pe WTP_pa {
replace `v' = 87.5 if `v' == -76
replace `v' = 12.5 - `v' if inrange(`v', -50, 75)
replace `v' = -87.5 if `v' == 76
}

Related

Difference between if (j%3 != 0 && j%4 != 0) and (!((j%3 == 0) && (j%4 == 0))), and why (!((j%3 == 0) || (j%4 == 0))) works if || means OR

I don't understand why the following syntax are not the same
if (j%3 != 0 && j%4 != 0)
if (!((j%3 == 0) && (j%4 == 0)))
Yet, the followings are.
if (j%3 != 0 && j%4 != 0) /
if (!((j%3 == 0) || (j%4 == 0)))
Why is that
!(A && B) != !A && !B
and
!(A || B) == !A && !B / !(A && B) == !A || !B
This is the mathematic boolean logic.
A and B <=> not (not A or not B)
not A and not B <=> not (A or B)
not (A and B) <=> not A or not B
For proving these equations, use value tables.
0 & 0 = 0 !(1 | 1) = !1 = 0
0 & 1 = 0 !(1 | 0) = !1 = 0
1 & 0 = 0 !(0 | 1) = !1 = 0
1 & 1 = 1 !(0 | 0) = !0 = 1
Say I have a red car and grey house, then "my car is blue and my house is grey" is false (!(A && B)). Yet "my car isn't blue and my house isn't grey" is also false (!(!A && !B)). So !(A && B) and !A && !B clearly aren't equivalent.
The actual negation of "my car is blue and my house is grey" is "my car isn't blue or my house isn't grey" (!A || !B).
We can also clearly see this is the case by plugging all possible values into the equations.
A
B
!(A && B)
!A || !B
!(A || B)
!A && !B
0
0
!(0 && 0) = !0 = 1
!0 || !0 = 1 || 1 = 1
!(0 || 0) = !0 = 1
!0 && !0 = 1 && 1 = 1
0
1
!(0 && 1) = !0 = 1
!0 || !1 = 1 || 0 = 1
!(0 || 1) = !1 = 0
!0 && !1 = 1 && 0 = 0
1
0
!(1 && 0) = !0 = 1
!1 || !0 = 0 || 1 = 1
!(1 || 0) = !1 = 0
!1 && !0 = 0 && 1 = 0
1
1
!(1 && 1) = !1 = 0
!1 || !1 = 0 || 0 = 0
!(1 || 1) = !1 = 0
!1 && !1 = 0 && 0 = 0
Two equivalences that are identified by the above table:
!(A && B) = !A || !B
!(A || B) = !A && !B
These are known as De Morgan's laws.

Julia- Make Array{Float64,3} in a short time

I want to get Array{Float64,3} from a matrix-valued function H(Lx,Ly,Lz) ,where Lx,Ly,Lz are parameters and H is a (Lx×Ly×Lz)×(Lx×Ly×Lz) matrix.
The sample code is
using LinearAlgebra
eye(T::Type,n) = Diagonal{T}(I, n)
eye(n) = eye(Float64,n)
function H(Lx,Ly,Lz) #def of H
N = Lx*Ly*Lz 
 mat_Htb = zeros(Complex{Float64},N,N)
 for iz = 1:Lz
 for ix = 1:Lx
 for iy=1:Ly
 for dz in -1:1
 jz = iz + dz
 for dx in -1:1
 jx = ix + dx
 for dy in -1:1
 jy = iy + dy
 ii = (iz-1)*Lx*Ly + (ix-1)*Ly + (iy-1) + 1
 jj = (jz-1)*Lx*Ly + (jx-1)*Ly + (jy-1) + 1
 if 1 <= jx <= Lx && 1 <= jy <= Ly && 1 <= jz <= Lz
 if dx == +1 && dy == 0 && dz == 0
 mat_Htb[ii,jj] += im  
 end
 if dx == -1 && dy == 0 && dz == 0
 mat_Htb[ii,jj] += im/4  
 end
 if dx == 0 && dy == +1 && dz == 0
 mat_Htb[ii,jj] += im/2
 end
 if dx == 0 && dy == -1 && dz == 0
 mat_Htb[ii,jj] += im
 end
 if dx == 0 && dy == 0 && dz == +1
 mat_Htb[ii,jj] += -im
 end
 if dx == 0 && dy == 0 && dz == -1
 mat_Htb[ii,jj] += im*(3/7)
 end
 if dx == 0 && dy == 0 && dz == 0
 mat_Htb[ii,jj] += im
 end
 end
 end
 end
 end
 end
 end
 end
 return mat_Htb
end
Lx = 10 #systemsize-parameters
Ly = 10
Lz = 10
ψ0 = Complex{Float64}[] #def of \psi0 ,(Lx×Ly×Lz)×1 vector
for iz = 1:Lz
for ix = 1:Lx
for iy=1:Ly
gauss = exp(-((ix-5)^2 + (iy-5)^2 + (iz-5)^2))
push!(ψ0,gauss)
end
end
end
ψ(t) = exp((-im*t).*H(Lx,Ly,Lz))*ψ0 #time-evolution
abs2ψ(t) = abs2.(ψ(t)./norm(ψ(t))) #normalized density
Then, I tried to make an Array{Float64,3} like this.
x = 1:Lx # our value range
y = 1:Ly
z = 1:Lz
t = 15 #time
ρ(ix,iy,iz) = abs2ψ(t)[(iz-1)*Lx*Ly + (ix-1)*Ly + (iy-1) + 1]
density = Float64[ρ(ix,iy,iz) for ix in x, iy in y,iz in z]
H(Lx,Ly,Lz),ψ(t),abs2ψ(t),ρ(ix,iy,iz) are calculated smoothly.
But the density takes about 30 minutes.
Ultimately, I will do loop-calculations for t.
So I want to reduce the calculation time.
Could you tell me how to solve this problem?
There are still numerous things that would probably need to be improved, but the following version should already be much faster than yours.
The key thing to remember is to try and not recompute the same thing several times (especially if it takes some time to compute it, and you're going to re-use the result a large number of times).
In your example, this applies to :
H, which only depends on Lx, Ly and Lz, and as such can be computed once and for all
ψ and abs2ψ, which depend on H and t, and should therefore get updated at each time step -- but can be re-used for all (ix, iy, iz) triplets.
using LinearAlgebra
function H(Lx,Ly,Lz)
N = Lx*Ly*Lz 
mat_Htb = zeros(Complex{Float64},N,N)
for iz = 1:Lz
for ix = 1:Lx
for iy=1:Ly
for dz in -1:1
jz = iz + dz
for dx in -1:1
jx = ix + dx
for dy in -1:1
jy = iy + dy
ii = (iz-1)*Lx*Ly + (ix-1)*Ly + (iy-1) + 1
jj = (jz-1)*Lx*Ly + (jx-1)*Ly + (jy-1) + 1
if 1 <= jx <= Lx && 1 <= jy <= Ly && 1 <= jz <= Lz
if dx == +1 && dy == 0 && dz == 0
mat_Htb[ii,jj] += im
end
if dx == -1 && dy == 0 && dz == 0
mat_Htb[ii,jj] += im/4
end
if dx == 0 && dy == +1 && dz == 0
mat_Htb[ii,jj] += im/2
end
if dx == 0 && dy == -1 && dz == 0
mat_Htb[ii,jj] += im
end
if dx == 0 && dy == 0 && dz == +1
mat_Htb[ii,jj] += -im
end
if dx == 0 && dy == 0 && dz == -1
mat_Htb[ii,jj] += im*(3/7)
end
if dx == 0 && dy == 0 && dz == 0
mat_Htb[ii,jj] += im
end
end
end
end
end
end
end
end
return mat_Htb
end
function run(Lx, Ly, Lz)
ψ0 = Complex{Float64}[] #def of \psi0 ,(Lx×Ly×Lz)×1 vector
for iz = 1:Lz
for ix = 1:Lx
for iy=1:Ly
gauss = exp(-((ix-5)^2 + (iy-5)^2 + (iz-5)^2))
push!(ψ0,gauss)
end
end
end
x = 1:Lx # our value range
y = 1:Ly
z = 1:Lz
t = 15 #time
H_ = H(Lx,Ly,Lz)
ψ = exp((-im*t).*H_)*ψ0 #time-evolution
abs2ψ = abs2.(ψ./norm(ψ)) #normalized density
ρ(ix,iy,iz) = abs2ψ[(iz-1)*Lx*Ly + (ix-1)*Ly + (iy-1) + 1]
density = Float64[ρ(ix,iy,iz) for ix in x, iy in y,iz in z]
end
Lx = 10 #systemsize-parameters
Ly = 10
Lz = 10
run(Lx, Ly, Lz)
For questions like this, which are very specific to a code that you want to optimize, I tend to think that posting on Julia's discourse forum would be more appropriate.

C problem requires to find students semester propably from year and age

I have an exercise where I have as input the name, the age and the current university year of whoever, and it asks the minimum years for him to graduate, the person's age when he graduates and how many semesters till the graduation. How can we find the semester the person is in? Thought I had found a way but it duplicates logical expressions so it's not corrects.
/*My attempt*/
if(age % 2 == 1 && year == 1 || age % 2 == 0 && year == 1)
semester = 1;
else if(age % 2 == 0 && year == 1 || age % 2 == 1 && year == 1)
semester = 2;
else if(age % 2 == 0 && year == 2 || age % 2 == 1 && year == 2)
semester = 3;
else if(age % 2 == 1 && year == 2 || age % 2 == 0 && year == 2)
semester = 4;
else if(age % 2 == 1 && year == 3 || age % 2 == 0 && year == 3)
semester = 5;
else if(age % 2 == 0 && year == 3 || age % 2 == 1 && year == 3)
semester = 6;
else if(age % 2 == 0 && year == 4 || age % 2 == 1 && year == 4)
semester = 7;
else if(age % 2 == 1 && year == 4 || age % 2 == 0 && year == 4)
semester = 8;

Optimize bitflag check

How can I optimize the following code?
( (kbd_flags & KBD_FLAG_SHIFT) && !(kbd_flags & KBD_FLAG_CAPS))
|| (!(kbd_flags & KBD_FLAG_SHIFT) && (kbd_flags & KBD_FLAG_CAPS))
Basically, I want to check if either KBD_FLAG_SHIFT or KBD_FLAG_CAPS is set, but not both.
I would like to share my solution after doing some research. Zodoh's expression can be simplified to
kbd_flags & KBD_FLAG_SHIFT
? !(kbd_flags & KBD_FLAG_CAPS)
: kbd_flags & KBD_FLAG_CAPS
(Omitting unneeded parentheses and the true and false expressions)
Another interesting way I figured out is the following:
x = kbd_flags & (KBD_FLAG_SHIFT | KBD_FLAG_CAPS);
return x && (x & x - 1) == 0;
This works because of the way two's complement notation is designed. As an example, if kbd_flags is set to 001000, x - 1 will be 000111 and 001000 & 000111 is 000000. As a result, 000000 is equal to 0, thus returning true. The first x expression makes sure that the "no bit set" case is excluded.
It will also work with more than only two bit flags:
#define A 0x01
#define B 0x02
#define C 0x04
#define D 0x08
#define E 0x10
#define F 0x20
x = flags & (A | B | C | D | E | F);
return x && (x & x - 1) == 0;
Here, the expression x && (x & x - 1) == 0 will be true if and only if one of the flags A through F is set.
A quick test (f being the integer holding the flags to test for):
int f, x;
for (f = 0; f <= F + 1; f++) {
x = f & (A | B | C | D | E | F);
printf("0x%02x %d%d%d%d%d%d -> %d\n", f
, (f & A) == A, (f & B) == B, (f & C) == C
, (f & D) == D, (f & E) == E, (f & F) == F
, x && (x & x - 1) == 0);
}
This code will output the follwing:
0x00 000000 -> 0
0x01 100000 -> 1
0x02 010000 -> 1
0x03 110000 -> 0
0x04 001000 -> 1
0x05 101000 -> 0
0x06 011000 -> 0
0x07 111000 -> 0
0x08 000100 -> 1
0x09 100100 -> 0
0x0a 010100 -> 0
0x0b 110100 -> 0
0x0c 001100 -> 0
0x0d 101100 -> 0
0x0e 011100 -> 0
0x0f 111100 -> 0
0x10 000010 -> 1
0x11 100010 -> 0
0x12 010010 -> 0
0x13 110010 -> 0
0x14 001010 -> 0
0x15 101010 -> 0
0x16 011010 -> 0
0x17 111010 -> 0
0x18 000110 -> 0
0x19 100110 -> 0
0x1a 010110 -> 0
0x1b 110110 -> 0
0x1c 001110 -> 0
0x1d 101110 -> 0
0x1e 011110 -> 0
0x1f 111110 -> 0
0x20 000001 -> 1
0x21 100001 -> 0
As you can see, x && (x & x - 1) == 0 is true iff one bit is set.
You can use this
(kbd_flags & KBD_FLAG_SHIFT) ? ((kbd_flags & KBD_FLAG_CAPS)? false : true) : ((kbd_flags & KBD_FLAG_CAPS)? true : false)
Else is you know how to use the bits you can use the XOR operator ^.
A = 0000 0001
B = 0000 0000
A ^ B = 0000 0001
A = 0000 0000
B = 0000 0001
A ^ B = 0000 0001
A = 0000 0000
B = 0000 0000
A ^ B = 0000 0000
A = 0000 0001
B = 0000 0001
A ^ B = 0000 0000
To answer more clearly.
(kbd_flags & KBD_FLAG_SHIFT) ^ (kbd_flags & KBD_FLAG_CAPS)
This should work.

Evaluation of this statement

I am reading a C book and don't understand this statement it is asking me to evaluate:
!(1 && !(0 || 1))
I can understand some things here... This is what I have so far, not(1 and not(0 or 1))
So is it not 1 and not 0 or 1? Or is it not 1 and 0 or 1? Do those two ! cancel each other out like a double negative? The answer is true but I expected false.
What is the explanation?
Use De Morgan's laws to simplify the original expression: !(1 && !(0 || 1)). When you negate a parenthetical logical expression, the negation is applied to each operand and the operator is changed.
!(1 && !(0 || 1)) // original expression
!1 || !!(O || 1) // by De Morgan's law
!1 || (0 || 1) // the two !!'s in front of the second operand cancel each other
0 || (0 || 1) // !1 is zero
0 || 1 // the second operand, 0 || 1, evaluates to true because 1 is true
1 // the entire expression is now 0 || 1, which is true
The answer is true.
A couple of other answers have said that the parentheses determine order of evaluation. That is wrong. In C, precedence is not the same as order of evaluation. Precedence determines which operands are grouped by which operators. The exact order of evaluation is unspecified. The logical operators are an exception: they are evaluated in strictly left-to-right order in order to enable short-circuit behavior.
(0 || 1) == 1
!1 == 0
1 && 0 == 0
!0 == 1 also known as true :)
Keep in mind that || and && are short circuit operators, but in this case you still have to evaluate the right side because the operators do not short circuit
!(1 && !(0 || 1)) => not(1 and not(0 or 1))
not(1 and not(0 or 1)) => not(1 and (0 and 1)) // !(a or b) = a and b
not(1 and (0 and 1)) => not(0) => 1 => true
!(1 && !(0 || 1))
=> ! (1 && !(1)) //0 || 1 is 1
=> ! (1 && 0) // !1 is 0
=> !0 // 1 && 0 is 0
=> 1 // !0 is 1
=>true
!(1 && !(0 || 1)) => !(1 && !(1)) => !(1 && !1) => !(1 && 0) => !(0) => !0 => 1(true)
If A =1 A && B = B. So the final expression inside !(....) is !(!(0 || 1)) which is 0 || 1 and 0 + 1 =1, hence the answer is true.
Starting from the deepest nesting and working outwards adding piece by piece;
(0 || 1) = (0 OR 1) = 1
!(0 || 1) = !1 = NOT 1 = 0
1 && !(0 || 1) = 1 && 0 = 1 AND 0 = 0
!(1 && !(0 || 1)) = !0 = NOT 0 = 1
To evaluate this, start with the innermost parentheses and work your way out like so:
not(1 and not(0 or 1)) -> not(1 and not(1)) -> not(1 and 0) -> not(0) -> 1 -> true.
!(1 && !(0 || 1))
since 0 || 1 evaluates as 1, is the same as
!(1 && !1)
continue
!(1 && 0)
continue
!0
so it's 1, true.
(0 || 1) --> 1
! 1 --> 0
1 && 0 --> 0
! 0 -- > 1
Answer true
It easy if you remember about which operation order
!(1 && !(0 || 1)) = !(1 && !(1)) = !(1 && 0) = !(0) = 1

Resources