Skip to content
Maintankadin

Theck's MATLAB thread - Cataclysm/4.x

Marblehead
Wed Aug 04, 2010 3:07 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

Naked untalented stamina = 152
Naked untalented stamina with BoK = round(152*1.05) = round(159.6) = 160
Naked talented stamina without BoK = round(152*1.15) = round(174.8) = 175

Both are wrong, so rounding is out.

Edit: Obviously, ceil() is also out.
tlitp
Wed Aug 04, 2010 3:16 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

theckhd wrote:I've already renamed the dot structure, and I'm thinking we should probably rename the mod structure as well, despite the fact that I really like the name mod. I can't decide between "mdf" and "mo" but I'm leaning towards the latter. Any opinions on that?

As long as length('whatever')>=3, it's fine. In this case, "mdf" it is.
theckhd
Wed Aug 04, 2010 3:34 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

tlitp wrote:As long as length('whatever')>=3, it's fine. In this case, "mdf" it is.

Bah, and I rather liked "mo" too. I'll upload an "mdf" version shortly here.
theckhd
Wed Aug 04, 2010 3:40 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

Uploaded r40.

If anyone wants to mess around with the stat scaling issue, this code may be helpful:
Code: Select all
str=[164 172 164 172; 1637 1718 1637 1718; 1677 1760 1677 1760];
sta=[152 159 174 183; 3450 3622 3966 4165; 3490 3664 4012 4213];
gear.str=[0 0 0 0; repmat(1637-164,2,4)];
gear.sta=[0 0 0 0; repmat(3450-152,2,4)]
cons.str=[0 0 0 0; 0 0 0 0; 40 40 40 40];cons.sta=cons.str;

base.str=164;base.sta=152;

mdf.BoK=repmat([1 1.05 1 1.05],3,1);
mdf.TbtL=repmat([0 0 0.15 0.15],3,1);

e1sta=floor(floor((base.sta+gear.sta+cons.sta).*(1+mdf.TbtL)).*mdf.BoK)
e1str=floor((base.str+gear.str+cons.str).*mdf.BoK)

e2str=floor(base.str.*mdf.BoK)+floor((gear.str+cons.str).*mdf.BoK)
e2sta=floor(base.sta.*(1+mdf.TbtL).*mdf.BoK)+floor((gear.sta+cons.sta).*(1+mdf.TbtL).*mdf.BoK)

err1str=e1str-str
err1sta=e1sta-sta
err2str=e2str-str
err2sta=e2sta-sta


The data is arranged in the form [1a 1b 1c 1d; 2a 2b 2c 2d; 3a 3b 3c 3d]
theckhd
Wed Aug 04, 2010 4:02 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

Observation: Neither strength functions throw off an error because the input conditions don't meet the requirement for differentiating. We need floor(floor(base+gear+cons)*BoK) > floor(base*BoK)+floor((gear+cons)*BoK). To get this condition, we need:

base-floor(base)+(gear+cons)-floor(gear+cons) >= 1

In other words, if base ends in xxx.5 and gear+cons ends in yyy.5, they'll both get floored down to xxx+yyy, while base+gear+cons will get floored to xxx+yyy+1.

In the current setup, here's base.str.*mdf.BoK and (gear.str+cons.str).*mdf.BoK:

Code: Select all
>> base.str.*mdf.BoK

ans =

  164.0000  172.2000  164.0000  172.2000
  164.0000  172.2000  164.0000  172.2000
  164.0000  172.2000  164.0000  172.2000

>> (gear.str+cons.str).*mdf.BoK

ans =

  1.0e+003 *

         0         0         0         0
    1473.0    1546.65    1473.0    1546.65
    1513.0    1588.65    1513.0    1588.65


We're just shy of our condition, because we have 0.2 + 0.65 = 0.85. We can't change the base contribution, but we can tweak gear slightly. If you were able to find a gearset with about 4 more STR, that would put us at yyy.85 from gear+cons, and should resolve the degeneracy.
Marblehead
Wed Aug 04, 2010 4:25 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

Of course. They all follow the same patterns.

Pattern 1: player.???=floor(floor(<sum of all ???>.*<talent modifiers>).*<buff modifiers>)

Pattern 2: player.???=floor(<sum of base and profession>.*<talent modifiers>.*<buff modifiers>)+floor(<sum of everything else>.*<talent modifiers>.*<buff modifiers>)

I assumed that since stamina calcs were wrong, all the other stats were wrong too, and we were just lucky with the strength calcs.
theckhd
Wed Aug 04, 2010 4:49 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

Marblehead wrote:Of course. They all follow the same patterns.

Pattern 1: player.???=floor(floor(<sum of all ???>.*<talent modifiers>).*<buff modifiers>)

Pattern 2: player.???=floor(<sum of base and profession>.*<talent modifiers>.*<buff modifiers>)+floor(<sum of everything else>.*<talent modifiers>.*<buff modifiers>)

I assumed that since stamina calcs were wrong, all the other stats were wrong too, and we were just lucky with the strength calcs.


