function discretenewtons($func, $xmin, $xmax, $guess = null) { $func = makepretty($func); $func = mathphp($func, "x"); $func = str_replace("(x)", '($x)', $func); if ($guess == null) { $guess = ($xmin + $xmax) / 2; } $cnt = 0; $eps = 1.0E-7; $x = $guess; $curx = $guess; $dx = min(($xmax - $xmin) / 100, 0.001); $y = eval("return ({$func});"); while (abs($y) > $eps && $cnt < 20) { $x = $curx + $dx; $ny = eval("return ({$func});"); $m = ($ny - $y) / $dx; $curx = $curx - $y / $m; $x = $curx; $y = eval("return ({$func});"); $cnt++; } //echo "N cnt: $cnt. "; if ($cnt == 20) { if ($x > $xmax || $x < $xmin) { echo "Newton's did not converge within interval"; } else { echo "Newton's did not acheive good accuracy"; } return null; } else { if ($x > $xmax || $x < $xmin) { echo "Newton's did not converge within interval"; return null; } else { return $curx; } } }
function ASplot($function) { $funcstr = implode(',', $function); preg_match_all('/[a-zA-Z]+/', $funcstr, $matches, PREG_PATTERN_ORDER); $okfunc = array('sin', 'cos', 'tan', 'sec', 'csc', 'cot', 'arcsin', 'arccos', 'arctan', 'x', 't', 'log', 'ln', 'e', 'pi', 'abs', 'sqrt', 'safepow'); foreach ($matches[0] as $m) { if (!in_array($m, $okfunc)) { echo "{$m}"; return; } } //do safety check, as this will be eval'ed //$function = explode(',',str_replace(array('"','\'',';'),'',$function)); $function = str_replace(array('"', '\'', ';'), '', $function); if (strpos($function[0], '[') === 0) { $funcp = explode(',', $function[0]); $isparametric = true; $xfunc = str_replace("[", "", $funcp[0]); $xfunc = mathphp($xfunc, "t"); $xfunc = str_replace("(t)", '($t)', $xfunc); $exfunc = create_function('$t', 'return (' . $xfunc . ');'); $yfunc = str_replace("]", "", $funcp[1]); $yfunc = mathphp($yfunc, "t"); $yfunc = str_replace("(t)", '($t)', $yfunc); $eyfunc = create_function('$t', 'return (' . $yfunc . ');'); } else { $isparametric = false; $func = mathphp($function[0], "x"); $func = str_replace("(x)", '($x)', $func); $efunc = create_function('$x', 'return (' . $func . ');'); } $avoid = array(); if (isset($function[1]) && $function[1] != '' && $function[1] != 'null') { $xmin = $function[1]; } else { $xmin = $this->xmin - min($this->border[0], 5) / $this->xunitlength; } if (isset($function[2]) && $function[2] != '' && $function[2] != 'null') { $xmaxarr = explode('!', $function[2]); $xmax = $xmaxarr[0]; $avoid = array_slice($xmaxarr, 1); } else { $xmax = $this->xmax + min($this->border[2], 5) / $this->xunitlength; } $xmin += ($xmax - $xmin) / 100000; //avoid divide by zero errors if (isset($function[3]) && $function[3] != '' && $function[3] != 'null') { $dx = ($xmax - $xmin) / ($function[3] - 1); $stopat = $function[3]; } else { $dx = ($xmax - $xmin) / 100; $stopat = 101; } $px = null; $py = null; $lasty = 0; $lastl = 0; for ($i = 0; $i < $stopat; $i++) { if ($isparametric) { $t = $xmin + $dx * $i; if (in_array($t, $avoid)) { continue; } $x = $exfunc($t); $y = $eyfunc($t); if (is_nan($x) || is_nan($y)) { continue; } } else { $x = $xmin + $dx * $i; if (in_array($x, $avoid)) { continue; } $y = $efunc($x); if (is_nan($y)) { continue; } } if ($i < 2 || $i == $stopat - 2) { $fx[$i] = $x; $fy[$i] = $y; } $lastx = $x; /*if (abs($y-$lasty) > ($this->ymax-$this->ymin)) { if ($lastl > 1) { $lastl = 0; }//break path $lasty = $y; } else { $lasty = $y; if ($lastl > 0) { $this->ASline(array("[$px,$py]","[$x,$y]")); } $px = $x; $py = $y; $lastl++; }*/ if ($py == null) { //starting line } else { if ($y > $this->ymax || $y < $this->ymin) { //going or still out of bounds if ($py <= $this->ymax && $py >= $this->ymin) { //going out if ($y > $this->ymax) { //going up $iy = $this->ymax + min($this->border[3], 5) / $this->yunitlength; } else { //going down $iy = $this->ymin - min($this->border[1], 5) / $this->yunitlength; } $ix = ($x - $px) * ($iy - $py) / ($y - $py) + $px; $this->ASline(array("[{$px},{$py}]", "[{$ix},{$iy}]")); } else { //still out } } else { if ($py > $this->ymax || $py < $this->ymin) { //coming or staying in bounds if ($y <= $this->ymax && $y >= $this->ymin) { //comin in if ($py > $this->ymax) { //comin from top $iy = $this->ymax + min($this->border[3], 5) / $this->yunitlength; } else { //coming from bottom $iy = $this->ymin - min($this->border[1], 5) / $this->yunitlength; } $ix = ($x - $px) * ($iy - $py) / ($y - $py) + $px; $this->ASline(array("[{$ix},{$iy}]", "[{$x},{$y}]")); } else { //still out } } else { //all in $this->ASline(array("[{$px},{$py}]", "[{$x},{$y}]")); } } } $px = $x; $py = $y; } if (isset($function[5]) && $function[5] != '' && $function[5] != 'null') { if ($function[5] == 1) { //need pt2arr for xunit adjust $this->ASarrowhead($this->pt2arr("{$fx[1]},{$fy[1]}"), $this->pt2arr("{$fx[0]},{$fy[0]}")); } else { if ($function[5] == 2) { $this->ASdot2(array("[{$fx[0]},{$fy[0]}]", "open")); } else { if ($function[5] == 3) { $this->ASdot2(array("[{$fx[0]},{$fy[0]}]", "closed")); } } } } if (isset($function[6]) && $function[6] != '' && $function[6] != 'null') { if ($function[6] == 1) { $this->ASarrowhead($this->pt2arr("{$fx[$stopat - 2]},{$fy[$stopat - 2]}"), $this->pt2arr("{$x},{$y}")); } else { if ($function[6] == 2) { $this->ASdot2(array("[{$x},{$y}]", "open")); } else { if ($function[6] == 3) { $this->ASdot2(array("[{$x},{$y}]", "closed")); } } } } }
function spacecurve($func, $tmin, $tmax) { global $imasroot; if ($GLOBALS['inquestiondisplay'] == false) { return ''; } if (func_num_args() > 3) { $disc = func_get_arg(3); if (!is_numeric($disc)) { $disc = 50; } } else { $disc = 50; } if (func_num_args() > 5) { $width = func_get_arg(4); $height = func_get_arg(5); } else { $width = 300; $height = 300; } if (func_num_args() > 6) { $axes = func_get_arg(6); } else { $axes = 1; } if (func_num_args() > 12) { $bounds = array_slice(func_get_args(), 7, 6); } $useragent = $_SERVER['HTTP_USER_AGENT']; $oldschool = false; if (isset($GLOBALS['sessiondata']['useflash'])) { $oldschool = true; } else { if (preg_match('/MSIE\\s*(\\d+)/i', $useragent, $matches)) { if ($matches[1] < 9) { $oldschool = true; } } } if ($oldschool) { $func = str_replace('[', '', $func); $func = str_replace(']', '', $func); $func = explode(',', $func); $func[0] = "(1+.01*cos(u))*({$func[0]})"; $func[1] = "(1+.01*cos(u))*({$func[1]})"; $func[2] = "(1+.01*sin(u))*({$func[2]})"; foreach ($func as $k => $v) { $func[$k] = mathphp($v, 'u|t'); $func[$k] = str_replace('(u)', '($u)', $func[$k]); $func[$k] = str_replace('(t)', '($t)', $func[$k]); $usefunc[$k] = create_function('$u,$t', 'return(' . $func[$k] . ');'); } $count = 0; $dt = ($tmax - $tmin) / ($disc - 1); for ($i = 0; $i < 4; $i++) { for ($j = 0; $j < $disc; $j++) { if ($count > 0) { $verts .= '~'; } $u = 1.571 * $i; $t = $vmin + $dt * $j; $x = $usefunc[0]($u, $t); $y = $usefunc[1]($u, $t); $z = $usefunc[2]($u, $t); $verts .= "{$x},{$y},{$z}"; $count++; } } $count = 0; for ($i = 0; $i < 3; $i++) { for ($j = 0; $j < $disc - 1; $j++) { if ($count > 0) { $faces .= '~'; } $faces .= $i * $disc + $j . ','; $faces .= ($i + 1) * $disc + $j . ','; $faces .= ($i + 1) * $disc + $j + 1 . ','; $faces .= $i * $disc + $j + 1; $count++; } } if (!isset($GLOBALS['3dplotcnt'])) { $r = 1; } else { $r = $GLOBALS['3dplotcnt'] + 1; } $GLOBALS['3dplotcnt'] = $r; $html .= "<div id=\"plot3d{$r}\">"; $html .= '<p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>'; $html .= '</div>'; $html .= '<script type="text/javascript">'; $html .= 'var FlashVars = {'; $html .= ' verts: "' . $verts . '",'; $html .= ' faces: "' . $faces . '",'; $html .= " width: {$width}, height: {$height} };"; $html .= " swfobject.embedSWF(\"{$imasroot}/assessment/libs/viewer3d.swf\", \"plot3d{$r}\", \"{$width}\", \"{$height}\", \"9.0.0\", \"{$imasroot}/assessment/libs/expressInstall.swf\",FlashVars);"; $html .= '</script>'; /*if (isset($GLOBALS['sessiondata']['useflash'])) { } else { $html = "<applet codebase=\"{$GLOBALS['imasroot']}/assessment/libs\" code=\"Viewer.class\" width=$width height=$height>\n"; $html .= "<param name=\"verts\" value=\"$verts\">\n"; $html .= "<param name=\"faces\" value=\"$faces\">\n"; if ($axes==1) { $html .= "<param name=\"axes\" value=\"show\">\n"; } else { $html .= "<param name=\"axes\" value=\"hide\">\n"; } $html .= "<param name=\"edges\" value=\"hide\">\n"; if (isset($bounds)) { $html .= "<param name=\"bounds\" value=\"" . implode(',',$bounds) . "\">\n"; } $url = $GLOBALS['urlmode'] . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . (isset($_SERVER['QUERY_STRING'])?'?'.$_SERVER['QUERY_STRING'].'&useflash=true':'?useflash=true'); $html .= "Not seeing the 3D graph? <a href=\"$url\">Try Alternate</a></applet>\n"; } */ } else { //new approach $func = str_replace('[', '', $func); $func = str_replace(']', '', $func); $func = explode(',', $func); foreach ($func as $k => $v) { $func[$k] = mathphp($v, 't'); $func[$k] = str_replace('(t)', '($t)', $func[$k]); $usefunc[$k] = create_function('$t', 'return(' . $func[$k] . ');'); } $count = 0; $dt = ($tmax - $tmin) / ($disc - 1); for ($j = 0; $j < $disc; $j++) { if ($count > 0) { $verts .= '~'; } $t = $vmin + $dt * $j; $x = $usefunc[0]($t); $y = $usefunc[1]($t); $z = $usefunc[2]($t); $verts .= "{$x},{$y},{$z}"; $count++; } if (!isset($GLOBALS['3dplotcnt'])) { $r = 1; $html .= '<script type="text/javascript" src="' . $imasroot . '/javascript/3dviewer.js"></script>'; } else { $r = $GLOBALS['3dplotcnt'] + 1; } $GLOBALS['3dplotcnt'] = $r; $html .= "<canvas id=\"plot3d{$r}\" width=\"{$width}\" height=\"{$height}\">"; $url = $GLOBALS['urlmode'] . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . (isset($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] . '&useflash=true' : '?useflash=true'); $html .= "Not seeing the 3D graph? <a href=\"{$url}\">Try Alternate</a>"; $html .= "</canvas>"; $html .= "<script type=\"text/javascript\">\$(window).on('load',function() {var plot3d{$r} = new Viewer3D({verts: '{$verts}', curves: true, width: '{$width}', height:'{$height}'}, 'plot3d{$r}');});</script>"; } return $html; }
function checklineagainstdata($xarr, $yarr, $line, $var = "x", $alpha = 0.05) { if (!is_array($xarr)) { $xarr = explode(',', $xarr); } if (!is_array($yarr)) { $yarr = explode(',', $yarr); } if (count($xarr) != count($yarr)) { echo "Error: linreg requires xarray length = yarray length"; return false; } if (count($xarr) < 3) { echo "Requires 3 or more data values"; return false; } $sx = array_sum($xarr); $sy = array_sum($yarr); $sxx = 0; $syy = 0; $sxy = 0; for ($i = 0; $i < count($xarr); $i++) { $sxx += $xarr[$i] * $xarr[$i]; $syy += $yarr[$i] * $yarr[$i]; $sxy += $xarr[$i] * $yarr[$i]; } $n = count($xarr); $r = ($n * $sxy - $sx * $sy) / (sqrt($n * $sxx - $sx * $sx) * sqrt($n * $syy - $sy * $sy)); $m = ($n * $sxy - $sx * $sy) / ($n * $sxx - $sx * $sx); $b = ($sy - $sx * $m) / $n; if ($line == '') { return array('', makepretty("`{$m} {$var} + {$b}`")); } foreach ($_POST as $k => $v) { //try to catch junk answers if ($v == $line) { if (preg_match('/[^,\\d\\.\\-]/', $_POST['qn' . substr($k, 2) . '-vals'])) { return array('', makepretty("`{$m} {$var} + {$b}`")); } } } $linec = mathphp(makepretty($line), $var); $linec = str_replace("({$var})", '($t)', $linec); $linefunc = create_function('$t', 'return(' . $linec . ');'); $xmin = min($xarr); $xmax = max($xarr); $dx = ($xmax - $xmin) / 5; if ($dx <= 0) { echo "error with xmin/xmax"; return false; } $isinbounds = true; $sqres = 0; for ($i = 0; $i < count($xarr); $i++) { $sqres += ($yarr[$i] - ($m * $xarr[$i] + $b)) * ($yarr[$i] - ($m * $xarr[$i] + $b)); } $sqres = sqrt($sqres / ($n - 2)); $sdiv = $sxx - $sx * $sx / $n; $tcrit = abs(invtcdf($alpha / 2, $n - 2)); $xbar = $sx / $n; for ($x = $xmin; $x < $xmax * 1.02; $x += $dx) { $ypred = $m * $x + $b; $yline = $linefunc($x); $yconf = $tcrit * $sqres * sqrt(1 + 1 / $n + ($x - $xbar) * ($x - $xbar) / $sdiv); if (abs($ypred - $yline) > $yconf) { $isinbounds = false; break; } } if ($isinbounds) { return array($line, makepretty("{$m} {$var} + {$b}")); } else { return array("({$line}) + 200000", makepretty("`{$m} {$var} + {$b}`")); } }
function parsesloppycomplex($v) { $v = mathphp($v, 'i'); $v = str_replace('(i)', '($i)', $v); $a = eval('$i=0;return (' . $v . ');'); $apb = eval('$i=1;return (' . $v . ');'); return array($a, $apb - $a); }
function parseFloat($input) { if (preg_match("/-\\s*oo/i", $input)) { return array(-INF, "-oo", false); } elseif (preg_match("/\\+?oo/i", $input)) { return array(INF, "oo", false); } $result = eval("return (" . mathphp($input, null) . ");"); $error = $result === false || is_string($result); return array($result, $input, $error); }
function ineqbetweenplot($funcs) { if (!is_array($funcs)) { settype($funcs, "array"); } $settings = array(-5, 5, -5, 5, 1, 1, 200, 200); for ($i = 1; $i < func_num_args(); $i++) { $settings[$i - 1] = func_get_arg($i); } $ymin = $settings[2]; $ymax = $settings[3]; $commands = "setBorder(5); initPicture({$settings[0]},{$settings[1]},{$settings[2]},{$settings[3]});"; $alt = "Graph, window x {$settings[0]} to {$settings[1]}, y {$settings[2]} to {$settings[3]}."; if (strpos($settings[4], ':')) { $lbl = explode(':', $settings[4]); } if (is_numeric($settings[4]) && $settings[4] > 0) { $commands .= 'axes(' . $settings[4] . ',' . $settings[4] . ',1'; } else { if (isset($lbl[0]) && is_numeric($lbl[0]) && $lbl[0] > 0 && $lbl[1] > 0) { $commands .= 'axes(' . $lbl[0] . ',' . $lbl[1] . ',1'; } else { $commands .= 'axes(1,1,null'; } } if (strpos($settings[5], ':')) { $grid = explode(':', $settings[5]); } if (is_numeric($settings[5]) && $settings[5] > 0) { $commands .= ',' . $settings[5] . ',' . $settings[5] . ');'; $dgrid = $settings[5]; } else { if (isset($grid[0]) && is_numeric($grid[0]) && $grid[0] > 0 && $grid[1] > 0) { $commands .= ',' . $grid[0] . ',' . $grid[1] . ');'; $dgrid = $grid[0]; } else { $commands .= ');'; $dgrid = 1; } } foreach ($funcs as $k => $function) { $alt .= "Start Graph"; $function = explode(",", $function); //correct for parametric $func = makepretty($function[0]); $func = mathphp($func, "x"); $func = str_replace("x", '$x', $func); $xfunc = create_function('$x', 'return (' . $func . ');'); //even though ASCIIsvg has a plot function, we'll calculate it here to hide the function // function of x,filltype,fillcolor,linecolor,dash,strokewidth $path = ''; $shades = ''; $filltype = $function[1]; $shades .= "stroke=\"blue\";strokedasharray=\"none\";"; $alt .= "Shaded in blue " . substr($filltype, 0, 5); if ($function[2] != '') { $path .= "stroke=\"{$function[2]}\";"; $alt .= ", Color {$function[2]}"; } else { $path .= "stroke=\"black\";"; $alt .= ", Color black"; } if ($function[4] != '') { $path .= "strokewidth=\"{$function[4]}\";"; } else { $path .= "strokewidth=\"1\";"; } if ($function[3] != '') { if ($function[3] == "dash") { $path .= "strokedasharray=\"5\";"; $alt .= ", Dashed"; } else { $path .= "strokedasharray=\"none\";"; } } else { $path .= "strokedasharray=\"none\";"; } $xmin = $settings[0]; $xmax = $settings[1]; if ($GLOBALS['sessiondata']['graphdisp'] == 0) { $dx = 1; $alt .= "<table class=stats><thead><tr><th>x</th><th>y</th></thead></tr><tbody>"; $stopat = $xmax - $xmin + 1; } else { $dx = ($xmax - $xmin) / 100; $stopat = 100; } $lasty = 0; $lastl = 0; for ($i = 0; $i < $stopat; $i++) { $x = $xmin + $dx * $i; $y = round($xfunc($x), 3); $alt .= "<tr><td>{$x}</td><td>{$y}</td></tr>"; if (abs($y - $lasty) > $ymax - $ymin) { if ($lastl > 1) { $path .= ']);'; $lastl = 0; } $lasty = $y; } else { if ($lastl == 0) { $path .= "path(["; } else { $path .= ","; } $path .= "[{$x},{$y}]"; $lasty = $y; $lastl++; } } if ($lastl > 0) { $path .= "]);"; } $alt .= "</tbody></table>\n"; $commands .= $path; //do shades for ($i = 0; $i < ($xmax - $xmin) * 4 / $dgrid; $i++) { $x = $xmin + $dgrid * (0.125 + 0.25 * $i); $y = round($xfunc($x), 3); if ($filltype == "above") { $mins[$i][] = $y; } else { if ($filltype == "below") { $maxs[$i][] = $y; } } } } for ($i = 0; $i < ($xmax - $xmin) * 4 / $dgrid; $i++) { $x = $xmin + $dgrid * (0.125 + 0.25 * $i); if (count($mins) == 0) { $miny = $ymin - 2; } else { $miny = max($mins[$i]); } if (count($maxs) == 0) { $maxy = $ymax + 2; } else { $maxy = min($maxs[$i]); } if ($miny < $maxy) { $shades .= "line([{$x},{$miny}],[{$x},{$maxy}]);"; } } $commands .= $shades; if ($GLOBALS['sessiondata']['graphdisp'] == 0) { return $alt; } else { return "<embed type='image/svg+xml' align='middle' width='{$settings['6']}' height='{$settings['7']}' src='{$GLOBALS['imasroot']}/javascript/d.svg' script='{$commands}' />\n"; } }
function calculusnumint($func, $var, $a, $b, $n, $method) { if ($n <= 0 || $a >= $b) { echo "invalid params to calculusnumint"; return false; } if ($method == 'simpsons' && $n % 2 != 0) { echo "simpsons requires even n"; return false; } $func = makepretty($func); $func = mathphp($func, $var); if ($func == '0;') { return 0; } $func = str_replace("({$var})", "(\${$var})", $func); $evalfunc = create_function("\${$var}", 'return(' . $func . ');'); $dx = ($b - $a) / $n; if ($method == 'right') { $x = $a + $dx; } else { if ($method == 'midpoint') { $x = $a + 0.5 * $dx; } else { $x = $a; } } if ($method == 'left' || $method == 'right' || $method == 'midpoint') { $ntodo = $n; } else { $ntodo = $n + 1; } $out = 0; $mult = 1; for ($i = 0; $i < $ntodo; $i++) { if ($method == 'trapezoidal') { if ($i == 0 || $i == $n) { $mult = 1; } else { $mult = 2; } } else { if ($method == 'simpsons') { if ($i == 0 || $i == $n) { $mult = 1; } else { if ($i % 2 == 0) { $mult = 2; } else { $mult = 4; } } } } $out += $mult * $evalfunc($x); $x += $dx; } if ($method == 'trapezoidal') { return $out * $dx / 2; } else { if ($method == 'simpsons') { return $out * $dx / 3; } else { return $out * $dx; } } }
function getnumbervalue($a) { $a = str_replace(',', '', $a); if (is_numeric($a)) { return $a * 1; } else { $a = @eval('return(' . mathphp($a, null) . ');'); return $a; } }