Effectively solve an overdetermined nonlinear equation system using fitted data in python - python

I think it’s the easiest way to describe my problem with a small example.
I have this data which is my input data. I have 3 LEDs and each LED is represented by 4 color-parts (value 1 to 4 in each array). If I increase the intensity of the LEDs (in this example from 10% to 30%) the color-parts change in different ways.
LED1_10 = np.array([1.5, 1, 0.5, 0.5])
LED1_20 = np.array([2.5, 1.75, 1.2, 1.2])
LED1_30 = np.array([3, 2.3, 1.7, 1.7])
LED2_10 = np.array([0.2, 0.8, 0.4, 0.4])
LED2_20 = np.array([0.6, 1.6, 0.5, 0.5])
LED2_30 = np.array([1.0, 2.0, 0.55, 0.55])
LED3_10 = np.array([1, 0.1, 0.4, 0.4])
LED3_20 = np.array([2.5, 0.8, 0.9, 0.9])
LED3_30 = np.array([3.25, 1, 1.3, 1.3])
The column elements of the arrays belong together. So if I bring LED1 from 10% to 30% the value in column 1 rises from 1.5 to 2.5 and then to 3. I want to find a polynomial for the rise of each of the LED color-parts, so I rearrange the data and use a polynomial fit to get the equations which describe the way the values are rising for each LED.
### Rearrange the values
LED1 = np.stack((LED1_10, LED1_20, LED1_30)).T
LED2 = np.stack((LED2_10, LED2_20, LED2_30)).T
LED3 = np.stack((LED3_10, LED3_20, LED3_30)).T
### Create x-vectro
x = np.array([10,20,30])
### Polynomal fits
Fit_LED1 = []
for i in range(len(LED1)):
z = np.polyfit(x, LED1[i], 2)
Fit_LED1.append(z)
Fit_LED2 = []
for i in range(len(LED2)):
z = np.polyfit(x, LED2[i], 2)
Fit_LED2.append(z)
Fit_LED3 = []
for i in range(len(LED3)):
z = np.polyfit(x, LED3[i], 2)
Fit_LED3.append(z)
Now I want to generate light of a specific color mixing together the light of each of the 3 different LEDs. Therefor I need to find out which intensity I need to use from each of the LEDs to get the best possible result. Color-parts 1-4 are represented by the solution vector: b = [7, 8, 2, 5] I do this solving the overdetermined nonlinear equation system like this:
def f(x):
x1, x2, x3 = x
return np.asarray(((-2.50000000e-03*x1**2 + 1.75000000e-01*x1 + -5.91091254e-15) + (-2.03207837e-18*x2**2 + 4.00000000e-02*x2 + -2.00000000e-01) + (-0.00375*x3**2 + 0.2625*x3 + -1.25),
(-0.001*x1**2 + 0.105*x1 + 0.05) + (-0.002*x2**2 + 0.14*x2 + -0.4) + (-0.0025*x3**2 + 0.145*x3 + -1.1),
(-0.001*x1**2 + 0.1*x1 + -0.4 ) + (-0.00025*x2**2 + 0.0175*x2 + 0.25) + (-0.0005*x3**2 + 0.065*x3 + -0.2),
(-0.001*x1**2 + 0.1*x1 + -0.4 ) + (-0.00025*x2**2 + 0.0175*x2 + 0.25) + (-0.0005*x3**2 + 0.065*x3 + -0.2)))
def system(x,b):
return (f(x)-b)
b = [7, 8, 2, 5]
x = scipy.optimize.leastsq(system, np.asarray((1,1,1)), args=b)[0]
I used the polynomials I got from the fit for each LED and added them to each other to get a equation for each of the four color parts. This would give the same result and maybe is a bit easier to read:
def g(x):
x1, x2, x3 = x
return np.asarray(((Fit_LED1[0][0]*x1**2 + Fit_LED1[0][1]*x1 + Fit_LED1[0][2]) + (Fit_LED2[0][0]*x1**2 + Fit_LED2[0][1]*x1 + Fit_LED2[0][2]) + (Fit_LED3[0][0]*x1**2 + Fit_LED3[0][1]*x1 + Fit_LED3[0][2]),
(Fit_LED1[1][0]*x1**2 + Fit_LED1[1][1]*x1 + Fit_LED1[1][2]) + (Fit_LED2[1][0]*x1**2 + Fit_LED2[1][1]*x1 + Fit_LED2[1][2]) + (Fit_LED3[1][0]*x1**2 + Fit_LED3[1][1]*x1 + Fit_LED3[1][2]),
(Fit_LED1[2][0]*x1**2 + Fit_LED1[2][1]*x1 + Fit_LED1[2][2]) + (Fit_LED2[2][0]*x1**2 + Fit_LED2[2][1]*x1 + Fit_LED2[2][2]) + (Fit_LED3[2][0]*x1**2 + Fit_LED3[2][1]*x1 + Fit_LED3[2][2]),
(Fit_LED1[3][0]*x1**2 + Fit_LED1[3][1]*x1 + Fit_LED1[3][2]) + (Fit_LED2[3][0]*x1**2 + Fit_LED2[3][1]*x1 + Fit_LED2[3][2]) + (Fit_LED3[3][0]*x1**2 + Fit_LED3[3][1]*x1 + Fit_LED3[3][2])))
def system(x,b):
return (f(x)-b)
b = [5, 8, 4, 12]
x = scipy.optimize.leastsq(system, np.asarray((1,1,1)), args=b)[0]
Now my problem is that I need to type each of the functions separately which is a lot of work, especially because my real-world application consists of 40 LEDs and more than 1000 color-parts for each of the LEDs. Is there an easier and more efficient way to define the equations for the equations system rather than typing each of the separately like I did here?
def g(x):
x1, x2, x3 = x
return np.asarray(((Fit_LED1[0][0]*x1**2 + Fit_LED1[0][1]*x1 + Fit_LED1[0][2]) + (Fit_LED2[0][0]*x1**2 + Fit_LED2[0][1]*x1 + Fit_LED2[0][2]) + (Fit_LED3[0][0]*x1**2 + Fit_LED3[0][1]*x1 + Fit_LED3[0][2]),
(Fit_LED1[1][0]*x1**2 + Fit_LED1[1][1]*x1 + Fit_LED1[1][2]) + (Fit_LED2[1][0]*x1**2 + Fit_LED2[1][1]*x1 + Fit_LED2[1][2]) + (Fit_LED3[1][0]*x1**2 + Fit_LED3[1][1]*x1 + Fit_LED3[1][2]),
(Fit_LED1[2][0]*x1**2 + Fit_LED1[2][1]*x1 + Fit_LED1[2][2]) + (Fit_LED2[2][0]*x1**2 + Fit_LED2[2][1]*x1 + Fit_LED2[2][2]) + (Fit_LED3[2][0]*x1**2 + Fit_LED3[2][1]*x1 + Fit_LED3[2][2]),
(Fit_LED1[3][0]*x1**2 + Fit_LED1[3][1]*x1 + Fit_LED1[3][2]) + (Fit_LED2[3][0]*x1**2 + Fit_LED2[3][1]*x1 + Fit_LED2[3][2]) + (Fit_LED3[3][0]*x1**2 + Fit_LED3[3][1]*x1 + Fit_LED3[3][2])))
I hope I was able to make my problem clear and would be very thankful if anyone could help me solving this task.
Thank you very much in advance :)