Well, yeah. My point was that the STR one could give us definitive results if we tweak the input conditions slightly. Since it only has one modifier, it would give us a good baseline to work from. If we know that the functional form is floor(base*talent)+floor((gear+cons)*talent) instead of floor((base+gear+cons)*talent), then when we go to add additional multipliers (BoK) we don't have to explore variations of the second formula at all. It narrows the parameter space pretty significantly.

I think I already know the answer based on the stamina data (to be posted shortly), but that's only after lots of trial and error, and I still can't nail down the implementation of the 2nd modifier.
theckhd
Wed Aug 04, 2010 4:53 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

Observations on stamina:

Here are the error arrays for sta:
Code: Select all
err1sta =

     0     0     0    -1
     0     0     1     0
     0     0     1     0

err2sta =

     0     0     0     0
     0    -1     0     0
     0    -1     0     0


e1sta has trouble when talented, but without BoK (i.e. the second floor being redundant). That means that floor((base+gear+cons)*(1+tbtl)) is in error. If it weren't, we wouldn't get an erroneous result in column 3.

e2sta doesn't have this problem in columns 1 or 3. Just to check, here's base*(1+tbtl) and (gear+cons)*(1+tbtl):

Code: Select all
ans =

  152.0000  152.0000  174.8000  174.8000
  152.0000  152.0000  174.8000  174.8000
  152.0000  152.0000  174.8000  174.8000

>> (gear.sta+cons.sta).*(1+mdf.TbtL)

ans =


         0         0         0         0
    3298.00    3298.00    3792.70    3792.70
    3338.00    3338.00    3838.70    3838.70


Note that for column 3, we have 0.8 from the first contribution and 0.7 from the second. As expected, if we floor them individually they round down to xxx+yyy, and if we floor them together it's xxx+yyy+1. The data suggests that the correct answer is xxx+yyy, so we have to conclude that equation 2 has the correct implementation of TbtL. I.e.

floor(base*(1+tbtl))+floor((gear+cons)*(1+tbtl)) is correct within the limitations of the data set.

The real question is how to implement BoK to fix this. Here are the two obvious guesses:
floor(floor(base*(1+tbtl))*BoK)+floor(floor((gear+cons)*(1+tbtl))*BoK)
floor([floor(base*(1+tbtl))+floor((gear+cons)*(1+tbtl))]*BoK) (brackets used for clarity)

Yet neither of these work. Here are the error results:
Code: Select all
e3sta=floor(floor(base.sta.*(1+mdf.TbtL)).*mdf.BoK)+floor(floor((gear.sta+cons.sta).*(1+mdf.TbtL)).*mdf.BoK);
e4sta=floor((floor(base.sta.*(1+mdf.TbtL))+floor((gear.sta+cons.sta).*(1+mdf.TbtL))).*mdf.BoK);

err3sta =

     0     0     0    -1
     0    -1     0    -2
     0    -1     0    -2


err4sta =

     0     0     0    -1
     0     0     0    -1
     0     0     0    -1


The second one is certainly closer, but it's still spitting out errors for the combination of TbtL and BoK. I'm toying around with ways to fix this as we speak.
theckhd
Wed Aug 04, 2010 5:02 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

Just in case anyone else is playing along, I got tired of trying to read my old code snippets. It was just too hard to read with so many different modifiers. I condensed the language a bit to make it easier to differentiate between the different formulas:

Code: Select all
clear
str=[164 172 164 172; 1637 1718 1637 1718; 1677 1760 1677 1760];
sta=[152 159 174 183; 3450 3622 3966 4165; 3490 3664 4012 4213];
gstr=[0 0 0 0; repmat(1637-164,2,4)];
gsta=[0 0 0 0; repmat(3450-152,2,4)]
cstr=[0 0 0 0; 0 0 0 0; 40 40 40 40];csta=cstr;

bstr=164;bsta=152;

bok=repmat([1 1.05 1 1.05],3,1);
tbtl=repmat([1 1 1.15 1.15],3,1);

estr(:,:,1)=floor((bstr+gstr+cstr).*bok);
estr(:,:,2)=floor(bstr.*bok)+floor((gstr+cstr).*bok);

esta(:,:,1)=floor(floor((bsta+gsta+csta).*tbtl).*bok);
esta(:,:,2)=floor(bsta.*tbtl.*bok)+floor((gsta+csta).*tbtl.*bok);
esta(:,:,3)=floor(floor(bsta.*tbtl).*bok)+floor(floor((gsta+csta).*tbtl).*bok);
esta(:,:,4)=floor((floor(bsta.*tbtl)+floor((gsta+csta).*tbtl)).*bok);
esta(:,:,5)=floor(bsta.*tbtl.*bok)+floor((gsta+csta).*tbtl.*bok);
esta(:,:,6)=floor((floor(bsta.*bok)+floor((gsta+csta).*bok)).*tbtl);
esta(:,:,7)=floor(bsta.*tbtl.*bok)+floor(gsta.*tbtl.*bok)+floor(csta.*tbtl.*bok);

errstr=estr-repmat(str,[1 1 size(estr,3)])
errsta=esta-repmat(sta,[1 1 size(esta,3)])

