Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix typo in BenefitSurtax function and add test_ID_HC_vs_BS #842

Merged
merged 2 commits into from
Jul 29, 2016
Merged

Fix typo in BenefitSurtax function and add test_ID_HC_vs_BS #842

merged 2 commits into from
Jul 29, 2016

Conversation

martinholmer
Copy link
Collaborator

This pull request is similar to Matt Jensen's pull request #490, which is now closed and was never merged into the master branch.

Following Matt, a bug in the BenefitSurtax function (caused by the use of uncapitalized casualty) has been fixed. This bug fix causes a minor change (in the expected direction) in the reform comparison (r29) that imposes a benefit surtax with a 6% of AGI deduction before applying a 100% benefit surtax rate.

The test_ID_HC_vs_BS() added to test_calculate.py is also essentially the same as the test Matt proposed in #490. However, the test passes unlike Matt's experience in November 2015. Note that this new test (as Matt's) uses the faux-puf.csv file containing 1991 records that are interpreted as being for tax year 2009.

In addition to the changes Matt proposed in #490, the BenefitSurtax function has been revised to make it clearer what kind of reform is being simulated. None of these changes involve a change in basic logic; they just attempt to improve clarity.

The next step is to use the real puf.csv file as inctax.py input to do the same thing as is done in test_ID_HC_vs_BS with faux-puf input. This will show if there are any HC-vs-BS inconsistencies in the real input data used by TaxBrain.

@MattHJensen @GoFroggyRun @feenberg @Amy-Xu

@codecov-io
Copy link

codecov-io commented Jul 26, 2016

Current coverage is 98.08% (diff: 100%)

Merging #842 into master will not change coverage

@@             master       #842   diff @@
==========================================
  Files            13         13          
  Lines          1777       1777          
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
  Hits           1743       1743          
  Misses           34         34          
  Partials          0          0          

Powered by Codecov. Last update 0474d8f...1f5ea9d

@martinholmer
Copy link
Collaborator Author

martinholmer commented Jul 26, 2016

This comment on pull request #842 summarizes the results of testing the consistency of a complete-haircut reform and a 100%-surtax-with-no-surtax-deduction reform using the puf.csv file used by TaxBrain. This test uses the same hc_reform and bs_reform as used in the test added in #842 except that the reforms are expressed in JSON. The inctax.py interface to the Tax-Calculator is used to generated 2013 tax results for each of these two reforms, and then an AWK script is used to check for differences between the two output files.

In summary, what this test shows is there is one filing unit in 2013 that has a different income tax liability under the two reforms. The RECID of that filing unit is 1072110. This filing unit will be investigated in a subsequent comment to this pull request.

@MattHJensen @GoFroggyRun @feenberg @Amy-Xu

Here are the details of what has been done:

tax-calculator$ cat hc_reform.json 
{
    // complete-haircut-of-itemized-deductions reform
    "_ID_Medical_HC": {"2013": [1.0]},
    "_ID_StateLocalTax_HC": {"2013": [1.0]},
    "_ID_RealEstate_HC": {"2013": [1.0]},
    "_ID_Casualty_HC": {"2013": [1.0]},
    "_ID_Miscellaneous_HC": {"2013": [1.0]},
    "_ID_InterestPaid_HC": {"2013": [1.0]},
    "_ID_Charity_HC": {"2013": [1.0]}
}

tax-calculator$ python inctax.py puf.csv 2013 --blowup --reform hc_reform.json --weights
You loaded data for 2009.
Your data have been extrapolated to 2013.

tax-calculator$ cat bs_reform.json 
{
    // 100% surtax on all itemized deductions
    "_ID_BenefitSurtax_crt": {"2013": [0.0]}, // no surtax deduction
    "_ID_BenefitSurtax_trt": {"2013": [1.0]}  // 100% surtax rate
}

tax-calculator$ python inctax.py puf.csv 2013 --blowup --reform bs_reform.json --weights
You loaded data for 2009.
Your data have been extrapolated to 2013.

tax-calculator$ ls -l puf*reform
-rw-r--r--   38019709 Jul 26 11:31 puf-13.out-inctax-bs_reform
-rw-r--r--   37526869 Jul 26 11:28 puf-13.out-inctax-hc_reform

tax-calculator$ awk -f taxdiffs.awk puf-13.out-inctax-hc_reform puf-13.out-inctax-bs_reform
NUM TAX UNITS= 219814
NUM_ITAX_DIFFS= 1
BIGGEST_ABS_DIFF= 1867.54
RECID_OF_BIGGEST= 1072110

The taxdiffs.awk script looks like this:

# TAXDIFFS.AWK calcs tax liability differences from two inctax.py output files
# USAGE: awk -f taxdiffs.awk inctax-output-filename-1 inctax-output-filename-2

function abs(v) {return v < 0 ? -v : v}

ARGIND == 1 {
    i++
    fuid1[i] = $1
    itax1[i] = $4
    fica1[i] = $6
}

ARGIND == 2 {
    n++
    fuid2[n] = $1
    itax2[n] = $4
    fica2[n] = $6
}

