裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

数学問題-6

2020年11月10日 | ブログラミング
Python では sympy を使う
WolframAlpha の「高等学校 数学」の例題を解いてみる


問題 n が無限大に近付くときの √(n)(√ (n+2)-√n) の極限

>>> from sympy import *
>>> var('a:z')
(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)

>>> limit(sqrt(n) * (sqrt(n + 2) - sqrt(n)), n, oo) # 'oo' means ∞ i.e. inf
1


コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

数学問題-5

2020年11月10日 | ブログラミング
Python では sympy を使う
WolframAlpha の「高等学校 数学」の例題を解いてみる

問題 z^6+27=0 を解く

>>> from sympy import *
>>> var('a:z')
(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)

>>> f = z**6 + 27
>>> solve(f)
[-sqrt(3)*I, sqrt(3)*I, -3/2 - sqrt(3)*I/2, -3/2 + sqrt(3)*I/2, 3/2 - sqrt(3)*I/2, 3/2 + sqrt(3)*I/2]

因数分解して,一次式,二次式を解くと以下のようになる

>>> factor(f)
(z**2 + 3)*(z**2 - 3*z + 3)*(z**2 + 3*z + 3)
>>> solve(z**2-3*z+3)
[3/2 - sqrt(3)*I/2, 3/2 + sqrt(3)*I/2]
>>> solve(z**2+3*z+3)
[-3/2 - sqrt(3)*I/2, -3/2 + sqrt(3)*I/2]

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

数学問題-4

2020年11月10日 | ブログラミング
Python では sympy を使う
WolframAlpha の「高等学校 数学」の例題を解いてみる

問題 sin x + cos x = 1 を解く

>>> from sympy import *
>>> var('a:z')
(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)

>>> f = sin(x) + cos(x) - 1
>>> ans = solve(f)
>>> ans
[0, pi/2]
>>> f.subs(x, ans[0]).evalf()
0
>>> f.subs(x, ans[1]).evalf()
0

以下の図で確認

>>> from sympy.plotting import plot
>>> plot(f, (x, -0.1, 1.7))



コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

数学問題-二重根号の簡約(Python 版)

2020年11月10日 | ブログラミング
数学問題-3 で,「二重根号の簡約は,直接的に解を求める事が出来ない(simplify では解が得られない)」と書いたが,解を求めるプログラムを Python で書いてみた。エラーチェックや,数式を引数にするという書式にしたので,ちょっと長くなった。

使用例

>>> double_root("sqrt(6-sqrt(32))")
('2-sqrt(2)', 0.5857864376269049)
>>> double_root("sqrt(6-2*sqrt(8))")
('2-sqrt(2)', 0.5857864376269049)
>>> double_root("sqrt(106+2*sqrt(1288))")
('sqrt(92)+sqrt(14)', 13.33332043339938)
>>> double_root("sqrt(106+sqrt(5152))")
('sqrt(92)+sqrt(14)', 13.33332043339938)
>>> double_root("sqrt(106+4*sqrt(322))")
('sqrt(92)+sqrt(14)', 13.33332043339938)
>>> double_root("sqrt(106+sqrt(368))")
"can't simplify"
>>> double_root("sqrt(-16+sqrt(368))")
"can't simplify"
>>> double_root("sqrt(16-sqrt(-368))")
'square root of negative value is not allowed (inner sqrt)'
>>> double_root("sqrt(16+sqrt(-368))")
'square root of negative value is not allowed (inner sqrt)'
>>> double_root("sqrt(16-sqrt(368))")
'square root of negative value is not allowed (outer sqrt)'
>>> double_root("sqrt(18+2*sqrt(81))")
('6', 6)
>>> double_root("sqrt(18-2*sqrt(81))")
('0', 0)
>>> double_root("sqrt(13+sqrt(144))")
('5', 5)
>>> double_root("sqrt(13-sqrt(144))")
('1', 1)