<edit> oops, noticed an error that occured when clearing. Here's updated code.
<edit2> and the error results:
Code: Select all
errsta(:,:,1) =

     0     0     0    -1
     0     0     1     0
     0     0     1     0


errsta(:,:,2) =

     0     0     0     0
     0    -1     0     0
     0    -1     0     0


errsta(:,:,3) =

     0     0     0    -1
     0    -1     0    -2
     0    -1     0    -2


errsta(:,:,4) =

     0     0     0    -1
     0     0     0    -1
     0     0     0    -1


errsta(:,:,5) =

     0     0     0     0
     0    -1     0     0
     0    -1     0     0


errsta(:,:,6) =

     0     0     0    -1
     0    -1     1    -1
     0    -1     1    -1


errsta(:,:,7) =

     0     0     0     0
     0    -1     0     0
     0    -1     0     0
Marblehead
Wed Aug 04, 2010 5:19 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

I found a way to get correct results for stamina, but it broke the strength ones. I thought to post it, cause it might help someone to get to the right answer.

Code: Select all
esta(:,:,8)=round(floor(bsta.*tbtl.*bok)+floor((gsta+csta).*tbtl).*bok)
estr(:,:,3)=round(floor(bstr.*bok)+floor(gstr+cstr).*bok)
theckhd
Wed Aug 04, 2010 5:54 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

Removing redundant round/floor functions, that's:
Code: Select all
floor(bsta*tbtl*bok)+round(floor((gsta+csta)*tbtl)*bok)
floor(bstr*bok)+round((gstr+cstr).*bok)


You're right, it borks the STR calculation. It also doesn't make much sense given that Blizzard has tended to stick with floor() functions in the past. But I haven't been able to come up with a better expression for the stamina results yet without using round() somewhere.

I've been toying around with
Code: Select all
esta(:,:,5)=floor(bsta.*tbtl.*bok)+floor((gsta+csta).*tbtl.*bok);

because that seems like the most straightforward implementation, and only gives two errors that suggest the gear scaling with Kings is incorrect. Adding the round function is the only thing that seems to fix it, so far.
tlitp
Wed Aug 04, 2010 9:16 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

Is anyone really interested in getting a string of 10 functions just to chop off a sporadic error of magnitude 1 ? Marblehead's #2 is quite reasonable.
Marblehead
Thu Aug 05, 2010 2:35 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

ability_model.m

Code: Select all
%Seal of Truth, using old SoVeng model, assumes a 5-stack
raw.SealofTruth=    0.33.*player.wdamage.*mdf.spdmg.*mdf.SotP;
raw.SealJud(1)=    (1+0.22.*player.hsp+0.14.*player.ap).*1.5;
dmg.SealofTruth=    raw.SealofTruth.*mdf.phcrit.*target.resrdx;
dps.SealofTruth=    dmg.SealofTruth./player.wswing;

%Censure (prev. Holy Vengeance), damage for a 5 stack over 15 seconds
mdf.Censcrit=1+(mdf.spcritmulti-1).*player.phcrit./100; %physical, 1.5 base multiplier
raw.Censure=        (0.013.*player.hsp+0.025.*player.ap).*5.*5.*mdf.spdmg;
dmg.Censure=        raw.Censure.*mdf.Censcrit.*target.resrdx;
dps.Censure=        dmg.Censure./(5.*cens.NetTick);

%Seal of Righteousness
raw.SealofRighteousness=    gear.swing.*(0.022.*player.ap+0.044.*player.hsp).* ...
                            mdf.spdmg.*mdf.SotP;
raw.SealJud(2)=             (0);    %Not yet on wowhead?
dmg.SealofRighteousness=    raw.SealofRighteousness.*target.resrdx;

Shouldn't there be a hit modifier for these calculations? If Censure behaves like HV, then each tick can miss/parry/dodge. Also, SoT and SoR don't hit if the swing misses, so I think they should have a mdf.mehit component too.

Code: Select all
%Hand of Reckoning
raw.HandofReckoning=(1+0.5.*player.ap).*mdf.spdmg;
dmg.HandofReckoning=raw.HandofReckoning.*mdf.sphit.*mdf.spcrit.*target.resrdx;

We'll have to test this to see in which attack table it is. I have a feeling that it has the same behavior as Judgement (using mdf.rahit and mdf.phcrit).
Gaffer
Thu Aug 05, 2010 7:42 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

Marblehead wrote:Shouldn't there be a hit modifier for these calculations? If Censure behaves like HV, then each tick can miss/parry/dodge. Also, SoT and SoR don't hit if the swing misses, so I think they should have a mdf.mehit component too.


I have about 5 minutes of logs without missing any Censure ticks. I'll check dosage applies when I can log in.
Chicken
Thu Aug 05, 2010 7:46 pm

Re: Theck's MATLAB thread - Cataclysm/4.x

Marblehead wrote:Shouldn't there be a hit modifier for these calculations? If Censure behaves like HV, then each tick can miss/parry/dodge.
Actually to match live behavior each application would need to check for a failure to connect (Which I'd assume is part of the Seal of Truth part of the model), but the ticks themselves are guaranteed to hit. On live the ticks can suffer from partial resists, though I understand they're removing those in Cataclysm.