There is a pattern in your equations which you can vectorise. First of all, gather all the LED fits in a 3D array.
fits = np.array([Fit_LED1, Fit_LED2, Fit_LED3])
And then define g(x) as
def g(x):
X = np.array([x**2, x, np.ones_like(x)]).T
return np.sum(fits * X[:,None], axis=(0, 2))
You can also confirm the result is correct with np.isclose(f(x), g(x)).
Of course you should do the same to LED1, LED2, etc so you don't have to hardcode Fit_LED1, etc. Just put everything in a 3d array and loop for each LED index.
LEDs = np.array([LED1, LED2, LED3])
fits = [
[np.polyfit(np.array([10, 20, 30]), LEDs[i,j], 2) for j in range(LEDs.shape[1])]
for i in range(LEDs.shape[0])
]
fits = np.array(fits)

Related

Why do I keep getting ValueError: solve: Input operand 1 has a mismatch in its core dimension 0?

I am attempting to write a code for Newton's Method for nonlinear systems in Python. My g function is a 5x1 matrix and the jacobian (derivative matrix) of this is a 5x5 matrix. The vector for the initial y values (y0) is also a 5x1. i keep on getting the error
ValueError: solve: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (m,m),(m,n)->(m,n) (size 1 is different from 5)
I have tried solving my problem manually and I get my answer however when I run my code. I suspect that the error is something silly that I am simply overlooking. But I just can't for the life of me figure out what the issue is. Below is my code:
def newton_prob(y0, g, jac, tol):
max_iteration = 100
tol = 1e-6
y_value = y0
for k in range(max_iteration):
J = np.array(jac(y_value))
G = np.array(g(y_value))
diff = np.linalg.solve(J, -G)
y_value = y_value + diff
stopcrit = np.linalg.norm(y_value - y0, 2) / np.linalg.norm(y0, 2)
if stopcrit < tol:
print('Convergence, nre iter:' , k)
break
else:
return y_value
#Test
y0 = np.array([[17],
[17],
[17],
[17],
[17]])
g = lambda y: np.array([[-9*y[1] + 18*y[0] - 9*(17) - (3/16)*y[0]*y[1] + (3/16)*y[0]*(17) + (124/27)],
[-9*y[2] + 18*y[1] -9*y[0] -(3/16)*y[1]*y[2] + (3/16)*y[0]*y[1] +(557/108)],
[-9*y[3] + 18*y[2] -9*y[1] + (3/16)*y[1]*y[2] - (3/16)*y[2]*y[3] + 6],
[-9*y[4] + 9*y[3] -9*y[2] - (3/16)*y[3]*y[4] + (3/16)*y[2]*y[3] + (775/108)],
[-9*(43/3) +18*y[4] -9*y[3] + (3/16)*y[3]*y[4] - (3/16)*y[4]*(43/3) + (236/27)]])
jac = lambda y: np.array([[18 -(3/16)*y[1] + (3/16)*(17), -9 -(3/16)*y[0], 0, 0, 0],
[-9 + (3/16)*y[1], 18 - (3/16)*y[2] + (3/16)*y[0], -9 - (3/16)*y[1], 0, 0],
[0, -9 + (3/16)*y[2], 18 + (3/16)*y[1] - (3/16)*y[3], -9 - (3/16)*y[2], 0],
[0, 0, -9 + (3/16)*y[3], 9 - (3/16)*y[3] + (3/16)*y[2], -9 - (3/16)*y[3]],
[0, 0, 0, -9 + (3/16)*y[4], 18 + (3/16)*y[3] - (3/16)*(43/3)]])
tol = 1e-6
print(newton_prob(y0, g, jac, tol))
Please help if possible
The dimensions of y0 and g seems to be wrong. Reduce them by one dimension:
y0 = np.array([17,
17,
17,
17,
17])
g = lambda y: np.array([-9*y[1] + 18*y[0] - 9*(17) - (3/16)*y[0]*y[1] + (3/16)*y[0]*(17) + (124/27),
-9*y[2] + 18*y[1] -9*y[0] -(3/16)*y[1]*y[2] + (3/16)*y[0]*y[1] +(557/108),
-9*y[3] + 18*y[2] -9*y[1] + (3/16)*y[1]*y[2] - (3/16)*y[2]*y[3] + 6,
-9*y[4] + 9*y[3] -9*y[2] - (3/16)*y[3]*y[4] + (3/16)*y[2]*y[3] + (775/108),
-9*(43/3) +18*y[4] -9*y[3] + (3/16)*y[3]*y[4] - (3/16)*y[4]*(43/3) + (236/27)])
Output:
[ 1.90727371e-01 -1.59772226e+01 -4.74196657e+01 -5.16165838e+03 4.86453399e+01]