END {
    if ( n != i ) {
        printf( "ERROR: i=%d != n=%d\n",
                i, n )
        exit
    }
    for ( i = 1; i <= n; i++ ) {
        if ( fuid1[i] != fuid2[i] ) {
            printf( "ERROR: for i=%d ID1=%d != ID2=%d\n",
                    i,  fuid1[i],  fuid2[i] )
            exit
        }
        if ( abs(fica1[i] - fica2[i] ) > 0.01 ) {
            printf( "ERROR: for ID=%d FICA=%.2f != FICA2=%.2f\n",
                    fuid1[i], fica1[i], fica2[i] )
            exit
        }
    }
    num_diffs = 0
    biggest_abs_diff = 0.0
    biggest_abs_diff_id = 0
    for ( i = 1; i <= n; i++ ) {
        abs_diff = abs(itax1[i] - itax2[i] )
        if ( abs_diff > 0.01 ) {
            # printf( "ERROR: for ID=%d ITAX=%.2f != ITAX2=%.2f\n",
            #         fuid1[i], itax1[i], itax2[i] )
            num_diffs++
            if ( abs_diff > biggest_abs_diff ) {
                biggest_abs_diff = abs_diff
                biggest_abs_diff_id = fuid1[i]
            }
        }
    }
    printf( "NUM TAX UNITS= %d\n", n )
    printf( "NUM_ITAX_DIFFS= %d\n", num_diffs )
    if ( num_diffs > 0 ) {
        printf( "BIGGEST_ABS_DIFF= %.2f\n", biggest_abs_diff )
        printf( "RECID_OF_BIGGEST= %d\n", biggest_abs_diff_id )
    }
}

@martinholmer
Copy link
Collaborator Author

Using the blown-up puf.csv file as inctax.py input for 2013, we saw above in pull request #842 that there was only one filing unit (out of 219,814) with an income tax difference in the two itemized-deduction-limitation reforms being discussed here. The size of the income tax liability difference for that unit is $1,867.54, with the benefit-surtax tax liability being higher than the complete-haircut tax liability. But this dollar amount is very small relative to that filing unit's total tax liability, which is in the range from about $734,000 to about $736,000. In other words, the tax difference is only about one-quarter of one percent of that unit's tax liability. And the tax differences for all the other filing units are no more than one cent. Using the blown-up sampling weights to compute aggregate income tax revenue (in billions of dollars) under the two itemized-deduction-limitation reforms, produces the following results:

tax-calculator$ awk '{t+=$4*$29}END{print t*1e-9}' puf-13.out-inctax-hc_reform
1381.16
tax-calculator$ awk '{t+=$4*$29}END{print t*1e-9}' puf-13.out-inctax-bs_reform
1381.16

So, these two reforms produce essentially the same aggregate income tax revenue because the one filing unit with a difference has a small difference and not too large a sampling weight, making the aggregate results essentially identical.

While more analysis of this single filing unit might shed more light on why these two reforms do not always produce exactly the same tax liability, I think we have reached the the place where rapidly diminishing returns to further effort begin.

And furthermore, in analysis not shown here, I have added to both these reforms the elimination of the Pease phase-out of itemized deductions, which has very different effects on this one filing unit under the two itemized-deduction-limitation reforms. When adding this plausible provision to each of the two reforms, the aggregate income tax revenue results are exactly as above (as one would expect), but the one filing unit with a difference when the Pease phase-out is active has a smaller tax difference: $748.00 (instead of $1,867.54). In addition, to this filing unit having a smaller difference, a second filing unit now has an income tax difference that is greater than one cent. These results suggest (at least to me) the possibility that the premise that these two types of itemized-deduction-limiting reforms should always have exactly the same results may not be true given the complexity of the tax code.

@MattHJensen @GoFroggyRun @feenberg @Amy-Xu

@martinholmer
Copy link
Collaborator Author

It seems almost certain that the filing unit with RECID=1072110 that is discussed in pull request #842 is the same filing unit as discussed in the earlier issue #752.

@martinholmer
Copy link
Collaborator Author

martinholmer commented Jul 27, 2016

This is a further note on the one filing unit in the puf.csv file that has a tax liability difference under the two itemized-deduction-limitation reforms discussed in pull request #842.

After discussing this filing unit in issue #752, Sean concluded two things. First, the tax liability difference is caused by a difference in the way these two reforms interact with AMT provisions. And second, there is no apparent problem with Tax-Calculator logic ("I see nothing wrong in the tax logic, as well as our Itemize-vs-standard optimization. [T]his [one filing unit] is likely to be a legit case in the tax logic, rather than a bug.")

To confirm Sean's conclusion, I have simulated these two itemized-deduction-limitation reforms in the presence of another reform that eliminates the AMT. This AMT elimination is implemented by setting the two AMT tax rate parameters to zero. Every filing unit in the puf.csv file has exactly the same income tax liability under these two compound reforms.

These results, along with Sean's detailed investigation of the one filing unit in issue #752, suggest strongly that the premise of this whole exercise is not correct: given the complexity of the AMT, there is no reason to believe that tax liability will be exactly the same under a complete-haircut reform and a 100%-benefit-surtax-with-no-deduction reform for every filing unit.

@MattHJensen @GoFroggyRun @feenberg @Amy-Xu

P.S. I suppose there is a chance that there is a bug in the AMT logic, but those provisions have been tested against Internet TAXSIM. While these two models produce the same results for a large number of randomly-generated filing units, I suppose there is some chance that a bug remains in Tax-Calculator because none of the randomly-generated filing units have the combination of attributes that triggers the bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants