# Tag Info

8

You play with up to 199 dice per player. So most of the time, the attacker will attack with 3 dice and the defender will attack with 2 dice. As long as that's the case, you could simply pick one of the three possible outcomes (with precalculated probabilities) and apply it. Outline: def _attack_(n_atk,n_def): while n_atk >= 3 and n_def >= 2: ...

7

Preprocessing Be sure to read superb_rain's excellent answer. The following code is meant as a preprocessing. It simply iterates over every single attack & defense configuration, and calculates the cumulative probability that the attacker manages to kill 0, 1 or 2 defense soldiers. It is slow, but it's not a problem since it's only supposed to run once ...

7

I haven't benchmarked any of the following but I suspect that they can help you out. I'd check each alteration separately. First, selecting the number of dice (die is singular, dice is plural) as you have is confusing and probably slow. n_atk_dice = min(n_atk, 3) n_def_dice = min(n_def, 2) Second, using np.sort is (a) overkill for the problem and (b) ...

6

You could replace for position in range(l): if random.random() < mu: intList[number] = intList[number] ^ (1 << position) with for bit in bits: if random() < mu: intList[number] ^= bit after preparing bits = [1 << position for position in range(l)] before the show and ...

5

Your second function is faster for me when simplifying it like this: @jit(nopython=True) def move_to_back_c(a, value): mask = a == value return np.append(a[~mask], a[mask]) In addition, Python's official style-guide, PEP8, recommends not surrounding a = with spaces if it is used for keyword arguments, like your nopython=True. Since numba ...

5

I only see a few micro optimisations: Iterate the list instead of a range, so that you don't have to do another lookup with list[i+1] Use more assignment operators, such as &=, |= and >>= It is not needed to use lst in andnumber = lst & lst. It can be just andnumber = lst So: def count_mixed_bits_v2(lst): andnumber = ornumber =...

5

After profiling your code as: import cProfile, pstats, StringIO pr = cProfile.Profile() pr.enable() for it in range(0,10000): getAlignmentData(source, sequence, sstart, tresholds) pr.disable() s = StringIO.StringIO() sortby = 'cumulative' ps = pstats.Stats(pr, stream=s).sort_stats(sortby) ps.print_stats() print s.getvalue() You will get: 1370129 ...

5

