how to iterate one value twice in for loop (Python) - for-loop

I am having a problem in really simple program. My problem is that i lose value (y = 50 or 100 or 150) because at that time first condition is not valid. so how can i repeat loop for let say y = 50. (i don't want to use '=' e.g y< = (50+increment) because this is just a dummy program.
thanks
increment = 0
b = 1
var = 0
for y in range(1,1000):
if y>= increment and y< (50+increment):
print(f'{y} in List {b}')
else:
var = y
increment += 50
b+=1

Related

speed up loop in matlab

I'm very new in MATLAB (this is my first script).
I wonder how may I speed up this loop, I don't know any toolbox or 'tricks' as I'm a newbie on it. I tried to code it with instinct, it works, but it is really long.
All are variables get with fread or integer manually entered, so this is basically simple math, but I have no clue on why is it so long (maybe nested loops ?) and how to improve, as I am more familiar with Python and for example multiprocess.
Thanks a lot
X = 0;
Points = [0,0,0];
for i=1:nbLines
for j=1:nbPositions-1
if lDate(i)>posDate(j) && lDate(i)<=posDate(j+1)
weight = (lDate(i) - posDate(j)) / (posDate(j+1)- posDate(j));
X = posX(j)*(1-weight) + posX(j+1) * weight;
end
end
if X ~= 0
for j=1:nbScans
Y = - distance(i,j) / tan(angle(i,j));
Points = [Points;X, Y, distance(i,j)];
end
end
end
X = 0;
Points = cell([],1) ;
Points{1} = [0,0,0];
count = 1 ;
for i=1:nbLines
id = find(lDate(i)>posDate & lDate(i)<=posDate) ;
if length(id) > 1
weight = (lDate(i) - posDate(id(1))) / (posDate(id(end))- posDate(id(1)));
X = posX(id(1))*(1-weight) + posX(id(end)) * weight;
end
if X ~= 0
j=1:nbScans ;
count = count+1 ;
Y = - distance(i,j)./tan(angle(i,j));
Points{count} = [repelem(X,size(Y,2),size(Y),1), Y, distance(i,j)'];
end
end
You have one issue with the given code. The blow line:
Points = [Points; X, Y, distance(i,j)];
This will definitely slow up your code. You need to initialize this array to store the numbers. If you initialize it, you will find good difference in speed.
X = 0;
Points = zeros([],3) ;
Points(1,:) = [0,0,0];
count = 1 ;
for i=1:nbLines
for j=1:nbPositions-1
if lDate(i)>posDate(j) && lDate(i)<=posDate(j+1)
weight = (lDate(i) - posDate(j)) / (posDate(j+1)- posDate(j));
X = posX(j)*(1-weight) + posX(j+1) * weight;
end
end
if X ~= 0
for j=1:nbScans
count = count+1 ;
Y = - distance(i,j) / tan(angle(i,j));
Points(count,:) = [X, Y, distance(i,j)];
end
end
end
Note that, you code only saves the last value of X, is this what you want?
try using parallelization- "parfor" instead of "for" that uses all available processors.
parfor i=1:nbLines
rest of code here
end

Hill Climbing Algorithm for finding Maxima in MATALB

I am trying to make a program in MATLAB in which we have to find the maxima.
The algorithm which I am using is compare the given point with two adjacent points.
If the next point is greater than the present , iterate in positive direction.
If the next point is smaller than the present, iterate in the negative direction.
If the previous point and the next point are less than the present, maxima reached.
I have made a while loop with flag variable.But it is not able to detect the maxima.
I intialize x to some number intially (say x = 0)
The function 'f(x) = -x^2 -3;'
The variable 'xint ' is the interval which is set to say 0.1.
The variable 'i' is just to keep a count.
clc
clear all
syms x
f(x) = -x^2+3;
max = 0;
x = 0;
xint = 0.1;
flag =1;
while(flag ==1)
fprintf('\ninside while\n')
if(f(x+xint)> f(x))
x = x + xint;
fprintf('inside first: Value of x is set to = %f, where function value is %f', x, f(x));
elseif(f(x+xint) < f(x))
x = x-xint;
fprintf('inside second: Value of x is set to = %f, where function value is %f', x, f(x));
else if(f(x-xint)<f(x) & f(x+xint) < f(x))
disp('Max detected')
max = x;
flag =0;
end
i = i+1;
end
Any help will be of use to me.
Thank You very much.
Anupam
Input :
f(x) = -x^2 +3;
Output:
The program does not enter into the third else if statement.And thus while loop keeps running.
You can't have a condition for the else clause. Additionally, if you were to make the else into an elseif it was be unreachable as the condition you wrote there can I be true when the condition you have for the previous elseif is true, but in a if-elseif statements only one clause gets executed every time.
Change the condition of the elseif and get to of the condition for the else:
elseif(f(x-xint) > f(x))
x = x-xint;
fprintf('inside second: Value of x is set to = %f, where function value is %f', x, f(x));
else
disp('Max detected')
max = x;
flag =0;
end
I am assuming xint is a positive value and your function is second degree polinomial with negative constant (i.e. y = a*x^2+b where a < 0), then:
if f(x+xint) > f(x) % go to right.
x1 = x+xint;
else % go to left
x1 = x
xint = -xint;
end
while f(x1) > f(x1+xint)
x1 = x1+xint;
end
Here x1 is maxima or something very close to it.

Why is my Julia shared array code running so slow?

I'm trying to implement Smith-Waterman alignment in parallel using Julia (see: Figure 1 of http://www.cs.virginia.edu/~rl6sf/paper_dump/2011:12:33:22.pdf), but the algorithm is running much slower in Julia than the serial version. I'm using shared arrays to do this and figure I am doing something silly that is making the code run slow. Could someone take a look and see if my code is optimized as possible? The parallel version should run faster than in serial….
The basic concept of it is to compute the anti-diagonal elements of a matrix in parallel from the upper left to lower right corner and to update them. I'm trying to use 32 cores on a shared array machine to do this. I have a SharedArray matrix that I am using to do this and am computing the elements of each anti-diagonal in parallel as shown below. The while loops in the spSW function submit tasks to workers in sync for each anti-diagonal using the helper function shared_get_score(). The main goal of this function is to fill in each element in the shared arrays "matrix" and "path".
function spSW(seq1,seq2,p)
indel = -1
match = 2
seq1 = "^$seq1"
seq2 = "^$seq2"
col = length(seq1)
row = length(seq2)
wl = workers()
matrix,path = shared_initialize_path(seq1,seq2)
for j = 2:col
jcol = j
irow = 2
#sync begin
count = 0
while jcol > 1 && irow < row + 1
#println(j," ",irow," ",jcol)
if seq1[jcol] == seq2[irow]
equal = true
else
equal = false
end
w = wl[(count % p) + 1]
#async remotecall_wait(w,shared_get_score!,matrix,path,equal,indel,match,irow,jcol)
jcol -= 1
irow += 1
count += 1
end
end
end
for i = 3:row
jcol = col
irow = i
#sync begin
count = 0
while irow < row+1 && jcol > 1
#println(j," ",irow," ",jcol)
if seq1[jcol] == seq2[irow]
equal = true
else
equal = false
end
w = wl[(count % p) + 1]
#async remotecall_wait(w,shared_get_score!,matrix,path,equal,indel,match,irow,jcol)
jcol -= 1
irow += 1
count += 1
end
end
end
return matrix,path
end
The other helper functions are:
function shared_initialize_path(seq1,seq2)
col = length(seq1)
row = length(seq2)
matrix = convert(SharedArray,fill(0,(row,col)))
path = convert(SharedArray,fill(0,(row,col)))
return matrix,path
end
#everywhere function shared_get_score!(matrix,path,equal,indel,match,i,j)
pathvalscode = ["-","|","M"]
pathvals = [1,2,3]
scores = []
push!(scores,matrix[i,j-1]+indel)
push!(scores,matrix[i-1,j]+indel)
if equal
push!(scores,matrix[i-1,j-1]+match)
else
push!(scores,matrix[i-1,j-1]+indel)
end
val,ind = findmax(scores)
if val < 0
matrix[i,j] = 0
else
matrix[i,j] = val
end
path[i,j] = pathvals[ind]
end
Does anyone see an obvious way to make this run faster? Right now it's about 10 times slower than the serial version.

split rectangle in cells / random coordinates / store in array in FORTRAN

I would like to split a rectangle in cells. In each cell it should be create a random coordinate (y, z).
The wide and height of the rectangle are known (initialW / initalH).
The size of the cells are calculated (dy / dz).
The numbers, in how many cells the rectangle to be part, are known. (numberCellsY / numberCellsZ)
Here my Code in Fortran to split the rectangle in Cells:
yRVEMin = 0.0
yRVEMax = initialW
dy = ( yRVEMax - yRVEMin ) / numberCellsY
zRVEMin = 0.0
zRVEMax = initialH
dz = ( zRVEMax - zRVEMin ) / numberCellsZ
do i = 1, numberCellsY
yMin(i) = (i-1)*dy
yMax(i) = i*dy
end do
do j = 1, numberCellsZ
zMin(j) = (j-1)*dz
zMax(j) = j*dz
end do
Now I would like to produce a random coordinate in each cell. The problem for me is, to store the coodinates in an array. It does not necessarily all be stored in one array, but as least as possible.
To fill the cells with coordinates it should start at the bottom left cell, go through the rows (y-direction), and after the last cell (numberCellsY) jump a column higher (z-dicrection) and start again by the first cell of the new row at left side. That should be made so long until a prescribed number (nfibers) is reached.
Here a deplorable try to do it:
call random_seed
l = 0
do k = 1 , nfibers
if (l < numberCellsY) then
l = l + 1
else
l = 1
end if
call random_number(y)
fiberCoordY(k) = yMin(l) + y * (yMax(l) - yMin(l))
end do
n = 0
do m = 1 , nfibers
if (n < numberCellsZ) then
n = n + 1
else
n = 1
end if
call random_number(z)
fiberCoordZ(m) = zMin(n) + z * (zMax(n) - zMin(n))
end do
The output is not what I want! fiberCoordZ should be stay on (zMin(1) / zMax(1) as long as numberCellsY-steps are reached.
The output for following settings:
nfibers = 9
numberCellsY = 3
numberCellsZ = 3
initialW = 9.0
initialH = 9.0
My random output for fiberCoordY is:
1.768946 3.362770 8.667685 1.898700 5.796713 8.770239 2.463412 3.546694 7.074708
and for fiberCoordZ is:
2.234807 5.213032 6.762228 2.948657 5.937295 8.649946 0.6795220 4.340364 8.352566
In this case the first 3 numbers of fiberCoordz should have a value between 0.0 and 3.0. Than number 4 - 6 a value between 3.0 and 6.0. And number 7 - 9 a value bewtween 6.0 - 9.0.
How can I solve this? If somebody has a solution with a better approach, please post it!
Thanks
Looking at
n = 0
do m = 1 , nfibers
if (n < numberCellsZ) then
n = n + 1
else
n = 1
end if
call random_number(z)
fiberCoordZ(m) = zMin(n) + z * (zMax(n) - zMin(n))
end do
we see that the z coordinate offset (the bottom cell boundary of interest) is being incremented inappropriately: for each consecutive nfibers/numberCellsZ coordinates n should be constant.
n should be incremented only every numberCellsY iterations, so perhaps a condition like
if (MOD(m, numberCellsY).eq.1) n=n+1
would be better.
Thanks francescalus! It works fine.
I added a little more for the case that nfibers > numberCellsY*numberCellsZ
n=0
do m = 1 , nfibers
if (MOD(m, numberCellsY).eq.1 .and. (n < numberCellsY)) then
n=n+1
end if
if (MOD(m, numberCellsY*numberCellsZ).eq.1 ) then
n = 1
end if
call random_number(z)
fiberCoordZ(m) = zMin(n) + z * (zMax(n) - zMin(n))
end do

Jython (JES) - Function for rotating a picture [duplicate]

I need to write a function spin(pic,x) where it will take a picture and rotate it 90 degrees counter clockwise X amount of times. I have just the 90 degree clockwise rotation in a function:
def rotate(pic):
width = getWidth(pic)
height = getHeight(pic)
new = makeEmptyPicture(height,width)
tarX = 0
for x in range(0,width):
tarY = 0
for y in range(0,height):
p = getPixel(pic,x,y)
color = getColor(p)
setColor(getPixel(new,tarY,width-tarX-1),color)
tarY = tarY + 1
tarX = tarX +1
show(new)
return new
.. but I have no idea how I would go about writing a function on rotating it X amount of times. Anyone know how I can do this?
You could call rotate() X amount of times:
def spin(pic, x):
new_pic = duplicatePicture(pic)
for i in range(x):
new_pic = rotate(new_pic)
return new_pic
a_file = pickAFile()
a_pic = makePicture(a_file)
show(spin(a_pic, 3))
But this is clearly not the most optimized way because you'll compute X images instead of the one you are interested in. I suggest you try a basic switch...case approach first (even if this statement doesn't exists in Python ;):
xx = (x % 4) # Just in case you want (x=7) to rotate 3 times...
if (xx == 1):
new = makeEmptyPicture(height,width)
tarX = 0
for x in range(0,width):
tarY = 0
for y in range(0,height):
p = getPixel(pic,x,y)
color = getColor(p)
setColor(getPixel(new,tarY,width-tarX-1),color)
tarY = tarY + 1
tarX = tarX +1
return new
elif (xx == 2):
new = makeEmptyPicture(height,width)
# Do it yourself...
return new
elif (xx == 3):
new = makeEmptyPicture(height,width)
# Do it yourself...
return new
else:
return pic
Then, may be you'll be able to see a way to merge those cases into a single (but more complicated) double for loop... Have fun...

Resources