{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "807b592c", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from smpl import plot\n", "from smpl import functions as fff\n", "import scipy" ] }, { "cell_type": "code", "execution_count": null, "id": "a8bcbe1c", "metadata": {}, "outputs": [], "source": [ "\n", "from scipy.misc import derivative\n", "\n", "def trim_domain(f, \n", " fmin = np.finfo(np.float32).min/2,\n", " fmax = np.finfo(np.float32).max/2,\n", " steps=100000,\n", " min_ch=0.001\n", " ):\n", " test = np.linspace(fmin,fmax,steps)\n", " dr = derivative(f,test,dx=1e-06)\n", " m1 = np.abs(dr)>min_ch\n", " bmin=np.argmax(m1)\n", " m2=(np.abs(dr)>min_ch)[::-1]\n", " tbmax=np.argmax(m2)\n", " xmin = test[bmin]\n", " xmax=test[::-1][tbmax]\n", " if bmin == 0 and tbmax ==0 and not m1[0] and not m2[0]:\n", " # trisect\n", " tmin = xmin\n", " tmax = xmax\n", " t1a,t1b = trim_domain(f,tmin+ (tmax-tmin)/3,tmax -(tmax-tmin)/3,min_ch=min_ch)\n", " if np.isclose(t1a,t1b):\n", " t2a,t2b = trim_domain(f,tmin + (tmax-tmin)/3,tmax,min_ch=min_ch)\n", " if np.isclose(t2a,t2b):\n", " t3a,t3b = trim_domain(f,tmin ,tmax- (tmax-tmin)/3,min_ch=min_ch)\n", " if np.isclose(t3a,t3b):\n", " return 0.,0. \n", " else:\n", " return t3a,t3b \n", " else:\n", " return t2a,t2b\n", " else:\n", " return t1a,t1b\n", " return xmin,xmax\n", " \n", "def get_domain(f,\n", " fmin = np.finfo(np.float32).min/2,\n", " fmax = np.finfo(np.float32).max/2,\n", " steps=100000,\n", "):\n", " \"\"\"\n", " Return the domain of the function ``f``.\n", " \"\"\"\n", " \n", " test = np.linspace(fmin,fmax,steps)\n", " \n", " r = f(test)\n", " mask = np.isfinite(r) \n", " tr = test[mask]\n", " if len(tr)>0:\n", " tmin = np.amin(tr)\n", " tmax = np.amax(tr)\n", " test_r = np.linspace(tmin,tmax,steps)\n", " if np.equal(tr.shape , test_r.shape) and np.allclose(test_r,tr):\n", " return tmin,tmax\n", " \n", " # trisect\n", " tmin = fmin\n", " tmax = fmax\n", " t1a,t1b = get_domain(f,tmin+ (tmax-tmin)/3,tmax -(tmax-tmin)/3)\n", " if np.isclose(t1a,t1b):\n", " t2a,t2b = get_domain(f,tmin + (tmax-tmin)/3,tmax)\n", " if np.isclose(t2a,t2b):\n", " t3a,t3b = get_domain(f,tmin ,tmax- (tmax-tmin)/3)\n", " if np.isclose(t3a,t3b):\n", " return 0.,0. \n", " else:\n", " return t3a,t3b \n", " else:\n", " return t2a,t2b\n", " else:\n", " return t1a,t1b" ] }, { "cell_type": "code", "execution_count": null, "id": "8ec7a5d7", "metadata": {}, "outputs": [], "source": [ "def is_monotone(f,tmin=None,tmax=None,):\n", " \"\"\"\n", " Test if function ``f`` is monotone.\n", "\n", " Parameters\n", " ----------\n", " f : function\n", " Function to be tested.\n", " test : array_like\n", " Test points.\n", "\n", " Returns\n", " -------\n", " bool\n", " True if function is monotone.\n", " \"\"\"\n", " if tmax is None and tmin is None:\n", " tmin,tmax = get_domain(f)\n", " test = np.linspace(tmin,tmax,1000)\n", " return np.all(f(test[1:])>=f(test[:-1]))" ] }, { "cell_type": "code", "execution_count": null, "id": "2aaad85d", "metadata": {}, "outputs": [], "source": [ "def get_interesting_region(f,min_ch = 1e-4):\n", " \"\"\"\n", " Return interesting xmin and xmax of function ``f``.\n", " \"\"\"\n", " omin_x,omax_x = get_domain(f)\n", " if is_monotone(f,omin_x,omax_x):\n", " min_x,max_x=trim_domain(f,omin_x,omax_x,min_ch = min_ch)\n", " #min_x,max_x=omin_x,omax_x\n", " else:\n", " tmax_x= scipy.optimize.minimize(lambda x: -f(x),0.,method='Nelder-Mead',bounds=[(omin_x,omax_x)])\n", " tmin_x= scipy.optimize.minimize(f,0.,method='Nelder-Mead',bounds=[(omin_x,omax_x)])\n", " if tmax_x.success:\n", " tmax_x = tmax_x.x[0]\n", " else:\n", " tmax_x =0.\n", " if tmin_x.success:\n", " tmin_x = tmin_x.x[0]\n", " else:\n", " tmin_x =0.\n", " \n", " if abs(tmax_x) > np.finfo(np.float32).max/10:\n", " tmax_x = 0.\n", " if abs(tmin_x) > np.finfo(np.float32).max/10:\n", " tmin_x = 0.\n", " x_min = min(tmax_x,tmin_x)\n", " x_max = max(tmax_x,tmin_x)\n", " min_x = ((x_max+x_min)/2-(x_max-x_min))\n", " max_x = ((x_max+x_min)/2+(x_max-x_min))\n", " if np.isclose(min_x,max_x):\n", " min_x,max_x=trim_domain(f,omin_x,omax_x,min_ch = min_ch)\n", " \n", " \n", " return min_x,max_x" ] }, { "cell_type": "code", "execution_count": null, "id": "f10d3b27", "metadata": {}, "outputs": [], "source": [ "f = np.exp\n", "print(np.finfo(np.float64).min,np.finfo(np.float64).max)\n", "print(get_domain(f))\n", "print(np.isclose(*get_domain(f)))\n", "print(is_monotone(f))" ] }, { "cell_type": "code", "execution_count": null, "id": "febd4179", "metadata": {}, "outputs": [], "source": [ "def ff(x):\n", " return np.exp(x)\n", "xmin,xmax =get_interesting_region(ff)\n", "plot.function(ff,xmin=xmin,xmax = xmax,logy=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "1d361b19", "metadata": {}, "outputs": [], "source": [ "def ff(x):\n", " return np.sin(x)\n", "xmin,xmax =get_interesting_region(ff)\n", "plot.function(ff,xmin=xmin,xmax = xmax,logy=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "07894d8b", "metadata": {}, "outputs": [], "source": [ "def ff(x):\n", " return x**2\n", "xmin,xmax =get_interesting_region(ff)\n", "plot.function(ff,xmin=xmin,xmax = xmax,logy=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "77db85a1", "metadata": {}, "outputs": [], "source": [ "def ff(x):\n", " return x\n", "xmin,xmax =get_interesting_region(ff)\n", "plot.function(ff,xmin=xmin,xmax = xmax,logy=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "09d1b27a", "metadata": {}, "outputs": [], "source": [ "def ff(x):\n", " return np.cos(x)\n", "xmin,xmax =get_interesting_region(ff)\n", "plot.function(ff,xmin=xmin,xmax = xmax,logy=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "a65bf46d", "metadata": {}, "outputs": [], "source": [ "def ff(x):\n", " return np.arctan(x)\n", "xmin,xmax =get_interesting_region(ff)\n", "plot.function(ff,xmin=xmin,xmax = xmax,logy=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "ddb43496", "metadata": {}, "outputs": [], "source": [ "def ff(x):\n", " return np.tan(x)\n", "xmin,xmax =get_interesting_region(ff)\n", "plot.function(ff,xmin=xmin,xmax = xmax,logy=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "a7b66cf0", "metadata": {}, "outputs": [], "source": [ "def ff(x):\n", " \"\"\"Lorentz\"\"\"\n", " return fff.lorentz(x,0,5,3,0)\n", "xmin,xmax =get_interesting_region(ff)\n", "plot.function(ff,xmin=xmin,xmax = xmax,logy=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "31a2e2c3", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "0efdaa8c", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "fa00bbda", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "db09fa71", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "61b7b6e2", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "d65601b8", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "1a0afbbd", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "db6178ca", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "065efbc0", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "d2c1c07d", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "db73bcee", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "c9255b07", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "796cd4e9", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "1374cfda", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "1c6daa4c", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "5bbfdba9", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "71feed85", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "357738ec", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.13" } }, "nbformat": 4, "nbformat_minor": 5 }