def rotate(self, x, y, z): # translate so rotating around the origin self.verts = Matrix.translate(self.verts, -self.center[0], -self.center[1], -self.center[2]) self.verts = Matrix.rotate(self.verts, x, y, z) self.verts = Matrix.translate(self.verts, self.center[0], self.center[1], self.center[2])
def fortate(self, a, b, c, d, e, f): self.verts = Matrix.tr4nslate(self.verts, -self.center[0], -self.center[1], -self.center[2], -self.center[3]) self.verts = Matrix.fortate(self.verts, a, b, c, d, e, f) self.verts = Matrix.tr4nslate(self.verts, self.center[0], self.center[1], self.center[2], self.center[3])
def sc4le(self, *args): self.verts = Matrix.tr4nslate(self.verts, -self.center[0], -self.center[1], -self.center[2], -self.center[3]) self.verts = Matrix.sc4le(self.verts, args) self.verts = Matrix.tr4nslate(self.verts, self.center[0], self.center[1], self.center[2], self.center[3])
def __init__(self, inputs, hidden, outputs): self.num_input_nodes = inputs self.num_hidden_nodes = hidden self.num_output_nodes = outputs self.weights_i = Matrix(self.num_hidden_nodes, self.num_input_nodes, True) self.weights_h = Matrix(self.num_output_nodes, self.num_hidden_nodes, True) self.bias_i = Matrix(self.num_hidden_nodes, 1, True) self.bias_h = Matrix(self.num_output_nodes, 1, True)
def generate_finite_diff_mesh(mesh_size, num_free_nodes): """ Generates a finite-difference mesh with the given size and number of free nodes. :param mesh_size: the mesh size :param num_free_nodes: the number of free nodes :return: the A and b matrices defining the mesh equation (Ax = b) """ A = Matrix.empty(num_free_nodes, num_free_nodes) b = Matrix.empty(num_free_nodes, 1) for row in range(mesh_size - 3): for col in range(mesh_size - 1): node = row * (mesh_size - 1) + col A[node][node] = -4 if row != 0: A[node][node - mesh_size + 1] = 1 if 12 <= node <= 14: b[node][0] = -15 else: A[node][node + mesh_size - 1] = 1 # Right Neumann boundary if col == mesh_size - 2: A[node][node - 1] = 2 else: if col != 0: A[node][node - 1] = 1 A[node][node + 1] = 1 # Special nodes A[15][10] = 1 A[15][15] = -4 A[15][16] = 1 A[15][17] = 1 A[16][11] = 1 A[16][15] = 1 A[16][16] = -4 A[16][18] = 1 b[16][0] = -15 A[17][15] = 2 A[17][17] = -4 A[17][18] = 1 A[18][16] = 2 A[18][17] = 1 A[18][18] = -4 b[18][0] = -15 return A, b
def create_network_branch_matrices_mesh(num_branches, branch_resistance, test_current): """ Create the Y, J, E network branch matrices of the resistive mesh given by the provided number of branches, branch resistance and test current. :param num_branches: the number of branches in the mesh :param branch_resistance: the resistance of each branch in the mesh :param test_current: the test current to apply to the mesh :return: the Y, J, E network branch matrices """ Y = Matrix.diagonal([1 / branch_resistance if branch < num_branches - 1 else 0 for branch in range(num_branches)]) # Negative test current here because we assume current is coming OUT of the test current node. J = Matrix.column_vector([0 if branch < num_branches - 1 else -test_current for branch in range(num_branches)]) E = Matrix.column_vector([0 for _ in range(num_branches)]) return Y, J, E
def skip_rows(mat): transposed = mat.transposed() fix_mat = Matrix.identity(mat.rows) unskipped_indexes = [] need_unit_row = False for x, col in enumerate(transposed.content[:-1]): is_prev_value_used = False for y, elem in enumerate(col[:-1]): # Let's explicity check element's equality to zero # (in theory element can have another type than "int") if elem != 0: if y == x and elem == 1: # Variable's value depends from previous value is_prev_value_used = True else: # Variable's value depends from values of another # variables or depends from previous value but used # multiplication break else: if ( # If variable is unchanged (is_prev_value_used and col[-1] == 0) or # Or variable has assigned to constant value not is_prev_value_used): if not is_prev_value_used: handle_mov(fix_mat.content, (VAR, x), (VALUE, col[-1])) for index, elem in enumerate(mat.content[x]): if elem != 0 and index != x: raise MatcodeFoldingError( 'Folded variable is used in calculations ' + 'of another variables') continue unskipped_indexes.append(x) if col[-1] != 0: need_unit_row = True if need_unit_row: unskipped_indexes.append(mat.rows - 1) lite_content = [] for y in unskipped_indexes: row = [] for x in unskipped_indexes: row.append(mat.content[y][x]) lite_content.append(row) return Matrix(lite_content), unskipped_indexes, fix_mat
def __init__(self): self.verts = Matrix([ [0.5, 0.5, 0.5, 0.5], #0 [0.5, 0.5, 0.5, -0.5], #1 [0.5, 0.5, -0.5, 0.5], #2 [0.5, 0.5, -0.5, -0.5], #3 [0.5, -0.5, 0.5, 0.5], #4 [0.5, -0.5, 0.5, -0.5], #5 [0.5, -0.5, -0.5, 0.5], #6 [0.5, -0.5, -0.5, -0.5], #7 [-0.5, 0.5, 0.5, 0.5], #8 [-0.5, 0.5, 0.5, -0.5], #9 [-0.5, 0.5, -0.5, 0.5], #10 [-0.5, 0.5, -0.5, -0.5], #11 [-0.5, -0.5, 0.5, 0.5], #12 [-0.5, -0.5, 0.5, -0.5], #13 [-0.5, -0.5, -0.5, 0.5], #14 [-0.5, -0.5, -0.5, -0.5] #15 ]) self.center = [0, 0, 0, 0] self.edges = [[0, 1], [0, 2], [0, 4], [0, 8], [1, 3], [1, 5], [1, 9], [2, 3], [2, 6], [2, 10], [3, 7], [3, 11], [4, 5], [4, 6], [4, 12], [5, 7], [5, 13], [6, 7], [6, 14], [7, 15], [8, 9], [8, 10], [8, 12], [9, 11], [9, 13], [10, 11], [10, 14], [11, 15], [12, 13], [12, 14], [13, 15], [14, 15]] # it's wrong but unnecessary self.faces = [[1, 2, 3, 4]]
def conjugate_gradient_solve(A, b, residual_vectors=None): """ Solves the Ax = b matrix equation given by the given A and b matrices :param A: the A matrix :param b: the b matrix :param residual_vectors: the list to store the residual vectors in :return: the solved x vector """ n = len(A) x = Matrix.empty(n, 1) r = b - A * x p = deepcopy(r) if residual_vectors is not None: residual_vectors.append(r) for _ in range(n): denom = p.transpose() * A * p alpha = (p.transpose() * r) / denom x = x + p * alpha.item() r = b - A * x beta = -(p.transpose() * A * r) / denom p = r + p * beta.item() if residual_vectors is not None: residual_vectors.append(r) return x
def q1d(): """ Question 1(d): Write a program that reads from a file a list of network branches (Jk, Rk, Ek) and a reduced incidence matrix, and finds the voltages at the nodes of the network. Use the code from part (a) to solve the matrix problem. """ print('\n=== Question 1(d) ===') for i in range(1, 7): A = Matrix.csv_to_matrix('{}/incidence_matrix_{}.csv'.format( NETWORK_DIRECTORY, i)) Y, J, E = csv_to_network_branch_matrices( '{}/network_branches_{}.csv'.format(NETWORK_DIRECTORY, i)) # print('Y: {}'.format(Y)) # print('J: {}'.format(J)) # print('E: {}'.format(E)) x = solve_linear_network(A, Y, J, E) print('Solved for x in network {}:'.format( i)) # TODO: Create my own test circuits here node_numbers = [] voltage_values = [] for j in range(len(x)): print('V{} = {:.3f} V'.format(j + 1, x[j][0])) node_numbers.append(j + 1) voltage_values.append('{:.3f}'.format(x[j][0])) save_rows_to_csv('report/csv/q1_circuit_{}.csv'.format(i), zip(node_numbers, voltage_values), header=('Node', 'Voltage (V)'))
def translationMatrix (x, y = 0, z = 0): if type(x) is Vector: y = x[1] z = x[2] x = x[0] return Matrix([[1, 0, 0, x], [0, 1, 0, y], [0, 0, 1, z], [0, 0, 0, 1]])
def rotate(points, axis, angle, hand="right"): """Takes a set of coordinates and rotates them around one of the axes by a specified angle. The rotation performed is right-handed, unless specified otherwise. The points must be a list (or tuple, or any collection) of coordinates in the form ``(x, y, z)``, *or* a list (etc.) of objects with x(), y() and z() methods. An example would be ``rotate([(1, 1, 1), (2, 2, 2)], "x", 45)``. :param points: A collection of (x, y, z) coordinates or appropriate objects. :param str axis: The axis to rotate around. Accepted values are `"x"`,\ `"y"` or `"z"`. :param number angle: The angle in degrees to rotate by. :param str hand: specifies whether the rotation should be right-handed or\ left-handed. The deafult is 'right'. :returns: The rotated coordinates.""" if not is_numeric: raise TypeError("angle must be numeric, not '%s'" % str(angle)) if not isinstance(hand, str): raise TypeError("hand must be str, not '%s'" % str(hand)) elif hand not in ("left", "right"): raise ValueError("hand must be 'left' or 'right', not %s" % hand) elif hand == "left": angle = -angle angle = radians(angle) points = [create_vertex(*point) for point in points] matrix = None if axis == "x": matrix = Matrix((1, 0, 0), (0, cos(angle), -sin(angle)), (0, sin(angle), cos(angle))) elif axis == "y": matrix = Matrix((cos(angle), 0, sin(angle)), (0, 1, 0), (-sin(angle), 0, cos(angle))) elif axis == "z": matrix = Matrix((cos(angle), -sin(angle), 0), (sin(angle), cos(angle), 0), (0, 0, 1)) else: raise ValueError("axis can only be 'x', 'y' or 'z', not %s" % axis) new_points = [matrix * point for point in points] return tuple([point.columns()[0] for point in new_points])
def q1(): print('\n=== Question 1 ===') S1 = build_triangle_and_find_local_S([0, 0, 0.02], [0.02, 0, 0]) S1.save_to_latex('report/matrices/S1.txt') print('S1: {}'.format(S1)) S2 = build_triangle_and_find_local_S([0.02, 0, 0.02], [0.02, 0.02, 0]) S2.save_to_latex('report/matrices/S2.txt') print('S2: {}'.format(S2)) C = Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1], [1, 0, 0, 0], [0, 0, 1, 0]]) C.save_to_latex('report/matrices/C.txt') print('C: {}'.format(C)) S = find_global_s_matrix(S1, S2, C) S.save_to_latex('report/matrices/S.txt') S.save_to_csv('report/csv/S.txt') print('S: {}'.format(S))
def __init__(self): self.verts = Matrix([[0.5, 0.5, 0.5], [0.5, 0.5, -0.5], [0.5, -0.5, 0.5], [-0.5, 0.5, 0.5], [0.5, -0.5, -0.5], [-0.5, -0.5, 0.5], [-0.5, 0.5, -0.5], [-0.5, -0.5, -0.5]]) self.center = [0, 0, 0] self.edges = [[0, 1], [0, 2], [0, 3], [1, 4], [1, 6], [2, 4], [2, 5], [3, 5], [3, 6], [4, 7], [5, 7], [6, 7]] # should faces point to edges or vertices? I feel like vertices would be easier self.faces = [[0, 1, 3, 6], [0, 1, 2, 4], [0, 2, 3, 5], [1, 4, 6, 7], [2, 4, 5, 7], [3, 5, 6, 7]]
def rank_pref(g1, g2): g1_pref = {} g2_pref = {} for p1_email, p1_response in g1.items(): pref = [] for p2_email, p2_response in g2.items(): pref.append(Match(p2_email, Matrix.weight(p1_response, p2_response))) random.shuffle(pref) pref.sort() g1_pref[p1_email] = pref for p2_email, p2_response in g2.items(): pref = [] for p1_email, p1_response in g1.items(): pref.append(Match(p1_email, Matrix.weight(p2_response, p1_response))) random.shuffle(pref) pref.sort() g2_pref[p2_email] = pref return g1_pref, g2_pref
def __init__(self, size=200): self.SIZE = size self.POINT_RADIUS = 1 if self.SIZE < 400 else 2 self.LINE_WIDTH = 1 if self.SIZE < 400 else 2 self.ARROW_SIZE = 6 if self.SIZE < 400 else 8 self.TRANSFORM = Matrix([[self.SIZE / 20, 0], [0, -self.SIZE / 20]]) self.SHIFT = Vector(self.SIZE / 2, self.SIZE / 2) Canvas.canvasCounter += 1 self.canvasID = "canvas_{}".format(Canvas.canvasCounter) display( Javascript(""" element.append("<canvas id='{}' width={} height={} style='background-color: #f0f0f0'></canvas>") """.format(self.canvasID, self.SIZE, self.SIZE)))
def run_loop(settings, matcode, index, vector_len): mat = Matrix.identity(vector_len) while True: instr = matcode[index] oper = instr[0] if oper == END: return mat, index try: if oper == LOOP: if len(instr) != 2 or instr[1][0] != VALUE: raise InvalidMatcodeError sub_mat, index = run_loop( settings, matcode, index + 1, vector_len, ) need_min_rows = settings['opt_min_rows'] if need_min_rows: rows_count = sub_mat.rows sub_mat, unskipped, fix_mat = skip_rows(sub_mat) cur_mat = sub_mat**instr[1][1] if need_min_rows: cur_mat = restore_rows(cur_mat, unskipped, fix_mat) else: if len(instr) != 3 or instr[1][0] != VAR: raise InvalidMatcodeError cur_mat = Matrix.identity(vector_len) matcode_map[oper](cur_mat.content, instr[1], instr[2]) except (InvalidMatcodeError, KeyError, TypeError) as err: if isinstance(err, InvalidMatcodeError) and err.args: raise err raise InvalidMatcodeError(('Invalid matrix code instruction: %s') % ' '.join(map(repr, instr))) mat *= cur_mat index += 1
def skip_rows(mat): need_unit_row = False unskipped_indexes = [] fix_mat = Matrix.identity(mat.rows) for index in xrange(mat.rows - 1): cur_row = mat.content[index] cur_col = [row[index] for row in mat.content] index_can_be_skipped = False prev_value_coeff = cur_col[index] const_coeff = cur_col[-1] # If an original value of a variable isn't used in calculations of # other variables and a new value doesn't depend on other variables if ( all(elem == 0 for j, elem in enumerate(cur_row) if j != index) and all(elem == 0 for j, elem in enumerate(cur_col[:-1]) if j != index) ): # If a new variable value is a constant if prev_value_coeff == 0: handle_mov(fix_mat.content, (VAR, index), (VALUE, const_coeff)) index_can_be_skipped = True # Or the value wasn't changed elif prev_value_coeff == 1 and const_coeff == 0: index_can_be_skipped = True if not index_can_be_skipped: unskipped_indexes.append(index) if const_coeff != 0: need_unit_row = True if need_unit_row: unskipped_indexes.append(mat.rows - 1) lite_content = [] for y in unskipped_indexes: row = [] for x in unskipped_indexes: row.append(mat.content[y][x]) lite_content.append(row) return Matrix(lite_content), unskipped_indexes, fix_mat
def skip_rows(mat): transposed = mat.transposed() fix_mat = Matrix.identity(mat.rows) unskipped_indexes = [] need_unit_row = False for x, col in enumerate(transposed.content[:-1]): is_prev_value_used = False for y, elem in enumerate(col[:-1]): # Let's explicity check element's equality to zero # (in theory element can have another type than "int") if elem != 0: if y == x and elem == 1: # Variable's value depends from previous value is_prev_value_used = True else: # Variable's value depends from values of another # variables or depends from previous value but used # multiplication break else: if ( # If variable is unchanged (is_prev_value_used and col[-1] == 0) or # Or variable has assigned to constant value not is_prev_value_used ): if not is_prev_value_used: handle_mov(fix_mat.content, (VAR, x), (VALUE, col[-1])) for index, elem in enumerate(mat.content[x]): if elem != 0 and index != x: raise MatcodeFoldingError( 'Folded variable is used in calculations ' + 'of another variables' ) continue unskipped_indexes.append(x) if col[-1] != 0: need_unit_row = True if need_unit_row: unskipped_indexes.append(mat.rows - 1) lite_content = [] for y in unskipped_indexes: row = [] for x in unskipped_indexes: row.append(mat.content[y][x]) lite_content.append(row) return Matrix(lite_content), unskipped_indexes, fix_mat
def csv_to_network_branch_matrices(filename): """ Converts a CSV file to Y, J, E network matrices. :param filename: the name of the CSV file :return: the Y, J, E network matrices """ with open(filename, 'r') as csv_file: reader = csv.reader(csv_file) J = [] Y = [] E = [] for row in reader: J_k = float(row[0]) R_k = float(row[1]) E_k = float(row[2]) J.append(J_k) Y.append(1 / R_k) E.append(E_k) Y = Matrix.diagonal(Y) J = Matrix.column_vector(J) E = Matrix.column_vector(E) return Y, J, E
def construct_phi(self): phi = Matrix.empty(self.mesh.num_rows, self.mesh.num_cols) for i in range(self.mesh.num_rows): y = self.mesh.get_y(i) for j in range(self.mesh.num_cols): x = self.mesh.get_x(j) boundary_pt = False for boundary in self.boundaries: if boundary.contains_point(x, y): boundary_pt = True phi[i][j] = boundary.potential() if not boundary_pt: phi[i][j] = self.guesser.guess(x, y) return phi
def __init__(self): self.verts = Matrix( [[1 / math.sqrt(10), 1 / math.sqrt(6), 1 / math.sqrt(3), 1], [1 / math.sqrt(10), 1 / math.sqrt(6), 1 / math.sqrt(3), -1], [1 / math.sqrt(10), 1 / math.sqrt(6), -2 / math.sqrt(3), 0], [1 / math.sqrt(10), -math.sqrt(1.5), 0, 0], [-2 * math.sqrt(2 / 5), 0, 0, 0]]) self.center = [0, 0, 0, 0] self.edges = [[0, 1], [0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]] self.faces = [[1, 2, 3]]
def run_loop(settings, matcode, index, vector_len): mat = Matrix.identity(vector_len) while True: instr = matcode[index] oper = instr[0] if oper == END: return mat, index try: if oper == LOOP: if len(instr) != 2 or instr[1][0] != VALUE: raise InvalidMatcodeError sub_mat, index = run_loop( settings, matcode, index + 1, vector_len, ) need_min_rows = settings['opt_min_rows'] if need_min_rows: rows_count = sub_mat.rows sub_mat, unskipped, fix_mat = skip_rows(sub_mat) cur_mat = sub_mat ** instr[1][1] if need_min_rows: cur_mat = restore_rows(cur_mat, unskipped, fix_mat) else: if len(instr) != 3 or instr[1][0] != VAR: raise InvalidMatcodeError cur_mat = Matrix.identity(vector_len) matcode_map[oper](cur_mat.content, instr[1], instr[2]) except (InvalidMatcodeError, KeyError, TypeError) as err: if isinstance(err, InvalidMatcodeError) and err.args: raise err raise InvalidMatcodeError(( 'Invalid matrix code instruction: %s' ) % ' '.join(map(repr, instr))) mat *= cur_mat index += 1
def find_disjoint_s_matrix(S1, S2): """ Finds the disjoint S matrix given by the two provided local S matrices. :param S1: the first local S matrix :param S2: the second local S matrix :return: the disjoint S matrix """ n = len(S1) S_dis = Matrix.empty(2 * n, 2 * n) for row in range(n): for col in range(n): S_dis[row][col] = S1[row][col] S_dis[row + n][col + n] = S2[row][col] return S_dis
def choleski_solve(A, b, half_bandwidth=None): """ Solves an Ax = b matrix equation by Choleski decomposition. :param A: the A matrix :param b: the b matrix :param half_bandwidth: the half-bandwidth of the A matrix :return: the solved x vector """ n = len(A[0]) if half_bandwidth is None: elimination(A, b) else: elimination_banded(A, b, half_bandwidth) x = Matrix.empty(n, 1) back_substitution(A, x, b) return x
def find_local_s_matrix(triangle): """ Finds the local S matrix for a finite-difference triangle. :param triangle: the finite-difference triangle :return: the local S matrix """ x = triangle.x y = triangle.y S = Matrix.empty(3, 3) for i in range(3): for j in range(3): S[i][j] = ((y[(i + 1) % 3] - y[(i + 2) % 3]) * (y[(j + 1) % 3] - y[(j + 2) % 3]) + (x[(i + 1) % 3] - x[(i + 2) % 3]) * (x[(j + 1) % 3] - x[(j + 2) % 3])) / (4 * triangle.area) return S
def __init__(self): self.verts = Matrix([ [1, 0, 0, 0], #0 [0, 1, 0, 0], #1 [0, 0, 1, 0], #2 [0, 0, 0, 1], #3 [-1, 0, 0, 0], #4 [0, -1, 0, 0], #5 [0, 0, -1, 0], #6 [0, 0, 0, -1] ]) #7 self.center = [0, 0, 0, 0] self.edges = [ [0, 1], [0, 2], [0, 3], [0, 5], [0, 6], [0, 7], [1, 2], [1, 3], [1, 4], [1, 6], [1, 7], [2, 3], [2, 4], [2, 5], [2, 7], [3, 4], [3, 5], [3, 6], [4, 5], [4, 6], [4, 7], [5, 6], [5, 7], [6, 7], ] self.faces = [[1, 2, 3]]
def compute_half_energy(S, mesh, mesh_size): """ Computes the half-energy needed to compute the capacitance of the mesh. :param S: the S matrix :param mesh: the mesh :param mesh_size: the mesh size :return: the half-energy """ U_con = Matrix.empty(4, 1) half_energy = 0 for row in range(mesh_size - 1): for col in range(mesh_size - 1): node = row * mesh_size + (col + 1) # 1-based if node < 28: U_con[0][0] = mesh[node + mesh_size] U_con[1][0] = mesh[node] U_con[2][0] = mesh[node + 1] U_con[3][0] = mesh[node + mesh_size + 1] half_energy_contribution = U_con.transpose() * S * U_con half_energy += half_energy_contribution[0][0] return half_energy
def create_incidence_matrix_mesh(cols, num_branches, num_horizontal_branches, num_nodes, num_vertical_branches): """ Create the incidence matrix given by the resistive mesh with the given number of columns, number of branches, number of horizontal branches, number of nodes, and number of vertical branches. :param cols: the number of columns in the mesh :param num_branches: the number of branches in the mesh :param num_horizontal_branches: the number of horizontal branches in the mesh :param num_nodes: the number of nodes in the mesh :param num_vertical_branches: the number of vertical branches in the mesh :return: the incidence matrix (A) """ A = Matrix.empty(num_nodes, num_branches) node_offset = -1 for branch in range(num_horizontal_branches): if branch == num_horizontal_branches - cols + 1: A[branch + node_offset + 1][branch] = 1 else: if branch % (cols - 1) == 0: node_offset += 1 node_number = branch + node_offset A[node_number][branch] = -1 A[node_number + 1][branch] = 1 branch_offset = num_horizontal_branches node_offset = cols for branch in range(num_vertical_branches): if branch == num_vertical_branches - cols: node_offset -= 1 A[branch][branch + branch_offset] = 1 else: A[branch][branch + branch_offset] = 1 A[branch + node_offset][branch + branch_offset] = -1 if num_branches == 2: A[0][1] = -1 else: A[cols - 1][num_branches - 1] = -1 return A
def restore_rows(lite_mat, unskipped_indexes, fix_mat): mat = Matrix.identity(fix_mat.rows) for y, row in izip(unskipped_indexes, lite_mat.content): for x, elem in izip(unskipped_indexes, row): mat.content[y][x] = elem return mat * fix_mat
def run_matcode(settings, matcode, vector): mat = run_loop(settings, matcode, 0, len(vector))[0] return (Matrix([vector]) * mat).content[0]
import sys from matrices import Matrix '''generates hadamard codes, using the hadamard matrix constructin, which are made using the sylvester construction https://en.wikipedia.org/wiki/Hadamard_matrix https://en.wikipedia.org/wiki/Hadamard_code''' #the length of the codes will be 2 ** size size = int(sys.argv[1]) H = Matrix([[1]]) while size: size -= 1 H = H.append_right(H).append_under(H.append_right(H * -1)) for row in H.append_under(H * -1): for i in row: sys.stdout.write(str((i + 1) / 2)) sys.stdout.write('\n')