fit hyperbola from data points

I have experimental data points (x1, x2, ..., xn), (y1, y2, ..., yn) of turbocharger pressure map and want to get trendline equation. In result of my research it's something like:
y = (ax^5 + bx^4 + cx^3 + dx^2 + ex + f)/(x+g) # my equation
Tell me please, are there any ready-made functions for this?
I tried using np.polyfit, but it works with usual polynoms and I must guess "g" in this way:
# y*(x-g) = ax^5 + bx^4 + cx^3 + dx^2 + ex + f
pc = np.polyfit(x, y*(x+g), 5)
y = (pc[0]*x**5 + pc[1]*x**4 + pc[2]*x**3 + pc[3]*x**2 + pc[4]*x + pc[5])/(x + g)
It would be nice if someone could help to get coefficiens of my equation.
Though this will lead to a slightly different minimization, you can linearize the equation as
x y = ax^5 + bx^4 + cx^3 + dx^2 + ex + f - g y
and solve by linear least-squares.

How to calculate sums of squares in Python?

First, is the formula TSS = ESS + RSS always correct? Even for an exponential model? If it is, I just do not understand where am I wrong.
I have 2 arrays of x and y values, where y depends on x.
x = np.array([1.5, 2.1, 2.4, 2.7, 3.2, 3.4, 3.6, 3.7, 4.0, 4.5, 5.1, 5.6])
y = np.array([0.6, 1.2, 1.3, 1.4, 1.45, 1.5, 1.6, 1.8, 1.9, 1.95, 2.1, 2.2])
I have a function that determines coefficients a and b and returns an equation of linear regression (or just a and b if needed)
def Linear(x, y, getAB = False):
AVG_X = np.average(x)
AVG_Y = np.average(y)
DISP_X = np.var(x)
DISP_Y = np.var(y)
STD_X = np.std(x)
STD_Y = np.std(y)
AVG_prod = np.average(x*y)
cov = AVG_prod - (AVG_X*AVG_Y)
b = cov/DISP_X
a = AVG_Y - b*AVG_X
if getAB:
return a, b
return lambda X: a + b*X
I have a function that determines coefficients a and b and returns an equation of EXPONENTIAL regression
def Exponential(x, y, getAB = False):
LOG_Y_array = [math.log(value) for value in y]
A, B = Linear(x, LOG_Y_array, getAB = True)
a = math.exp(A)
b = math.exp(B)
if getAB:
return a, b
return lambda X: a * (b**X)
I created the array of calculated y values based of exponential model
Exponential_Prediction = Exponential(x, y)
Exponential_Prediction_y = [Exponential_Prediction(value) for value in x]
And finally, that is how I calculate TSS, ESS and RSS
TSS = np.sum((y - np.average(y))**2)
ESS_Exp = np.sum((Exponential_Prediction_y - np.average(y))**2)
RSS_Exp = np.sum((y-Exponential_Prediction_y)**2)
That is all pretty clear, except the output of this
print(str(TSS) + " = " + str(ESS_Exp) + " + " + str(RSS_Exp))
is 2.18166666667 = 2.75523753042 + 0.432362713806
I do not understand how ESS could be more than TSS
You're missing a term that is zero when you're using linear regression, since you're not, you have to add it. In the link that Vince commented, you can see that TSS = ESS + RSS + 2*sum((y - yhat)*(yhat - ybar)).
You need to include that extra term in order for it to add up:
extra_term = 2 * np.sum((y - Exponential_Prediction_y) * (Exponential_Prediction_y - y.mean()))
print(str(TSS) + " = " + str(ESS_Exp) + " + " + str(RSS_Exp) + " + " + str(extra_term))

