File:Cubic graph special points.svg

Original file (SVG file, nominally 512 × 614 pixels, file size: 17 KB)

Summary

Description
English: Graph showing the relationship between the roots, turning or stationary points and inflection point of a cubic polynomial and its first and second derivatives. The vertical scale is compressed 1:50 relative to the horizontal scale for ease of viewing. Thanks to Álvaro Lozano-Robledo for a method to find a cubic function with distinct special points with non-zero integer coordinates.
Source Own work
Author Cmglee
Other versions
Cubic graph special points repeated.svg
SVG development
InfoField
 
The source code of this SVG is invalid due to an error.
 
This W3C-invalid diagram was created with Python.
{{#switch:{{{1}}}|p=
Translate this file This SVG file contains embedded text that can be translated into your language, using any capable SVG editor, text editor or the SVG Translate tool. For more information see: About translating SVG files.
|P=
This file is translated using SVG <switch> elements. All translations are stored in the same file! Learn more.

For most Wikipedia projects, you can embed the file normally (without a lang parameter). The Wikipedia will use its language if the SVG file supports that language. For example, the German Wikipedia will use German if the SVG file has German. To embed this file in a particular language use the lang parameter with the appropriate language code, e.g. [[File:Cubic graph special points.svg|lang=en]] for the English version. Do not specify a lang parameter if it is not needed. The parameter may prevent the use of a subsequent translation.

To translate the text into your language, you can use the SVG Translate tool. Alternatively, you can download the file to your computer, add your translations using whatever software you're familiar with, and re-upload it with the same name. You will find help in Graphics Lab if you're not sure how to do this.

|vf|vs|vv|f=
 
This SVG diagram uses embedded text.
|#default=
 
This diagram uses .
import re, math
def fmt(string): ## string.format(**vars()) using tags {expression!format} by CMG Lee
 def f(tag): i_sep = tag.rfind('!'); return (re.sub('\.0$', '', str(eval(tag[1:-1])))
  if (i_sep < 0) else ('{:%s}' % tag[i_sep + 1:-1]).format(eval(tag[1:i_sep])))
 return (re.sub(r'(?<!{){[^{}]+}', lambda m:f(m.group()), string)
         .replace('{{', '{').replace('}}', '}'))
def append(obj, string): return obj.append(fmt(string))
def tabbify(cellss, separator='|'):
 cellpadss = [list(rows) + [''] * (len(max(cellss, key=len)) - len(rows)) for rows in cellss]
 fmts = ['%%%ds' % (max([len(str(cell)) for cell in cols])) for cols in zip(*cellpadss)]
 return '\n'.join([separator.join(fmts) % tuple(rows) for rows in cellpadss])

def format_sign(x): return ('%+d' % (x)).replace('+', '+ ').replace('-','&#8722; ')
def scale_x(x): return 50 * x
def scale_y(y): return -y
n_search     = 20
cubic_bez_dx = 15
quad_bez_dx  = 15
linear_dx    = 15
fmt_out = '{id}\
|{root0}|{root1}|{root2}|{max_x}|{max_y}|{min_x}|{min_y}|{inf_x}|{inf_y}|{inf_c}|{inf_m}\
|{cubic_b}|{cubic_c}|{cubic_d}|{quad_b}|{quad_c}\
'
double_dash = '-' * 2
outss = []
outs  = []
for i_pass in range(2): ## 0: to find best values, 1: output SVG
 id_best = None
 if (i_pass == 1):
  outss = sorted(outss, key=lambda outs:[max(abs(int(outs[5])), abs(int(outs[7]))),
                                         max(abs(int(outs[1])), abs(int(outs[3])))])
  id_best = int(outss[0][0])
  print(tabbify([fmt_out.replace('{','').replace('}','').split('|')] + outss))
 id = 0
 for   k2 in range(-n_search, n_search + 1):
  for  k1 in range(k2 + 1, n_search + 1):
   for k0 in range(k1 + 1, n_search + 1):
    (root0, root1, root2) = (-k0, -k1, -k2)
    if (root0 == 0 or root0 == root1 or
        root1 == 0 or root1 == root2 or
        root2 == 0 or root2 == root0): continue
    cubic_a   = 1
    cubic_b   = k0 + k1 + k2
    cubic_c   = k0 * k1 + k1 * k2 + k2 * k0
    cubic_d   = k0 * k1 * k2
    quad_a    = cubic_a * 3
    quad_b    = cubic_b * 2
    quad_c    = cubic_c
    linear_a  = quad_a * 2
    linear_b  = quad_b
    if (cubic_a == 0 or quad_a == 0 or linear_a == 0 or
        cubic_b == 0 or quad_b == 0 or linear_b == 0 or
        cubic_c == 0 or quad_c == 0 or
        cubic_d == 0): continue
    sqrt_disc = (4 * (k0 ** 2 + k1 ** 2 + k2 ** 2 - quad_c)) ** 0.5
    if ((quad_b + sqrt_disc) % linear_a != 0 or
        (quad_b - sqrt_disc) % linear_a != 0): continue
    (max_x, min_x) = [(-quad_b + sign * sqrt_disc) / linear_a for sign in (-1,1)]
    quad_bez_x1  = inf_x = (max_x + min_x) / 2
    linear_x0    = inf_x - linear_dx
    linear_x1    = inf_x + linear_dx
    cubic_bez_x0 = inf_x - cubic_bez_dx
    cubic_bez_x3 = inf_x + cubic_bez_dx
    (inf_y, max_y, min_y, cubic_bez_y0, cubic_bez_y3) = [
                    cubic_a * x ** 3 + cubic_b * x ** 2 + cubic_c * x + cubic_d
                    for x in (inf_x, max_x, min_x, cubic_bez_x0, cubic_bez_x3)]
    quad_bez_x0 = inf_x - quad_bez_dx
    quad_bez_x2 = inf_x + quad_bez_dx
    (inf_m, quad_bez_y0, quad_bez_y2, cubic_bez_m0, cubic_bez_m3) = [
                 quad_a * x ** 2 + quad_b * x + quad_c for x in
                 (inf_x, quad_bez_x0, quad_bez_x2, cubic_bez_x0, cubic_bez_x3)]
    inf_c       = inf_y - inf_m * inf_x
    quad_bez_y1 = ((linear_a * quad_bez_x0 + quad_b) * (quad_bez_x1 - quad_bez_x0) + quad_bez_y0)
    cubic_bez_x1 = (3 * inf_x - cubic_bez_dx) // 3 ## not sure how to get this
    cubic_bez_x2 = inf_x + (inf_x - cubic_bez_x1)
    cubic_bez_y1 = cubic_bez_m0 * (cubic_bez_x1 - cubic_bez_x0) + cubic_bez_y0
    cubic_bez_y2 = cubic_bez_m3 * (cubic_bez_x2 - cubic_bez_x3) + cubic_bez_y3
    if (id == id_best):
     path_cubic = fmt('''M {scale_x(cubic_bez_x0)},{scale_y(cubic_bez_y0)} C\
 {scale_x(cubic_bez_x1)},{scale_y(cubic_bez_y1)}\
 {scale_x(cubic_bez_x2)},{scale_y(cubic_bez_y2)}\
 {scale_x(cubic_bez_x3)},{scale_y(cubic_bez_y3)}''')
     path_quad = fmt('''M {scale_x(quad_bez_x0)},{scale_y(quad_bez_y0)} Q\
 {scale_x(quad_bez_x1)},{scale_y(quad_bez_y1)}\
 {scale_x(quad_bez_x2)},{scale_y(quad_bez_y2)}''')
     path_linear = fmt('''M {scale_x(linear_x0)},{scale_y(linear_x0 * linear_a + linear_b)} L\
 {scale_x(linear_x1)},{scale_y(linear_x1 * linear_a + linear_b)}''')
     path_tangent = fmt('''M {scale_x(float(min_y - inf_c) / inf_m)!.0f},{scale_y(min_y)} L\
 {scale_x(float(max_y - inf_c) / inf_m)!.0f},{scale_y(max_y)}''')
     append(outs,'''\
  <use xlink:href="#axes"/>
  <g stroke-width="4">
   <g mask="url(#mask_line)">
    <path class="line_cubic"   d="{path_cubic}"/>
    <path class="line_quad"    d="{path_quad}"   stroke-dasharray="20,5"/>
    <path class="line_linear"  d="{path_linear}" stroke-dasharray="6,4" stroke-width="6"/>
    <path class="line_tangent" d="{path_tangent}" stroke-dasharray="25,5,5,5,5,5"/>
   </g>
   <g class="line_concav">
    <path d="M {scale_x(max_x)},{scale_y(max_y)} V 0
             M {scale_x(min_x)},{scale_y(min_y)} V 0
             M {scale_x(inf_x)},{scale_y(inf_y)} V 500" stroke-dasharray="20,5,5,5"/>
    <path d="M -630 460 Q -630 470 -620 470 H 35 Q 45 470 45 460 M 55 460 Q 55 470 65 470 H 620 Q 630 470 630 460"/>
   </g>
  </g>
  <g stroke-width="8">
   <g class="label_cubic">
    <text class="equation" x="-70" y="-630"><tspan class="var">f</tspan><tspan dx="0.2ex">(</tspan><tspan class="var">x</tspan><tspan>) =&#160;</tspan><tspan class="var">x</tspan><tspan>&#179; {format_sign(cubic_b)}</tspan><tspan class="var">x</tspan><tspan>&#178; {format_sign(cubic_c)}</tspan><tspan class="var">x</tspan><tspan>&#160;{format_sign(cubic_d)}</tspan></text>
    <g transform="translate({scale_x(root0)},               0)"><use xlink:href="#root"/><text x="0.5ex"  y="2ex">root ({root0})</text></g>
    <g transform="translate({scale_x(root1)},               0)"><use xlink:href="#root"/><text x="0.5ex"  y="2ex">root ({root1})</text></g>
    <g transform="translate({scale_x(root2)},               0)"><use xlink:href="#root"/><text x="-0.5ex" y="2ex" class="end">root ({root2})</text></g>
    <g transform="translate({scale_x(max_x)},{scale_y(max_y)})"><use xlink:href="#tp"  /><text x="-9ex" y="-0.8ex">turning point, stationary point &amp; local maximum ({max_x}, {max_y})</text></g>
    <g transform="translate({scale_x(min_x)},{scale_y(min_y)})"><use xlink:href="#tp"  /><text x="5ex" y="2ex" class="end">turning point, stationary point &amp; local minimum ({min_x}, {min_y})</text></g>
    <g transform="translate({scale_x(inf_x)},{scale_y(inf_y)})"><use xlink:href="#ip"  /><text y="-1ex">falling inflection point ({inf_x}, {inf_y})</text></g>
    <!-{double_dash}
    <g transform="translate(0             ,{scale_y(cubic_d)})"><use xlink:href="#yi"  /><text x="0.5ex">y-intercept ({cubic_d})</text></g>
    {double_dash}>
   </g>
   <g class="label_quad">
    <text class="equation" x="-530" y="-260"><tspan class="var">f</tspan><tspan dx="0.2ex" class="var">'</tspan><tspan dx="0.2ex">(</tspan><tspan class="var">x</tspan><tspan>) = {quad_a}</tspan><tspan class="var">x</tspan><tspan>&#178; {format_sign(quad_b)}</tspan><tspan class="var">x</tspan><tspan>&#160;{format_sign(quad_c)}</tspan></text>
    <g transform="translate({scale_x(max_x)},               0)"><use xlink:href="#root"/><text x="0.5ex"  y="-0.2ex">root ({max_x})</text></g>
    <g transform="translate({scale_x(min_x)},               0)"><use xlink:href="#root"/><text x="-0.3ex" y="-0.2ex" class="end">root ({min_x})</text></g>
    <g transform="translate({scale_x(inf_x)},{scale_y(inf_m)})"><use xlink:href="#tp"  /><text x="-1ex" y="2ex" class="end"><tspan>turning point, stationary point</tspan><tspan x="-1ex" dy="2ex">&amp; local maximum ({inf_x}, {inf_m})</tspan></text></g>
    <use xlink:href="#tp"   transform="translate({scale_x(inf_x)},{scale_y(inf_m)})"/>
   </g>
   <g class="label_linear">
    <text class="equation" x="-560" y="120"><tspan class="var">f</tspan><tspan dx="0.2ex" class="var">''</tspan><tspan dx="0.2ex">(</tspan><tspan class="var">x</tspan><tspan>) = {linear_a}</tspan><tspan class="var">x</tspan><tspan>&#160;{format_sign(linear_b)}</tspan></text>
    <g transform="translate({scale_x(inf_x)},               0)"><use xlink:href="#root"/><text x="-0.5ex" y="-0.2ex" class="end">root ({inf_x})</text></g>
   </g>
   <g class="label_concav">
    <text x="-295" y="505"><tspan class="var">f</tspan><tspan dx="0.2ex">(</tspan><tspan class="var">x</tspan><tspan>) curve concave (downwards)</tspan></text>
    <text x="345"  y="505"><tspan class="var">f</tspan><tspan dx="0.2ex">(</tspan><tspan class="var">x</tspan><tspan>) convex (downwards)</tspan></text>
   </g>
   <g class="label_tangent">
    <g transform="translate(-140,-860)"><text><tspan>tangent at inflection point:</tspan><tspan x="15" dy="2ex" class="var">y</tspan><tspan>&#160;= -147</tspan><tspan class="var">x</tspan><tspan>&#160;+ 433</tspan></text></g>
   </g>
  </g>
''')
    outss.append(fmt(fmt_out).split('|'))
    id += 1

out_p = fmt('width="100%" height="100%" viewBox="-640 -1024 1280 1536"')

## Compile everything into an .svg file
myself   = open(__file__, 'r').read() ## the contents of this very file
file_out = open(__file__[:__file__.rfind('.')] + '.svg', 'w') ## *.* -> *.svg
try: ## use try/finally so that file is closed even if write fails
 file_out.write('''<?xml version="1.0" encoding="utf-8"?><!%s
%s%s%s\n%s%s''' % ('-' + '-', ## because SVG comments cannot have 2 consecutive '-'s
  myself[ : myself.find('width',myself.find('<svg'))], ## assume width specified before height/viewBox
  out_p, ## replace SVG width/height/viewBox with {out_p} & dynamic SVG block with {outs} contents
  myself[myself.find('>',myself.find('<svg')) : myself.find('\n',myself.find('BEGIN_'+'DYNAMIC_SVG'))],
  '\n'.join(outs), myself[myself.rfind('\n',0,myself.find('END_'+'DYNAMIC_SVG')) : ]))
finally:
 file_out.close()

## SVG-Python near-polyglot framework version 2 by CMG Lee (Feb 2016) -->

Licensing

I, the copyright holder of this work, hereby publish it under the following licenses:
w:en:Creative Commons
attribution share alike
This file is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license.
You are free:
  • to share – to copy, distribute and transmit the work
  • to remix – to adapt the work
Under the following conditions:
  • attribution – You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
  • share alike – If you remix, transform, or build upon the material, you must distribute your contributions under the same or compatible license as the original.
GNU head Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled GNU Free Documentation License.
You may select the license of your choice.

Captions

Add a one-line explanation of what this file represents

Items portrayed in this file

depicts

image/svg+xml

a61221eeba1b4683b672c939f4d93ab756a85a65

17,862 byte

614 pixel

512 pixel

File history

Click on a date/time to view the file as it appeared at that time.

(newest | oldest) View (newer 10 | ) (10 | 20 | 50 | 100 | 250 | 500)
Date/TimeThumbnailDimensionsUserComment
current01:08, 4 February 2024Thumbnail for version as of 01:08, 4 February 2024512 × 614 (17 KB)CmgleeWork around leading-or-trailing-nonbreaking-space-ignored rsvg bug: http://en.wikipedia.org/w/index.php?title=Wikipedia:SVG_help&diff=prev&oldid=1189400853
00:59, 4 February 2024Thumbnail for version as of 00:59, 4 February 2024512 × 614 (17 KB)CmgleeFix "global minimum" and use minus signs
06:35, 2 February 2024Thumbnail for version as of 06:35, 2 February 2024512 × 614 (17 KB)Opencooperrv: not sure if it's something I changed or changes in the renderer, but the new MediaWiki raster conversion doesn't preserve the non-breaking spaces and uses a spindly font
06:28, 2 February 2024Thumbnail for version as of 06:28, 2 February 2024512 × 614 (17 KB)Opencooperproper Unicode minus sign
18:18, 19 April 2019Thumbnail for version as of 18:18, 19 April 2019512 × 614 (17 KB)CmgleeUse exact cubic and quadratic Bézier curves instead of approximating with polylines, update labels, shrink markers and convert to near-polyglot Python.
09:44, 26 August 2013Thumbnail for version as of 09:44, 26 August 2013512 × 614 (19 KB)AnonMoosremove trivial syntax error, should now validate
19:30, 3 August 2012Thumbnail for version as of 19:30, 3 August 2012512 × 614 (19 KB)CmgleeAdd tangent at inflection point.
12:49, 3 August 2012Thumbnail for version as of 12:49, 3 August 2012512 × 614 (17 KB)CmgleeFix based on comments by Duoduoduo and 188.127.120.236.
21:18, 27 March 2012Thumbnail for version as of 21:18, 27 March 2012512 × 614 (17 KB)CmgleeAlign text labels.
20:59, 25 March 2012Thumbnail for version as of 20:59, 25 March 2012512 × 614 (17 KB)CmgleeRefine text labels.
(newest | oldest) View (newer 10 | ) (10 | 20 | 50 | 100 | 250 | 500)

The following 3 pages use this file:

Global file usage

The following other wikis use this file:

Metadata