Documentation The amount of documentation you've written is ambitious, but its arrangement is slightly unhelpful for a few reasons. When documenting the "parameters to a class", you're really documenting the parameters to __init__. As such, this block: """ Parameters ---------- shapefile : str It is a string pointing to a ...

4

First off, you should not be using Python 2 anymore, if at all possible. It will be deprecated next year. The major differences (important for this code) are that xrange is now range and print is a function. Next, since I am currently on mobile I do not have access to numba. But since you said it does not yield any performance gain anyways, I just removed ...

4

Just a few quick points on your code: any future imports should be at the top of any code. Are you using this intentionally (2to3?) or this is leftover code? your loop to generate test data overrides i in two secondary loops - this is bad coding practice. you're using xrange, which is pretty much deprecated since Python 2.3. Are you really using Python 2....

4

Code style Try to use an IDE which integrates with linters (Pycodestyle, Pylama, Mypy,...). This alone found some 97 warning, ranging from no whitespaces after a comma, trailing whitespace, redundant backslashes, closing brackets not matching the indentation,... All of these are no big issues, but they make the code look messy, and are easy to fix. I use a ...

4

I don't know numba, but here's a little rewrite: Shorter variable names like and_, using the underscore as suggested by PEP 8 ("used by convention to avoid conflicts with Python keyword") and as done by operator.and_. Yours crashes if the list has fewer than two elements, I start with neutral values instead. Looping over the list elements rather ...

4

No significant performance improvement but cleaner code. Because temp_list is overwritten element-wise you can create it once and then leave it. At the end of each iteration you can then copy the entire list into int_list for the next iteration. Similarly you can simplify creating the random ints a and b a bit. There are a lot of ways that get close to this ...

4

By a very wide margin, the slowest part of your code is this loop: for k in range(nangles): pi_nm2 = 0 pi_nm1 = 1 for n in range(1, nstop): tau_nm1 = n * mu[k] * pi_nm1 - (n + 1) * pi_nm2 S1[k] += (2 * n + 1) * (pi_nm1 * a[n - 1] + tau_nm1 * b[n - 1]) / (n + 1) / n S2[k] += (2 * n + 1) * (...

3

Markov Chains, Part 2 Goal My above answer was getting too long. The goal here will be to use a Markov chain to calculate the probability of reaching an absorbing state (end state, e.g. 3 vs 0 -> attacker wins or 0 vs 2 -> defense wins) from a transient state (initial state, e.g. 12 vs 7). Code Here's a slightly modified code: # pip install PyDTMC # ...

3

One obvious improvement is the repeated calculations of N-1 and 1<<l - 1 -- those can be calculated once outside the loop and put in variables. Another wasted effort is the triple initialization of intList_temp. There is no reason to set it to 0, set it to intList, then set it to the actually calculated values. Also that while loop to ensure the values ...

3

You might consider to use a tuple of directions, something like this: directions = ((1,0), (0,1), (-1,0), (0,-1)) In your while loop, you can do: direction = directions[np.random.randint(4)] A += direction B += direction If you switch from tuple to numpy arrays (direction and your current position), you could also use numpy.add which might be ...

2

I have twisted the problem a little and find a way of optimize it at the cost of only get the information of one level of subdivision. Whith this I mean that the bellow method obtains the same result as the method posted on the question (it assings 1 unique index to all the points that are inside a node) but instead of having a concatenation of the indexes ...

2

There are a couple of obvious (but minor) contributors to inefficiency here: You search an increasing number of stick positions for each particle. If I understand the code correctly, once a particle has "stuck" to a position, no other particle will ever "stick" there, and you can remove the original position from the set. You could use a set instead of a ...

2

for x3 in range(N): intList_temp[x3] = intList[x3] and for x3 in range(N): intList[x3] = intList_temp[x3] look pretty messy, I'm not proficient in python, but there should be an implementation of copying a vector much faster.

2

l is a poor variable name. It doesn't convey any information about what it is and it is easy to confuse with the number 1. I'll use nbits. If nbits is not too large, it might make sense to precompute a table of possible bit flips and their probablities. For a probability of mu that a bit flips, the probability that it doesn't flip is (1 - mu). The ...

2

I think you can rearrange your equation from $AB_{ija} = \frac{1}{2}(A_{ia} + B_{ja})$ \\$ \begin{align} C_{ij} = \sum_a & A_{ia}\cdot \log\left(\frac{A_{ia}}{AB_{ija}}\right) + B_{ja}\cdot \log\left(\frac{B_{ja}}{AB_{ija}}\right) + \\ &+ (1-A_{ia})\cdot \log\left(\frac{1-A_{ia}}{1-AB_{ija}}\right) + (1-B_{ja})\cdot \log\left(\frac{1-B_{ja}}{1-...

1

You are slicing your original dataset 1000 times, making 2000 comparisons with borders for each of the values in it. It is much faster to calculate the proper bin for each value using simple math: bin = (value - min_data) / dx D[bin] += 1 And you can use original circle to set all В[bin] The only problem, that at max_data, bin would be equal bins (not ...

1

Actually, it is embarrassing to answer my question, but I think the problem was about the initial compilation time using numba. After I executed function Grid_Search once and executed it again, it outperforms original code in terms of execution time. If you have other suggestions to make execution time faster, please tell me.

1

I concur with your conclusions with your goals, especially 1-3. I think it's fantastic. For goal 5 it's hard to say. I've the feeling it is quite a niche project in a way. For example I haven't got a clue of how many people are generally working in that area, let alone looking around for a new project like this. It might make sense to push more into ...

1

If you profile the code without using njit, you will find that most of the time is consumed in calls to randint and sort: atk_rolls = sort[n_atk_dice](np.random.randint(1, 7, n_atk_dice)) def_rolls = sort[n_def_dice](np.random.randint(1, 7, n_def_dice)) So, instead of generating and sorting those random numbers for each loop iteration, you could pregenerate ...

1

It is absolutely not optimal for a small mu. It's generally more efficient to first generate how many bits you'd like to flip using a Binomial distribution, and then sample the indices. However, then we have to generate words with k set bits, which involves more expensive RNG calls. However when mu is very small and l is very large, this is the most ...

1

You can simplify this by rearranging the function as follows (writing z=(a+b)/2): a log(a/z) + b log(b/z) + (1-a) log( (1-a)/(1-z) ) + (1-b) log( (1-b)/(1-z) ) = a log(a) + b log(b) + (1-a) log(1-a) + (1-b) log(1-b) - 2z log(z) - 2(1-z)log(1-z) The first 4 terms can be evaluated outside the main loop, so that you only need to evaluate log(z) and log(1-z) ...

1

I changed the main part of the script to: from time import time start = time() val = LSMPut(1, 0.06, 0.15, 100, 90, 20, 40_000, 5) print(f'Done in {time() - start:.3} seconds') print(val) The point is that Python will print how long the calculation took to run. Before modifications, the script takes 3.05 seconds to run on my computer. Now I can modify ...

1

Stability The single most important feature of merge sort is stability: elements comparing equal retain their original order. As coded merge loses stability: shall src_arr[i0] and src_arr[i1] compared equal, src_arr[i1] is copied first. A standard remedy is to compare them backwards; in pseudocode: if (src_arr[i1] < src_arr[i0]) copy src_arr[i1] ...

Only top voted, non community-wiki answers of a minimum length are eligible