@@ -6,11 +6,12 @@ defmodule LearnKit.Regression.Polynomial do
66 defstruct factors: [ ] , results: [ ] , coefficients: [ ] , degree: 2
77
88 alias LearnKit.Regression.Polynomial
9+ use Polynomial.Calculations
910
1011 @ type factors :: [ number ]
1112 @ type results :: [ number ]
1213 @ type coefficients :: [ number ]
13- @ type degree :: number
14+ @ type degree :: integer
1415
1516 @ doc """
1617 Creates polynomial predictor with data_set
@@ -26,6 +27,12 @@ defmodule LearnKit.Regression.Polynomial do
2627 %LearnKit.Regression.Polynomial{factors: [1, 2, 3, 4], results: [3, 6, 10, 15], coefficients: [], degree: 2}
2728
2829 """
30+ @ spec new ( factors , results ) :: % Polynomial {
31+ factors: factors ,
32+ results: results ,
33+ coefficients: [ ] ,
34+ degree: 2
35+ }
2936 def new ( factors , results ) when is_list ( factors ) and is_list ( results ) do
3037 % Polynomial { factors: factors , results: results }
3138 end
@@ -65,6 +72,12 @@ defmodule LearnKit.Regression.Polynomial do
6572 }
6673
6774 """
75+ @ spec fit ( % Polynomial { factors: factors , results: results } ) :: % Polynomial {
76+ factors: factors ,
77+ results: results ,
78+ coefficients: coefficients ,
79+ degree: degree
80+ }
6881 def fit ( % Polynomial { factors: factors , results: results } , options \\ [ ] ) do
6982 degree = options [ :degree ] || 2
7083 matrix = matrix ( factors , degree )
@@ -87,13 +100,10 @@ defmodule LearnKit.Regression.Polynomial do
87100 {:ok, [20.999999999999723, 27.999999999999574]}
88101
89102 """
103+ @ spec predict ( % Polynomial { coefficients: coefficients , degree: degree } , list ) :: { :ok , list }
90104 def predict ( polynomial = % Polynomial { coefficients: _ , degree: _ } , samples )
91105 when is_list ( samples ) do
92- { :ok ,
93- Enum . map ( samples , fn sample ->
94- { :ok , prediction } = predict ( polynomial , sample )
95- prediction
96- end ) }
106+ { :ok , do_predict ( polynomial , samples ) }
97107 end
98108
99109 @ doc """
@@ -110,63 +120,9 @@ defmodule LearnKit.Regression.Polynomial do
110120 {:ok, 20.999999999999723}
111121
112122 """
123+ @ spec predict ( % Polynomial { coefficients: coefficients , degree: degree } , number ) :: { :ok , number }
113124 def predict ( % Polynomial { coefficients: coefficients , degree: degree } , sample ) do
114125 ordered_coefficients = coefficients |> Enum . reverse ( )
115126 { :ok , substitute_coefficients ( ordered_coefficients , sample , degree , 0.0 ) }
116127 end
117-
118- defp matrix_line ( 1 , factors , degree ) do
119- power_ofs = Enum . to_list ( 1 .. degree )
120-
121- [ Enum . count ( factors ) ] ++
122- Enum . map ( power_ofs , fn factor ->
123- sum_x_with_k ( factors , factor , 0.0 )
124- end )
125- end
126-
127- defp matrix_line ( line , factors , degree ) do
128- line_factor = line - 1
129- power_ofs = Enum . to_list ( line_factor .. ( degree + line_factor ) )
130-
131- Enum . map ( power_ofs , fn factor ->
132- sum_x_with_k ( factors , factor , 0.0 )
133- end )
134- end
135-
136- defp matrix ( factors , degree ) do
137- lines = Enum . to_list ( 1 .. ( degree + 1 ) )
138-
139- Enum . map ( lines , fn line ->
140- matrix_line ( line , factors , degree )
141- end )
142- end
143-
144- defp substitute_coefficients ( [ ] , _ , _ , sum ) , do: sum
145-
146- defp substitute_coefficients ( [ coefficient | tail ] , x , k , sum ) do
147- sum = sum + :math . pow ( x , k ) * coefficient
148- substitute_coefficients ( tail , x , k - 1 , sum )
149- end
150-
151- defp sum_x_with_k ( [ x | tail ] , k , sum ) do
152- sum = sum + :math . pow ( x , k )
153- sum_x_with_k ( tail , k , sum )
154- end
155-
156- defp sum_x_with_k ( [ ] , _ , sum ) , do: sum
157-
158- defp sum_x_y_with_k ( [ ] , [ ] , _degree , sum ) , do: [ sum ]
159-
160- defp sum_x_y_with_k ( [ x | xtail ] , [ y | ytail ] , degree , sum ) do
161- exponent = degree - 1
162- sum = sum + :math . pow ( x , exponent ) * y
163- sum_x_y_with_k ( xtail , ytail , degree , sum )
164- end
165-
166- def x_y_matrix ( _ , _ , 0 , matrix ) , do: matrix |> Enum . reverse ( )
167-
168- def x_y_matrix ( xs , ys , degree , matrix ) do
169- matrix = matrix ++ [ sum_x_y_with_k ( xs , ys , degree , 0.0 ) ]
170- x_y_matrix ( xs , ys , degree - 1 , matrix )
171- end
172128end
0 commit comments