Inequality constrained convex optimization in Matlab - function

I want to solve the following problem:
minimize E[T]
subject to λi * pi - μi <= 0; for all i, i=1,...,n
(λ0 + sum(λi*(1-pi))) - μ0 <=0;
pi-1 <=0; for all i, i=1,...,n
pi => 0; for all i, i=1,...,n
where E(T) = (λ0 + sum(λi*(1-pi)) / ( ( λ0 + sum(λi) ) * μ0 -(λ0 + sum(λi*(1-pi) ) )) + sum((pi * λi) / ((λ0 + sum(λi)) * (μi - pi * λi)) )
where all sum goes from 1 to n
That's what we know about the parameters: n = 2, λ0 = 0, μ0 = 1, λ1 = free parameter, λ2 = 2, μ1 = μ2 = 2,
This problem can be handled as an inequality constrained minimization
problem.
I know that λ1 goes from 0 to 3 and what i want to get are p1 and p2. p1 and p2 are between 0 and 1.
And how can i choose the starting points? Or is this problem can be solved in Matlab?
I tried to to use fmincon with interior point algorithm in Matlab. But i don't really know how a linearly increasing parameter can be in nonlinear constraints.
If you can tell me suggestions or other functions that can handle this problem properly i would be pleased.

Related

How can gauss newton method implemented using armijo line search in python?

We define the sigmoidal function
σ(t) = 1 / (1+e−t)
It has the derivative σ′(t) = σ(t)(1 − σ(t)). The module gauss_newton contains a function generate_data(gamma=0) which generates a data set (ti , αi ) where ti ∈ R and αi ∈ R with
αi = σ(6ti + 1) + εiγ.
for i = 1, . . . , 10. The values εi ∼ N (0, 1) are independently normally distributed and the real value γ ∈ R controls the influence of εi.
(i) Solve the problem min (1/2(∥F(x)∥^2),
with Fi(x) = σ(x1ti + x2) − αi for i = 1,...,10 and γ = 0 using the Gauss Newton algorithm . Iterate until the size of the search direction is sufficiently small, i.e. until ∥∆xk ∥ < δ for some tolerance δ > 0.

Normalization of histogram in Octave by hist(y,x,norm)?

I was trying to normalize the histogram of uniformly distributed random numbers in the interval [0,10]. In octave documentation I came across the function as hist(y, x, norm) which I applied and got the histogram normalized in the interval. The code that I used is
m=input('Number of random numbers required = ')
v=10*rand(1,m)
hist(v,10,1,"facecolor", "b", "edgecolor", "w",'linewidth',1.5);
title(['Normalized histogram for ' num2str(m) ' uniformly distributed random numbers'])
set(gca,'fontsize',30)
but as I changed the bin number to 50 then for getting the normalized histogram I had to change the third argument of hist() to 5.
Here is the code
m=input('Number of random numbers required = ')
v=10*rand(1,m)
hist(v,50,5,"facecolor", "b", "edgecolor", "w",'linewidth',1.5);
title(['Normalized histogram for ' num2str(m) ' uniformly distributed random numbers'])
set(gca,'fontsize',30)
then only it produced a normalized histogram as the previous one. What's actually happening here? Why I need to change the norm argument to 5 when I changed the bin number to 50?
When I tried to normalize the gaussian distribution using same method I got it wrong ?( I had to do it write all the algorithm to get the correct answer) so I would like to know how the norm argument works ?
here is the code that i tried for gaussian distribution which yielded the wrong result
m=input('Number of random numbers required = ');
v=randn(1,m)
[f,x]=hist(v,50);
hold on;
g = 1 / sqrt(2 * pi) * exp(-0.5 * x .^ 2);
plot(x, g, 'r','linewidth',1.5);
hist(v,50,5,"facecolor", "b", "edgecolor", "w",'linewidth',1.5);
title(['Normalized histogram for ' num2str(m) ' gaussian distributed random numbers'])
set(gca,'fontsize',30)
The reason is because you are trying to compare a frequency histogram with a frequency DENSITY function. Which means you have not taken the effect of the bin width into account.
In other words, if we consider each value in v, which represents histogram height, to be the product of the bin width w and a 'density' value h such that v = h * w at each element, then your normalisation says that sum(v) = 1, and therefore sum(h * w) = w * sum(h) = 1.
Therefore in order to obtain a valid 'density' function from your current values, you need to divide your current values in v by the (constant) bin width w, to obtain the density value h.
Compare with this code:
m = 5000;
v = randn( m, 1 );
g = 1 / sqrt(2 * pi) * exp( -0.5 * x .^ 2 );
[nn,xx] = hist( v, 50, 1, 'facecolor', 'b', 'edgecolor', 'w', 'linewidth', 1.5);
nn = nn / diff(xx)(1);
bar( xx, nn, 0.5, 'facecolor', [0, 0.5, 1], 'edgecolor', [0, 0.25, 0.5] );
hold on;
plot(x, g, 'r','linewidth', 3);
title({ ['Normalized histogram for ', num2str(m)], ' gaussian distributed random numbers'})
set(gca,'fontsize',20)
hold off

Numeric function

As a sub-routine for a script I'm writing, I need a numerical function that behaves in a specific pattern. It takes a single input and provides a single output, such that between 0 and L inclusive, it is the identity function, but then between L+1 and L*2+1, it returns L to 0 respectively, and then from L*2+2 to L*3+2 it returns 0 to L respectively, and so on. I want to do this without any if statements, only using absolute value and modulus. Can anyone give me pseudocode for this function?
Given input I, limit L and result R, and using only basic arithmetic and absolute values, this gives the desired result.
R = ABS(L * ((I - (I % (L + 1))) / (L + 1) % 2) + (L + 1) * (I - (I % (L + 1))) / (L + 1) - I)
This can obviously be hugely simplified by declaring some intermediate variables, and using additional methods, e.g. floor to simulate integer division. Here's a Javascript example:
var factor = Math.floor(input / (limit + 1));
var flag = factor % 2;
var result = Math.abs(limit * flag + (limit + 1) * factor - input)

ORDER BY Color with Hex Code as a criterio in MySQL

I have a table that contains color options for a product. The color options include a hex color code, which is used to generate the UI (HTML).
I would like to sort the rows so that the colors in the UI look like a rainbow, instead of the current order that sorts based off of the Name of the color (not very useful).
Here is what my query looks like. I get the R G B decimal values from the hex code. I just don't know how to order it.
I've looked into color difference algorithms. They seem more useful to compare 2 colors' similarity, not sort.
I'm using MySQL:
select a.*, (a.c_r + a.c_g + a.c_b) color_sum
from (
select co.customization_option_id,
co.designer_image_url,
concat(co.name, " (",cog.name, ")") name,
co.customization_option_group_id gr,
designer_hex_color,
conv(substr(designer_hex_color, 1, 2), 16, 10) c_r,
conv(substr(designer_hex_color, 3, 2), 16, 10) c_g,
conv(substr(designer_hex_color, 5, 2), 16, 10) c_b
from customization_options co
left join customization_option_groups cog
on cog.id = co.customization_option_group_id
where co.customization_id = 155
and co.customization_option_group_id
in (1,2,3,4)) a
order by ????
You want to sort hex codes by wavelength, this roughly maps onto the hue-value. Given a hexcode as a six character string: RRGGBB.
You just need to make a function that takes in a hexcode string and outputs the hue value, here's the formula from this Math.SO answer:
R' = R/255
G' = G/255
B' = B/255
Cmax = max(R', G', B')
Cmin = min(R', G', B')
Δ = Cmax - Cmin
I wanted to see if this would work, so I whipped up a sample program in Ruby, it samples 200 random colors uniformly from RGB-space, and sorts them, the output looks like a rainbow!
Here's the Ruby source:
require 'paint'
def hex_to_rgb(hex)
/(?<r>..)(?<g>..)(?<b>..)/ =~ hex
[r,g,b].map {|cs| cs.to_i(16) }
end
def rgb_to_hue(r,g,b)
# normalize r, g and b
r_ = r / 255.0
g_ = g / 255.0
b_ = b / 255.0
c_min = [r_,g_,b_].min
c_max = [r_,g_,b_].max
delta = (c_max - c_min).to_f
# compute hue
hue = 60 * ((g_ - b_)/delta % 6) if c_max == r_
hue = 60 * ((b_ - r_)/delta + 2) if c_max == g_
hue = 60 * ((r_ - g_)/delta + 4) if c_max == b_
return hue
end
# sample uniformly at random from RGB space
colors = 200.times.map { (0..255).to_a.sample(3).map { |i| i.to_s(16).rjust(2, '0')}.join }
# sort by hue
colors.sort_by { |color| rgb_to_hue(*hex_to_rgb(color)) }.each do |color|
puts Paint[color, color]
end
Note, make sure to gem install paint to get the colored text output.
Here's the output:
It should be relatively straight-forward to write this as a SQL user-defined function and ORDER BY RGB_to_HUE(hex_color_code), however, my SQL knowledge is pretty basic.
EDIT: I posted this question on dba.SE about converting the Ruby to a SQL user defined function.
This is based on the answer by #dliff. I initially edited it, but it turns out my edit was rejected saying "it should have been written as a comment or an answer". Seeing this would be too large to post as a comment, here goes.
The reason for editing (and now posting) is this: there seems to be a problem with colors like 808080 because their R, G and B channels are equal. If one needs this to sort or group colors and keep the passed grayscale/non-colors separate, that answer won't work, so I edited it.
DELIMITER $$
DROP FUNCTION IF EXISTS `hex_to_hue`$$
CREATE FUNCTION `hex_to_hue`(HEX VARCHAR(6)) RETURNS FLOAT
BEGIN
DECLARE r FLOAT;
DECLARE b FLOAT;
DECLARE g FLOAT;
DECLARE MIN FLOAT;
DECLARE MAX FLOAT;
DECLARE delta FLOAT;
DECLARE hue FLOAT;
IF(HEX = '') THEN
RETURN NULL;
END IF;
SET r = CONV(SUBSTR(HEX, 1, 2), 16, 10)/255.0;
SET g = CONV(SUBSTR(HEX, 3, 2), 16, 10)/255.0;
SET b = CONV(SUBSTR(HEX, 5, 2), 16, 10)/255.0;
SET MAX = GREATEST(r,g,b);
SET MIN = LEAST(r,g,b);
SET delta = MAX - MIN;
SET hue=
(CASE
WHEN MAX=r THEN (60 * ((g - b)/delta % 6))
WHEN MAX=g THEN (60 * ((b - r)/delta + 2))
WHEN MAX=b THEN (60 * ((r - g)/delta + 4))
ELSE NULL
END);
IF(ISNULL(hue)) THEN
SET hue=999;
END IF;
RETURN hue;
END$$
DELIMITER ;
Again, I initially wanted to edit the original answer, not post as a separate one.
If your products can have lots of color probably a good UI will require a color picker, normally those are rectangular, so not really something possible with the order by.
If the products have a manageable number of colors you have different choice, the easiest to implement is an order table, where for every possible color is defined an order position, this table can then be joined to your query, something like
SELECT ...
FROM (SELECT ...
...
...
, ci.color_order
FROM customization_options co
LEFT JOIN customization_option_groups cog
ON cog.id = co.customization_option_group_id
LEFT JOIN color_ ci
ON designer_hex_color = ci.color
WHERE ...) a
ORDER BY color_order
Another way to go is to transform the RGB color to hue and use this as the order.
There are different formula for this conversion, depending on wich order you want the primary color to have, all of them can be found on the wikipedia page for hue, I can update the answer to help you convert one of those to T-SQL, if needed.
MySQL function Hex to Hue. Based on Tobi's answer. :)
CREATE FUNCTION `hex_to_hue`(hex varchar(6)) RETURNS float
BEGIN
declare r float;
declare b float;
declare g float;
declare min float;
declare max float;
declare delta float;
declare hue float;
set r = conv(substr(hex, 1, 2), 16, 10)/255.0;
set g = conv(substr(hex, 3, 2), 16, 10)/255.0;
set b = conv(substr(hex, 5, 2), 16, 10)/255.0;
set max = greatest(r,g,b);
set min = least(r,g,b);
set delta = max - min;
set hue=
(case
when max=r then (60 * ((g - b)/delta % 6))
when max=g then (60 * ((b - r)/delta + 2))
when max=b then (60 * ((r - g)/delta + 4))
else null
end);
RETURN hue;
END

I have 3 columns x,y and type. I'd like to find out if there's at least 3 connections of the same type on a grid using SQL

I have a game table like:
CREATE TABLE game_piece(
x Integer,
y Integer,
type Integer
);
Each (x,y) can only have 1 piece. Representing a grid (numbers being types):
1235
1134
9678
By connected I mean they have to be directly next to the origin in a vertical or horizontal fashion like:
C C=connected
COC O=origin
C
I'd like to check if there's 3 pieces connected anywhere on the grid without needing to get the whole grid of the database and doing it in python, if there's decent solution. Suggestions?
To clarify my comments on Xophmeister's answer, like this:
SELECT o.x, o.y
FROM game_piece o
JOIN game_piece p
ON p.type = o.type
AND (
(o.x = p.x AND p.y IN (o.y-1,o.y+1))
OR
(o.y = p.y AND p.x IN (o.x-1,o.x+1))
)
GROUP BY o.x, o.y
HAVING COUNT(*) > 1
And here it is working on your test data: http://sqlfiddle.com/#!3/0bd34/1
Edit: Since you only want to know if the condition exists, the best way to do it is to just shove LIMIT 1 on the end and see whether the query returns a result or not. For some reason sqlfiddle doesn't like me putting the LIMIT in there, but I tested it on my server and it works just fine.
By 'connected', I'm going to assume you mean adjacent: That is, (5,3,1234) and (4,3,1234) would be connected.
As such, what you can do is join the table to itself twice, where each join depends on the one that preceded, and the conditions include:
on nextPiece.type = lastPiece.type
and (nextPiece.x in (lastPiece.x - 1, lastPiece.x + 1)
or nextPiece.y in (lastPiece.x - 1, lastPiece.x + 1))
Note that this doesn't consider diagonals as being adjacent.
The problem with this technique is that it will return duplicates: If record A is connected to record B, then both A and B will show in the result set. As you're joining twice, you'll see three duplicates... You can do a select distinct if all you are interested in is whether you've found a match, but the query in general will not be particularly fast either way (depending on how big your grid is and how sparsely it is populated).
EDIT See Braiba's solution (and comments, below): I made a mistake :P
Depending on what do you mean by connected, you don't need to dump the whole db but only the 2 pieces on 4 directions.
select x, y,
from game_piece
where (
(x between origin_x - 2 AND origin_x + 2 AND y = origin_y)
OR (y between origin_y - 2 AND origin_y + 2 AND x = origin_x)
)
AND type = the_type;
origin_x, origin_y are the coordinates of the piece you want to check.
That will dump between 1 and 8 pieces you'll have to check.
If the game table is very large, you should add an index on the x and y column, otherwise that might not be useful.
Hope it helps.
M.
This will return the number of different connection types:
select count(distinct type) as connections
from game_piece
where ((y = $y and x between $x - 1 and $x + 1)
or (x = $x and y between $y - 1 and $y + 1))
and (x != $x or y != $y) -- exclude the origin itself
You can use this solution:
SELECT 1
FROM game_piece
WHERE
(x = $o_x AND y IN ($o_y + 1, $o_y - 1)) OR
(y = $o_y AND x IN ($o_x + 1, $o_x - 1))
GROUP BY type
HAVING COUNT(1) = 3
$o_x and $o_y being the originX and originY input parameters respectively.
If there are exactly 3 pieces of the same type connected to the origin (either vertically or horizontally), this will return 1, otherwise, it will return an empty result-set.
Edit:
What you can try in order to find out if there's any pieces on the grid having 2 or more of the same adjacent types:
SELECT COUNT(1) > 0 AS doesExist
FROM
(
SELECT 1
FROM game_piece p
INNER JOIN game_piece o ON
p.type = o.type AND (
(p.x = o.x AND p.y IN (o.y + 1, o.y - 1)) OR
(p.y = o.y AND p.x IN (o.x + 1, o.x - 1))
)
GROUP BY p.type, o.x, o.y
HAVING COUNT(1) > 1
) a
Which will return 1 if there are one or more pieces and 0 if not.