Solving an Equation System in SciPy

i am trying to fit an exponential curve through three given Points. But i get only very wrong results of fsolve or actual 0. I need this for my Bachelor Thesis so if anyone knows a better solution for the problem, it would be very kind to tell me this solution.
from numpy import *
from scipy.optimize import *
def myFunction(variables):
x1 = 1
y1 = 100
x2 = 5
y2 = 50
x3 = 10
y3 = 1
(a,k,b) = variables
y1 = a*exp(-x1*k)+b
y2 = a*exp(-x2*k)+b
y3 = a*exp(-x3*k)+b
#0 = a*k**2 * exp(-x1+k)
return ([a, k, b])
z = fsolve(myFunction,(1,0.1,5))
print(z)
this is my problem, i need to fit an e function through this 3 given points, and in addition the second derivation of the forumla should be 0
edit: 06.12.17
in some way i have now an improvement with a polynom, but does not really fit like it should.
The second Maximum should not be there.. :D
from numpy import *
from scipy.optimize import *
import matplotlib.pyplot as plt
def myFunction(z):
a = z[0]
b = z[1]
c = z[2]
d = z[3]
e = z[4]
f = z[5]
g = z[6]
x = [0, 10 ,15 ,20 ,50 ,100]
y = [10 ,90 ,100 ,90 ,50 ,10]
s = [0, 10, 1, 0, 0, 0]
F = empty((8))
F[0] = a*x[0]**6 + b*x[0]**5 + c*x[0]**4 + d*x[0]**3 + e*x[0]**2 + f*x[0]**1 + g - y[0]
F[1] = a*x[1]**6 + b*x[1]**5 + c*x[1]**4 + d*x[1]**3 + e*x[1]**2 + f*x[1]**1 + g - y[1]
F[2] = a*x[2]**6 + b*x[2]**5 + c*x[2]**4 + d*x[2]**3 + e*x[2]**2 + f*x[2]**1 + g - y[2]
F[3] = a*x[3]**6 + b*x[3]**5 + c*x[3]**4 + d*x[3]**3 + e*x[3]**2 + f*x[3]**1 + g - y[3]
F[4] = a*x[4]**6 + b*x[4]**5 + c*x[4]**4 + d*x[4]**3 + e*x[4]**2 + f*x[4]**1 + g - y[4]
F[5] = a*x[5]**6 + b*x[5]**5 + c*x[5]**4 + d*x[5]**3 + e*x[5]**2 + f*x[5]**1 + g - y[5]
F[6] = 6*a*x[3]**5 + 5*b*x[3]**4 + 4*c*x[3]**3 + 3*d*x[3]**2 + 2*e*x[3]**1 + f - s[3]
F[7] = 6*a*x[5]**5 + 5*b*x[5]**4 + 4*c*x[5]**3 + 3*d*x[5]**2 + 2*e*x[5]**1 + f - s[5]
return F
zGuess = array([1,1,1,1,1,1,1,1])
z = fsolve(myFunction,zGuess)
print(z)
x_axis = linspace(0,100,100)
y_axis = z[0]*x_axis**6 + z[1]*x_axis**5 + z[2]*x_axis**4 + z[3]*x_axis**3 + z[4]*x_axis**2 + z[5]*x_axis**1 + z[6]
plt.plot(x_axis, y_axis)
plt.show()
edit 07.12.17
the whole signal should look like the data of the second example. But the difficulty is in the part of the first example. My suggestion was to use 2 polynoms, but my prof would prefer an polynom x<20 and an e function x>20. The overlapping of both should also be very smooth.
Well fsolve find the roots of a function, does not really do a non-linear fit. I must admit I don't actually quite get what you want to achieve with your code. If you want to do a nonlinear fit (since you are talking about exponential functions here) you may want to check my notebook here https://github.com/michelucci/Regression-with-Python/blob/master/(Non)%20linear%20fit%20in%20Python.ipynb that I hope can point you in the right direction. It contains first a part on linear regression and then a non-linear tutorial.
You can check curve_fit() python function in the scipy.optimize library. That should help you with what you want to do.
Let me know if that helps you.
You may also want to check this link to better understand what a non-linear fit is https://en.wikipedia.org/wiki/Nonlinear_regression
Best, Umberto

