# -*- coding: UTF-8 -*-
"""
:filename: sppas.src.calculus.stats.linear_fct.py
:author: Brigitte Bigi
:contact: develop@sppas.org
:summary: Linear functions
.. _This file is part of SPPAS: http://www.sppas.org/
..
-------------------------------------------------------------------------
___ __ __ __ ___
/ | \ | \ | \ / the automatic
\__ |__/ |__/ |___| \__ annotation and
\ | | | | \ analysis
___/ | | | | ___/ of speech
Copyright (C) 2011-2021 Brigitte Bigi
Laboratoire Parole et Langage, Aix-en-Provence, France
Use of this software is governed by the GNU Public License, version 3.
SPPAS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
SPPAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SPPAS. If not, see <http://www.gnu.org/licenses/>.
This banner notice must not be removed.
-------------------------------------------------------------------------
A linear function from the real numbers to the real numbers is a function
whose graph - in Cartesian coordinates with uniform scales, is a line in
the plane.
The equation y = ax + b is referred to as the slope-intercept form of a
linear equation.
"""
import math
# ---------------------------------------------------------------------------
[docs]def slope(p1, p2):
"""Estimate the slope between 2 points.
:param p1: (tuple) first point as (x1, y1)
:param p2: (tuple) second point as (x2, y2)
:returns: float value
"""
# test types
try:
x1 = float(p1[0])
y1 = float(p1[1])
x2 = float(p2[0])
y2 = float(p2[1])
except:
raise
# test values (p1 and p2 must be different)
if x1 == x2:
return 0.
x_diff = x2 - x1
y_diff = y2 - y1
return y_diff / x_diff
# ---------------------------------------------------------------------------
[docs]def intercept(p1, p2):
"""Estimate the intercept between 2 points.
:param p1: (tuple) first point as (x1, y1)
:param p2: (tuple) second point as (x2, y2)
:returns: float value
"""
a = slope(p1, p2)
b = float(p2[1]) - (a * float(p2[0]))
return b
# ---------------------------------------------------------------------------
[docs]def slope_intercept(p1, p2):
"""Return the slope and the intercept.
:param p1: (tuple) first point as (x1, y1)
:param p2: (tuple) second point as (x2, y2)
:returns: tuple(slope,intercept)
"""
a = slope(p1, p2)
b = float(p2[1]) - (a * float(p2[0]))
return a, b
# ---------------------------------------------------------------------------
[docs]def linear_fct(x, a, b):
"""Return f(x) of the linear function f(x) = ax + b.
:param x: (float) X-coord
:param a: (float) slope
:param b: (float) intercept
"""
x = float(x)
a = float(a)
b = float(b)
return (a * x) + b
# ---------------------------------------------------------------------------
[docs]def ylinear_fct(y, a, b):
"""Return x of the linear function y = ax + b.
:param y: (float) Y-coord
:param a: (float) slope
:param b: (float) intercept
"""
y = float(y)
a = float(a)
b = float(b)
return (y - b) / a
# ---------------------------------------------------------------------------
[docs]def linear_values(delta, p1, p2, rounded=6):
"""Estimate the values between 2 points, step-by-step.
Two different points p1=(x1,y1) and p2=(x2,y2) determine a line. It is
enough to substitute two different values for 'x' in the linear function
and determine 'y' for each of these values.
a = y2 − y1 / x2 − x1 <= slope
b = y1 - a * x1 <= intercept
Values for p1 and p2 are added into the result.
:param delta: (float) Step range between values.
:param p1: (tuple) first point as (x1, y1)
:param p2: (tuple) second point as (x2, y2)
:param rounded: (int) round floats
:returns: list of float values, i.e. all the y, including the ones of p1 and p2
:raises: MemoryError could be raised if too many values have to be \
returned.
"""
delta = float(delta)
# linear function parameters
a, b = slope_intercept(p1, p2)
x1 = float(p1[0])
x2 = float(p2[0])
d = round((x2-x1), rounded) # hack
# number of values to add in the array
steps = int(math.ceil(d / delta)) + 1
array = [0.] * steps
# values to add in the array, from p1 to previous-p2
for step in range(1, steps):
x = (step*delta) + x1
y = linear_fct(x, a, b)
array[step] = round(y, rounded)
# first and last values (i.e. p1 and p2)
y = linear_fct(x1, a, b)
array[0] = round(y, rounded)
y = linear_fct(x2, a, b)
array[-1] = round(y, rounded)
return array