A theorem of the DPS function

#0 - Jan. 7, 2009, 4:12 p.m.
Blizzard Post
By clicking this topic's title, you agree that you understand what to expect. There will be some headache-inducing calculations found in this topic. Bear with it. In addition, if you wish to try this out for yourself, I recommend using a program such as mathematica to calculate integrals and the like.

Introduction

As any kind of DPSer, you are usually tasked with several tasks, some of which might be hard for some and easy for others, and so forth. It varies per class and chosen main specialization, as well as personal preference. So far, so good. The first few of these tasks, to obtain the idealized result of maximum dps and/or maximum item usage, i.e. getting the most out of it, is to specify the talent specialization you're going to go with and your ability sequence.

I'm deliberately saying sequence as this thus includes all dps-styles, both those based on rotations, as well as those that involve some or total degree of reactive dps. Reactive DPS means that your decisions on which spells/abilities to use are influenced by the environment, even in the state of steady dps on a fixated target (read: Patchwerk).

DPS, or rather the amount of it, is influenced a lot by whatever you're doing. First of all, which abilities you use, second, the sum of the total damage done by your abilities, and third, the total time it takes to do all the abilities in your sequence. Here comes what I refer to as the fundamental theorem of it, or the use of it in practical terms:

The Derivatives of a correct DPS function with respect to diffrent stats which will approach or exactly match the dps a person will do over time in a reference situation used for purposes of maximizing DPS (usually simple fights such as patchwerk) will essentially tell you the inverse relations between mentioned diffrent stats.

That's rather a mouthful. It's also kind of hard to understand. As a sidenote: This topic is not meant to practically go and make DPS functions for all existing specs and combinations. In a changing game such as an MMO, where specs, and even entire classes change over time, the work involved would be inappropriate for a single person. Thus we're trying to find a general 'way' of doing things. How exactly to properly find a formula for DPS is diffrent for each class.

Diving in

Periodically changing values.
Something that's persistent in this game is DPS-based cycles, abilities that have cooldowns and that will raise DPS, or a stat, by a factor of sorts during a part of the time. How do we map these as functions? Essentially we're looking for a function that looks a bit like this, i'm calling this one f(t):
........... ----------- ........... ----------
........... | ........... | ........... |
...........| ........... | ........... |
---------- ........... ----------

Where we want the top part to be a, the bottom part to be 0, and the width adjustable. Then n^f(t) will be a function that exactly does what we want, multiply the DPS for half the time. We also want the induvidual widths of the part adjustable.
One method that would be extremely handy in constructing this function is using a sine function.
Intricately, if we start with a sine,
Sin(t) , the result is actually pretty close to the intended function. If we divide this function by its own absolute value, it will become -1 and 1 in the appropriate ranges. Note that this function is infinite at exactly the conversion point between the positive and negative parts. Add 1, divide by two, and it's done. The end result is:

f(t) = (( Sin(2*pi / n * t)) / Abs(Sin(2*pi / n * t)) + 1) / 2. Notice the 'n' which defines the period.

Now we will want to 'shift' the function, i.e. make one part shorter or longer than the other, in other words, Q% of the time, the function needs to be '1'. Now we know that the sine function is symmetrical. And that Sin(t) + w, where w is arbitrary, can be set to zero as an equation to find out the t. Also, Q=100 corresponds to t= 1.5pi and Q = 0 to t=0.5pi. So how exactly do these two relate? The answer is a simple linear connection, since we're just arbitrarily setting the point where the function needs to be zero. Thus t = 0.5pi + 0.01piQ.
Now we need to solve for w.

Sin(0.5pi + 0.01piQ) + w = 0.
w = -Sin(0.5pi + 0.01piQ).

This shift does not need to be adjusted by the function's period. Now we add this sine to the already existing sines on both sides of the f(t) formula for g(t) the formula that also includes a Q coefficient or expected percentage of being apparent. Say you had a trinket that's activated for 20 seconds every 2 minutes. That means Q = 20 / 120 or Q = 1/6. Just put it in the formula and the correct line rolls out. Of course, it needs to be multiplied by whatever spell damage your trinket gives. So we also need to be able to adjust the amplitude. That's just putting a constant A in front, right?