How to calculate weight to minimize variance?

given several vectors:
x1 = [3 4 6]
x2 = [2 8 1]
x3 = [5 5 4]
x4 = [6 2 1]
I wanna find weight w1, w2, w3 to each item, and get the weighted sum of each vector: yi = w1*i1 + w2*i2 + w3*i3. for example, y1 = 3*w1 + 4*w2 + 6*w3
to make the variance of these values(y1, y2, y3, y4) to be minimized.
notice: w1, w2, w3 should > 0, and w1 + w2 + w3 = 1
I don't know what kind of problems it should be... and how to solve it in python or matlab?
You can start with building a loss function stating the variance and the constraints on w's. The mean is m = (1/4)*(y1 + y2 + y3 + y4). The variance is then (1/4)*((y1-m)^2 + (y2-m)^2 + (y3-m)^2 + (y4-m)^2) and the constraint is a*(w1+w2+w3 - 1) where a is the Lagrange multiplier. The problem looks like to me a convex optimisation with convex constraints since the loss function is quadratic with respect to target variables (w1,w2,w3) and the constraints are linear. You can look for projected gradient descent algorithms which respect to the constraints provided. Take a look to here http://www.ifp.illinois.edu/~angelia/L5_exist_optimality.pdf There are no straightforward analytic solutions to such kind of problems in general.
w = [5, 6, 7]
x1 = [3, 4, 6]
x2 = [2, 8, 1]
x3 = [5, 5, 4]
y1, y2, y3 = 0, 0, 0
for index, i in enumerate(w):
y1 = y1 + i * x1[index]
y2 = y2 + i * x2[index]
y3 = y3 + i * x3[index]
print(min(y1, y2, y3))
I think I maybe get the purpose of your problem.But if you want to find the smallest value, I hope this can help you.
I just make the values fixed, you can make it to be the def when you see this is one way to solve your question.
I don't know much about optimization problem, but I get the idea of gradient descent so I tried to reduce the weight between the max score and min score, my script is below:
# coding: utf-8
import numpy as np
#7.72
#7.6
#8.26
def get_max(alist):
max_score = max(alist)
idx = alist.index(max_score)
return max_score, idx
def get_min(alist):
max_score = min(alist)
idx = alist.index(max_score)
return max_score, idx
def get_weighted(alist,aweight):
res = []
for i in range(0, len(alist)):
res.append(alist[i]*aweight[i])
return res
def get_sub(list1, list2):
res = []
for i in range(0, len(list1)):
res.append(list1[i] - list2[i])
return res
def grad_dec(w,dist, st = 0.001):
max_item, max_item_idx = get_max(dist)
min_item, min_item_idx = get_min(dist)
w[max_item_idx] = w[max_item_idx] - st
w[min_item_idx] = w[min_item_idx] + st
def cal_score(w, x):
score = []
print 'weight', w ,x
for i in range(0, len(x)):
score_i = 0
for j in range(0,5):
score_i = w[j]*x[i][j] + score_i
score.append(score_i)
# check variance is small enough
print 'score', score
return score
# cal_score(w,x)
if __name__ == "__main__":
init_w = [0.2, 0.2, 0.2, 0.2, 0.2, 0.2]
x = [[7.3, 10, 8.3, 8.8, 4.2], [6.8, 8.9, 8.4, 9.7, 4.2], [6.9, 9.9, 9.7, 8.1, 6.7]]
score = cal_score(init_w,x)
variance = np.var(score)
round = 0
for round in range(0, 100):
if variance < 0.012:
print 'ok'
break
max_score, idx = get_max(score)
min_score, idx2 = get_min(score)
weighted_1 = get_weighted(x[idx], init_w)
weighted_2 = get_weighted(x[idx2], init_w)
dist = get_sub(weighted_1, weighted_2)
# print max_score, idx, min_score, idx2, dist
grad_dec(init_w, dist)
score = cal_score(init_w, x)
variance = np.var(score)
print 'variance', variance
print score
In my practice it really can reduce the variance. I am very glad but I don't know whether my solution is solid in math.
My full solution can be viewed in PDF.
The trick is to put the vectors x_i as columns of a matrix X.
Then writing the problem becomes a Convex Problem with constrain of the solution to be on the Unit Simplex.
I solved it using Projected Sub Gradient Method.
I calculated the Gradient of the objective function and created a projection to the Unit Simplex.
Now all needed is to iterate them.
I validated my solution using CVX.
% StackOverflow 44984132
% How to calculate weight to minimize variance?
% Remarks:
% 1. sa
% TODO:
% 1. ds
% Release Notes
% - 1.0.000 08/07/2017
% * First release.
%% General Parameters
run('InitScript.m');
figureIdx = 0; %<! Continue from Question 1
figureCounterSpec = '%04d';
generateFigures = OFF;
%% Simulation Parameters
dimOrder = 3;
numSamples = 4;
mX = randi([1, 10], [dimOrder, numSamples]);
vE = ones([dimOrder, 1]);
%% Solve Using CVX
cvx_begin('quiet')
cvx_precision('best');
variable vW(numSamples)
minimize( (0.5 * sum_square_abs( mX * vW - (1 / numSamples) * (vE.' * mX * vW) * vE )) )
subject to
sum(vW) == 1;
vW >= 0;
cvx_end
disp([' ']);
disp(['CVX Solution - [ ', num2str(vW.'), ' ]']);
%% Solve Using Projected Sub Gradient
numIterations = 20000;
stepSize = 0.001;
simplexRadius = 1; %<! Unit Simplex Radius
stopThr = 1e-6;
hKernelFun = #(vW) ((mX * vW) - ((1 / numSamples) * ((vE.' * mX * vW) * vE)));
hObjFun = #(vW) 0.5 * sum(hKernelFun(vW) .^ 2);
hGradFun = #(vW) (mX.' * hKernelFun(vW)) - ((1 / numSamples) * vE.' * (hKernelFun(vW)) * mX.' * vE);
vW = rand([numSamples, 1]);
vW = vW(:) / sum(vW);
for ii = 1:numIterations
vGradW = hGradFun(vW);
vW = vW - (stepSize * vGradW);
% Projecting onto the Unit Simplex
% sum(vW) == 1, vW >= 0.
vW = ProjectSimplex(vW, simplexRadius, stopThr);
end
disp([' ']);
disp(['Projected Sub Gradient Solution - [ ', num2str(vW.'), ' ]']);
%% Restore Defaults
% set(0, 'DefaultFigureWindowStyle', 'normal');
% set(0, 'DefaultAxesLooseInset', defaultLoosInset);
You can see the full code in StackOverflow Q44984132 (PDF is available as well).

Categories

Resources