プログラム
>>> import re
>>> import numpy as np
>>> from math import sqrt
>>> 
>>> def double_root(equation):
...     def solve(a_plus_b, a_mult_b):
...         for b in range(1, int(a_mult_b**0.5 + 1)):
...             if a_mult_b % b == 0 and a_plus_b == b + a_mult_b // b:
...                 return (a_mult_b // b, b)
...         return (np.nan, np.nan)
...     def simplify(a):
...         int_root = int(a**0.5)
...         if int_root**2 == a:
...             return str(int_root)
...         else:
...             return "sqrt(%d)" % a
...     inner = re.sub("sqrt\(", "", equation, 1)
...     inner = re.sub("\)", "", inner, 1)
...     match = re.search("sqrt\(-[0-9]*\)", equation)
...     if match is not None:
...         return "square root of negative value is not allowed (inner sqrt)"
...     elif eval(inner) < 0:
...         return "square root of negative value is not allowed (outer sqrt)"
...     result1 = eval(equation)
...     sign = '+' if re.search('-', equation) is None else '-'
...     equation = re.sub("\)", "", equation)
...     equation = re.sub("sqrt\(", "", equation)
...     equation = re.sub("[-+*]", ",", equation)
...     # print(equation)
...     if equation[0] == ',':
...         return "can't simplify"
...     parsed = list(map(int, equation.split(",")))
...     # print(parsed)
...     if len(parsed) == 3:
...         parsed[1] = parsed[1]**2 * parsed[2]
...     parsed[1] = parsed[1] / 4
...     if parsed[1] != int(parsed[1]):
...         return "can't simplify"
...     # print(parsed[1], parsed[2], "\n")
...     res = solve(parsed[0], int(parsed[1]))
...     if np.isnan(res[0]):
...         return 'can\'t simplify'
...     res_str = "%s%s%s" % (simplify(res[0]), sign, simplify(res[1]))
...     result2 = eval(res_str)
...     if np.allclose(result1, result2):
...         if int(result2) == result2:
...             res0, res1 = sqrt(res[0]), sqrt(res[1])
...             res_str = str(int(res0 + res1)) if sign == '+' else str(int(res0 - res1))
...         return res_str, eval(res_str)
...     return "error: original = %g, simplified = %g" % (result1, result2)
	
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

数学問題-二重根号の簡約(R 版)

2020年11月10日 | ブログラミング
数学問題-3 で,「二重根号の簡約は,直接的に解を求める事が出来ない(simplify では解が得られない)」と書いたが,解を求めるプログラムを R で書いてみた。エラーチェックや,数式を引数にするという書式にしたので,ちょっと長くなった。

使用例

> double.root("sqrt(6-sqrt(32))")
$equation
[1] "2 - sqrt(2)"

$expression
expression(2 - sqrt(2))

$eval
[1] 0.5857864

> double.root("sqrt(6-2*sqrt(8))")
$equation
[1] "2 - sqrt(2)"

$expression
expression(2 - sqrt(2))

$eval
[1] 0.5857864

> double.root("sqrt(106+2*sqrt(1288))")
$equation
[1] "sqrt(92) + sqrt(14)"

$expression
expression(sqrt(92) + sqrt(14))

$eval
[1] 13.33332

> double.root("sqrt(106+sqrt(5152))")
$equation
[1] "sqrt(92) + sqrt(14)"

$expression
expression(sqrt(92) + sqrt(14))

$eval
[1] 13.33332

> double.root("sqrt(106+4*sqrt(322))")
$equation
[1] "sqrt(92) + sqrt(14)"

$expression
expression(sqrt(92) + sqrt(14))

$eval
[1] 13.33332

> double.root("sqrt(106+sqrt(368))")
[1] "can't simplify"
> double.root("sqrt(-16+sqrt(368))")
[1] "can't simplify"
> double.root("sqrt(16-sqrt(-368))")
[1] "square root of negative value is not allowed (inner sqrt)"
> double.root("sqrt(16+sqrt(-368))")
[1] "square root of negative value is not allowed (inner sqrt)"
> double.root("sqrt(16-sqrt(368))")
[1] "square root of negative value is not allowed (outer sqrt)"
> double.root("sqrt(18+2*sqrt(81))")
$equation
[1] "6"

$expression
expression(6)

$eval
[1] 6

> double.root("sqrt(13+sqrt(144))")
$equation
[1] "5"

$expression
expression(5)

$eval
[1] 5

プログラム
double.root = function(equation) {
  solve = function(a.plus.b, a.mult.b) {
    for (b in 1:sqrt(a.mult.b)) {
      if (a.mult.b %% b == 0 && a.plus.b == b + a.mult.b %/% b) {
        return(list(a = a.mult.b %/% b, b = b))
      }
    }
    return(NA)
  }
  simplify = function(a) {
    int.root = trunc(sqrt(a))
    if (int.root ^ 2 == a) {
      return(sprintf("%d", int.root))
    } else {
      return(sprintf("sqrt(%d)", a))
    }
  }
  inner = sub("\\)$", "", sub("sqrt\\(", "", equation))
  if (grepl("sqrt\\(-[0-9]*\\)", equation)) {
    return("square root of negative value is not allowed (inner sqrt)")
  } else if (eval(parse(text = inner)) < 0) {
    return("square root of negative value is not allowed (outer sqrt)")
  }
  result1 = eval(parse(text = equation))
  sign = ifelse(grepl("-", equation), "-", "+")
  equation = gsub("sqrt\\(", "", equation)
  equation = gsub("\\)", "", equation)
  # print(equation)
  parsed = as.integer(unlist(strsplit(equation, "[-+*]")))
  # print(parsed)
  if (is.na(parsed[1])) {
    return("can't simplify")
  }
  if (length(parsed) == 3) {
    parsed[2] = parsed[2] ^ 2 * parsed[3]
  }
  parsed[2] = parsed[2] / 4
  if (parsed[2] != trunc(parsed[2])) {
    return("can't simplify")
  }
  # cat(parsed[1], parsed[2], "\n")
  res = solve(parsed[1], parsed[2])
  if (length(res) != 2) {
    return("can't simplify")
  }
  res.str = paste(simplify(res$a), sign, simplify(res$b))
  result2 = eval(parse(text = res.str))
  if (all.equal(result1, result2)) {
      if (sign == "+") {
        res.str = as.character(sqrt(res$a) + sqrt(res$b))
      } else {
        res.str = as.character(sqrt(res$a) - sqrt(res$b))
      }
    result = parse(text = res.str)
    return(list(
      equation = res.str,
      expression = result,
      eval = eval(result)
    ))
  }
  return(sprintf("error: original = %g, simplified = %g", result1, result2))
}

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

数学問題-3

2020年11月10日 | ブログラミング
Python では sympy を使う
WolframAlpha の「高等学校 数学」の例題を解いてみる
https://ja.wolframalpha.com/examples/mathematics/koukousugaku/
 
二重根号の簡約は,直接的に解を求める事が出来ない(simplify では解が得られない)。
そこで,解法の基礎に帰って,それを sympy で解く。
 
問題 sqrt(124 - 6*sqrt(291)) を簡約する
 
>>> from sympy import *
>>> import math

>>> var('a, b, x, y')
(a, b, x, y)

>>> x = 124
>>> y = 10476 # = 36*291 = 4*2619
>>> simplify(sqrt(x-sqrt(y))) # math.sqrt(x - math.sqrt(y))
sqrt(124 - 6*sqrt(291))
>>> simplify(sqrt(x-2*sqrt(y//4)))
sqrt(124 - 6*sqrt(291))

>>> simplify(sqrt(a+b-2*sqrt(a*b))) # この形にしたい
sqrt(a + b - 2*sqrt(a*b)) # == sqrt(b) - sqrt(a), b > a
>>> eq1 = Eq(a+b, x)
>>> eq2 = Eq(a*b, y//4)
>>> res = solve([eq1, eq2]) # 連立方程式を解く
>>> res
[{a: 27, b: 97}, {a: 97, b: 27}] # a = 27, b = 97 が解
>>> a2, b2 = list(res[0].values())
>>> a2+b2
124
>>> a2*b2
2619
>>> ans0 = sqrt(a2+b2-2*sqrt(a2*b2)) # math.sqrt(124 - 2*math.sqrt(2619))
>>> ans1 = sqrt(max(a2, b2)) - sqrt(min(a2, b2)) # math.sqrt(97) - math.sqrt(27)
>>> ans0 == ans1
False # 等しくはないが
>>> ans1.evalf(), ans0.evalf()
(4.65270537908947, 4.65270537908947) # 実質的に等しい
>>> (ans0 - ans1).evalf()
0.e-121



コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

数学問題-2

2020年11月10日 | ブログラミング
Python では sympy を使う
WolframAlpha の「高等学校 数学」の例題を解いてみる
https://ja.wolframalpha.com/examples/mathematics/koukousugaku/

問題 f(x)=log(x)/x^2の最大値 を求める

>>> from sympy import *
>>> from sympy.plotting import plot
>>> var('a:z')
(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)

>>> func = log(x)/x**2 # 関数
>>> func
log(x)/x**2
>>> func2 = diff(func) # 導関数
>>> func2
-2*log(x)/x**3 + x**(-3)
>>> ans = solve(func2) # 導関数 = 0 を解く
>>> ans
[exp(1/2)]
>>> ans[0].evalf()
1.64872127070013
>>> func2.subs(x, ans[0])
0
>>> max = func.subs(x, ans[0]) # 最大値
>>> max
exp(-1)/2
>>> max.evalf()
0.183939720585721


図を描いて確かめておく

>>> plot(func, (x, 1.3, 2))


コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

数学問題

2020年11月10日 | ブログラミング
Python では sympy を使う
WolframAlpha の「高等学校 数学」の例題を解いてみる
https://ja.wolframalpha.com/examples/mathematics/koukousugaku/

問題 (1/8)^x ≦ 7(1/2)^x-6をみたす実数xを求める

>>> from sympy import *
>>> from sympy.plotting import plot
>>> var('a:z')
(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)
>>> func1 = (1/8)**x
>>> func2 = 7*(1/2)**x - 6
>>> solve(Eq(func1, func2), x)
[-1.00000000000000, 0.0, -1.58496250072116 + 4.53236014182719*I]

以下のように図を描いて,答えは -1 ≦ x ≦ 0 であることがわかる

>>> p = plot(func1, func2, (x, -1.1, 0.1), legend=True, ylabel='', show=False)
>>> p[0].line_color = 'b'
>>> p[1].line_color = 'r'
>>> p.show()
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

数式処理-3

2020年11月10日 | ブログラミング
Python では sympy を使う
WolframAlpha の「代数」の例題 3 題を解いてみる
https://ja.wolframalpha.com/examples/mathematics/

>>> from sympy import *
>>> var('a:z')
(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)

問題 1. 方程式を解く x^3 - 4x^2 + 6x - 24 = 0

>>> solve(x**3 - 4*x**2 + 6*x -24)
[4, -sqrt(6)*I, sqrt(6)*I]

問題 2.  多項式を因数分解する 2x^5 - 19x^4 + 58x^3 - 67x^2 + 56x - 48

>>> factor(2*x**5 - 19*x**4 + 58*x**3 -67*x**2 + 56*x - 48)
(x - 4)**2*(2*x - 3)*(x**2 + 1)

問題 3. 式を簡約する 1/(1+√2)

>>> simplify(1/(1+sqrt(2)))
-1 + sqrt(2)


コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村