g(t) = A * (( Sin(2*pi / n * t) -Sin(0.5pi + 0.01piQ)) / Abs(Sin(2*pi / n * t)-Sin(0.5pi + 0.01piQ)) + 1) / 2.

And there you have a handy formula to calculate such things in a DPS function. Do note however though, that using this means that you can no longer take the derivative towards 't'.
We can continue with g(t) now and also add a multiplication factor m to it, to use it as a multiplier. What's then important is that when we do this, you will need to 'map' your sequence to the final g(t), and see if there's any spells in the spot where g(t) suddenly changes value. WoW considers spells to either have the modifier or not. Simply count which spells are in and which ones are not. With more complicated functions you will have to calculate the multiplier of each induvidual spell. A graphical calculator or a program such as mathematica might help a lot with it.
Note that the integral of this function can be graphically approximated. When you know that h(t) is your dps function of t, and other variables, you can use
p-
| h(t)g(t)dt
0-

To calculate total damage dished out in a given time p. Divide by p and you have your dps for a fight that lasts 'p' seconds. Note that h(t) does not have to contain any 't's. However, when h(t) does not contain any t's it's much smarter to go for the simple solution (i.e. this solution is for when h(t) DOES contain t's, as is the case with, for example, dps that starts up slowly. It might be smart to activate your trinket 5 seconds later and end up with higher total damage, it's all contained in the basic formulae.

Simple solution: Approach any kinds of time-related buffs like this as pure damage increases by a number or factor. To calculate this factor, you'll just first determine what percentage of time the buff is active, then use the stochastical result that if a given chance 'p' is there of something being active at a given time, the total factor of the time it will approximately be actuve is p. So your trinket would just, when the tootlip reads '400 spell power' give 400 / 6 = approx. 67 spell power.

Okay, so now that we have time-related multipliers covered, we can look at what I call a sequence of spells.

-- Note: All variables are cleared and can be reused. Any variables used after this note have nothing to do with the variables used before. So the 'n' hereafter is a 'diffrent' 'n'. I simply don't have much intention of using weird numerics/symbols on this forum to smart out of the 26-character limit, or actually 52.--.

The sequence of spells contains n spells. SUM will hereby mean the total SUM of n objects, where i is used as a counter. So SUM(20q(i)) will mean that 20 times the function q of i is counted for 'n' 'i'. Just to be clear. (there's no summation symbol here...)

The DPS function, or function of the damage dealt, is in realty actually infinately thin infinately high spikes on the points where you deal damage. The surface area of the spikes then equals the damage of each spell. So let's make a series D(i) which are the damages of each of the abilities you're using in your sequence. So each melee hit, each DoT tick, etc. etc. is one D(i). Then your dps function h(t) looks like this:

h(t) = SUM(D(i)).

Now each D(i) now corresponds to a damage source. Now it's a task of finding a nice function which will approach the intended result. A good candidate is the normal distribution along a certain average. This average is the spell's time of casting T. If we make sigma infinately small, or in other words a small number e, then this funcion will closely match reality. Note that the time of casting T is something you can obtain from making your sequence. Also, haste will affect the time of casting T. There will also be another constant to multiply the normal distribution with, U. U is the total damage dished out by the event, for example a fireball always hitting for 2400 would have a U of 2400. Note that U is another function, i.e. when you have a spell, it can crit, hit, damage is affected by spellpower times its coefficient, etc. etc. You basically put that all in U. I will use the notation N(mu,sigma^2) for the normal distribution.

The actual formula is 1/((2pi)^.5*sigma) * e ^ (((x-mu)/sigma)^2), for those that are using calculators or mathematica and don't want to look it up. I'm lazy so i'm just writing N(..,..) for it. Note that it cannot be integrated algebraically, but can be derivated if you wish so.

X is the amount of haste rating needed for 1% haste. D refers to spell power or attack power, C to crit rating, H to haste rating. If you got this far, constructing the U function shouldn't be too hard. The D function then follows out of it (note: do not use the 'e' key on your calculator, that's 2.7something. just take a small number as e, not too small as that will mess up things, something like 0.0001 should be more than small enough for our approximations). You can also add in expertise, etc.
#10 - Jan. 9, 2009, 5:05 p.m.
Blizzard Post
Too much math for me on a Friday afternoon, but blue tagging for visibility (and a later read). :)