Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions MJxPrep.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ if (window.MJxPrep) {
eqn = wrapVariables(eqn)
eqn = wrapFuncCalls(eqn)

// Fix Kronecker deltas now: kronecker(a, b) -> kronecker_{a, b}
// The wrapping interferes with parsing of delta_{complexthings},
// due to not satisfying the usual regex forms for a variable or function
eqn = replaceFunctionCalls(eqn, 'kronecker', function(funcName, args) {
if (args.length !== 2) {return funcToSelf(funcName, args) ;}
return 'delta_{' + args[0] + ',' + args[1] + '}'
})

// Return the preprocessed equation
return eqn;
}
Expand Down
1 change: 1 addition & 0 deletions course/course/course.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<problem url_name="formula8"/>
<problem url_name="formula9"/>
<problem url_name="formula10"/>
<problem url_name="formula11"/>
</vertical>
</sequential>
<sequential url_name="matrixgrader" display_name="MatrixGrader">
Expand Down
49 changes: 49 additions & 0 deletions course/problem/formula11.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<problem display_name="Kronecker Deltas" showanswer="always" weight="10" attempts="">

<p>
The Kronecker delta often appears in expressions, and is included in the library. To invoke it, use <code>kronecker(x, y)</code>. Note that when using the AsciiMath preprocessor, this will render correctly. We decided against calling it <code>delta(x, y)</code>, as [mathjaxinline]\delta[/mathjaxinline] is a common user function name, and we do not support name overloading of functions.
</p>

<p>
When using a Kronecker delta in a solution, we strongly recommend using integer sampling in a small range (e.g., 1 to 4) and using many samples (e.g., 30) so that the various possible permutations are triggered in the grading.
</p>

<p>
What is the derivative [mathjaxinline]\frac{\partial x_i}{\partial x_j}[/mathjaxinline]?
</p>

<p>Suggested inputs:</p>
<ul>
<li><code>kronecker(i, j)</code> is the correct input</li>
<li><code>kronecker(i+1, j+1)</code> is also correct</li>
<li><code>kronecker(i+1, j)</code> is incorrect</li>
<li><code>1</code> and <code>0</code> are incorrect, but may be graded as correct in very rare circumstances, depending on the ranges and number of samples used</li>
</ul>

<script type="text/python" system_path="python_lib">
from mitxgraders import *
grader = FormulaGrader(
answers='kronecker(i, j)',
variables=['i', 'j'],
sample_from={
'i': IntegerRange([1, 4]),
'j': IntegerRange([1, 4])
},
samples=30,
suppress_warnings=True # Needed because we're using i and j as variables
)
</script>

<p style="display:inline">[mathjaxinline]\displaystyle \frac{\partial x_i}{\partial x_j} =[/mathjaxinline] </p>
<customresponse cfn="grader" inline="1">
<textline math="1" inline="1" correct_answer="x^n/fact(n)" preprocessorClassName="MJxPrep" preprocessorSrc="/static/MJxPrep.js"/>
</customresponse>

<h3>Resources</h3>
<ul>
<li>
<a href="https://github.com/mitodl/mitx-grading-library/tree/master/course/problem/formula11.xml" target="_blank">View source</a>
</li>
</ul>

</problem>
1 change: 1 addition & 0 deletions docs/grading_math/functions_and_constants.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ By default, all of the following functions are made available to students in `Fo
- `re(x)` Real part of a complex expression*
- `im(x)` Imaginary part of a complex expression*
- `conj(x)` Complex conjugate of a complex expression*
- `kronecker(x, y)` Kronecker delta* (Note that we highly recommend integer sampling over a short range (eg, 1 to 4) when kronecker deltas appear in an answer, and using many samples (eg, 30) so that most permutations appear in the sampling.)

## MatrixGrader Default Functions

Expand Down
5 changes: 5 additions & 0 deletions mitxgraders-js/MJxPrep.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ describe('preProcessEqn', () => {
expect(preProcessEqn(eqn)).toBe('{:cross({:x:}):}+{:({:a:}+{:b:}) {:times:} {:c:}:}+{:y:}')
} )

it('replaces Kronecker delta functions', () => {
const eqn = 'kronecker(x) + kronecker(a + b, c)'
expect(preProcessEqn(eqn)).toBe('{:kronecker({:x:}):}+{:delta_{{:a:}+{:b:},{:c:}}:}')
} )

it('wraps variables and function calls', () => {
// The behavior of wrapVariables and wrapFunCalls is primarily described
// in their dedicated tests
Expand Down
13 changes: 13 additions & 0 deletions mitxgraders/helpers/calc/mathfuncs.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ def arctan2(x, y):

return np.arctan2(y, x)

# NOTE: tests are in a separate file, NOT doctests.
# see https://bugs.python.org/issue6835
@SpecifyDomain.make_decorator((1,), (1,))
def kronecker(x, y):
"""
Returns 1 if x==y, and 0 otherwise.
Note that this should really only be used for integer expressions.
"""
if x == y:
return 1
return 0

def content_if_0d_array(obj):
"""
If obj is a 0d numpy array, return its contents. Otherwise, return item.
Expand Down Expand Up @@ -261,6 +273,7 @@ def has_one_scalar_input(display_name):
for key in ELEMENTWISE_FUNCTIONS}

SCALAR_FUNCTIONS['arctan2'] = arctan2
SCALAR_FUNCTIONS['kronecker'] = kronecker

ARRAY_FUNCTIONS = {
're': real,
Expand Down
Binary file modified python_lib.zip
Binary file not shown.
1 change: 1 addition & 0 deletions tests/formulagrader/test_formulagrader.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ def test_fg_debug_log():
" 'fact': <function factorial at 0x...>,<br/>\n"
" 'factorial': <function factorial at 0x...>,<br/>\n"
" 'im': <function imag at 0x...>,<br/>\n"
" 'kronecker': <function kronecker at 0x...>,<br/>\n"
" 'ln': <function log at 0x...>,<br/>\n"
" 'log10': <function log10 at 0x...>,<br/>\n"
" 'log2': <function log2 at 0x...>,<br/>\n"
Expand Down
9 changes: 8 additions & 1 deletion tests/helpers/calc/test_mathfuncs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from pytest import approx, raises
from mitxgraders.helpers.calc.exceptions import DomainError, FunctionEvalError
from mitxgraders.helpers.calc.mathfuncs import (
arctan2,
arctan2, kronecker,
cot, arccot,
csc, arccsc,
sec, arcsec,
Expand Down Expand Up @@ -125,3 +125,10 @@ def test_arctan2():
match = 'arctan2\(0, 0\) is undefined'
with raises(FunctionEvalError, match=match):
arctan2(0, 0)

def test_kronecker():
assert kronecker(1, 1) == 1
assert kronecker(1, 0) == 0
assert kronecker(0, 1) == 0
assert kronecker(0, 0) == 1
assert kronecker(1.5, 1.5) == 1