You are on page 1of 26

//********************************************************************************

*********************************************************************//

// The Following subroutines implements the computation of lower and upper bounds of
approximate subdifferential of a proper convex univariate

// PLQ function composed of quadratic pieces of the form ax^{2} + bx + c where, a>=0 (real number),
b is any real and c may be a real or +infinity.

// Created by: Deepak Kumar (Deepak.n.sonukumar@gmail.com) Last updated:


27/07/2016 (DD/MM/YYYY)

//********************************************************************************
********************************************************************//

function [outputvalue]=
plq_binary_search(plqf,ind_L,ind_R,implementationtype,plql,x_bar,partFlag,varargin)

// plqf : Matix, Piecewise linear quadratic Functions(N) in Nx4 matrix(as per data
structure of CCA Toolbox)

// ind_L : Int, Left side index to start Binary search with

// ind_R : Int, Right side index to start Binary search with

// Implementationtype = 1 : Int, Binary search in the primal space to find the particular domain
or the interval in which x_bar belongs

// Implementationtype = 2 : Int, Binary search in dual space for finding the particular PLQ
functions

// plql : vector, affine function defined as y-> x_bar*y + (eps-f(x_bar))

// partFlag : char, Flag for algorithm to compute the left/right side bound

// fStar : Matrix, legendre-Fenchel Transfrom(used only for visualizing)

//xvec = plqf(:,1); // to store the x values in a vector to do binary


search upon

if implementationtype == 1 then // Implementation type 1 for finding the


index of xbar

BreakEvenPointFlag = %F; // Flag to check if x_bar is a breakeven


point
while ((ind_R-ind_L)~=1 & BreakEvenPointFlag == %F),

ind_M = floor((ind_L + ind_R)/2); // computing the centric index as mean


of leftmost and rightmost index

[ind_L,ind_R,BreakEvenPointFlag] =
binary_search_cmp(ind_L,ind_R,ind_M,plqf(ind_M,1),x_bar); // a Function to compute the next
iteration's left and right indices

if (BreakEvenPointFlag) then outputvalue = ind_M; end; // BreakEvenPointFlag == True


implies xvec(ind_M) = x_bar

end

if ~BreakEvenPointFlag then // if BreakEvenPointFlag is false implies we


didn't got our solution through binary search, hence according to Data Structure used right index is
our PLQ function

outputvalue = ind_R; // output value will always correspond to the


right index (according to the data structure used)

end

end

if implementationtype == 2 then // implementationtype == 2 is for using


BS for searching Bounds on approximate subdifferential

FoundBoundValue = %F; // initialize Found Bound Flag to be false

if partFlag=='L' then // if it's left part

indxbar = ind_R; // indxbar is the right index

end

if partFlag=='R' then // if it is right part

indxbar=ind_R+1; // indxbar is right part+1(as left and right


indices have been reversed)

end

while (abs(ind_R-ind_L)~=1 & ~FoundBoundValue),

ind_M = floor((ind_L+ind_R)/2); // ind_M is assigned the integer value of


the arithmatic mean of

[Fc_SM,S_M] = point_lft_calc(plqf,ind_M); // For calculating subdifferential and


conjugate value at mid index
L_SM = S_M*plql(3) + plql(4);

[ind_L,ind_R,FoundBoundValue] = binary_search_cmp(ind_L,ind_R,ind_M,L_SM,Fc_SM); //
Obtain Left and Right indices of Binary Search for next iteration

if (FoundBoundValue) then outputvalue = S_M; end;

end

if ~FoundBoundValue then

if partFlag == 'L' then // Calculations on Left part of x_bar

// mprintf("\n\n --------------------Left part of the x_bar--------------- \n\n")

[outputvalue] = find_solutions(plqf,ind_L,ind_R,plql,x_bar,indxbar,partFlag); // For the left


part of the graph, find solution(s)

if length(outputvalue) == 0 then cerror("No Solution found on left Side --> No solution .........
Check Function..."); end;

// mprintf("\n\n-----------------Left part Completed------------------\n\n")

end

if partFlag == 'R' & argn(2)>7 then // Calculations on Right part of


x_bar

// mprintf("\n\n --------------------Right part of the x_bar--------------- \n\n")

[outputvalue] = find_solutions(plqf,ind_R,ind_L,plql,x_bar,indxbar,partFlag,varargin(1)); //
For Right part of the graph, find solution

// mprintf("\n\n-------------------- Right Part Completed -----------------------\n\n")

end

end

end

endfunction

//Specific for this Algorithm only

function [bound] = find_solutions(plqf,indxL,indxR,plql,xbar,indxbar,partFlag,varargin)

// The Function finds solution by using the true_bound_check function but accomodating any
interval jump by Binary search(BS)
// plqf : Matrix, Piece-wise linear quadratic function

// indxL : Int, The final left index returned by BS

// indxR : Int, The final right index returned by BS

// plql : vector, affine function defined as y-> x_bar*y + (eps-f(x_bar))

// xbar : Float, The point(in primal domain) for calculation of approximate subdifferential

// indxbar : int, index of the function where xbar belongs

// partFlag : char, Flag to determine left or right part

// bound : vector, The lower/upper bound or both according to the cases

if indxL<1 & isinf(plqf(indxR,4)) then // if function is left bounded

bound = plq_fextd_sol(plqf,indxR+1,plql,xbar,indxbar,partFlag,%T); // search for solution in


first part of extended solution

if length(bound)==1 then // if bound is found

return; // return the bound

end

end

if indxL<1 & isinf(plqf(indxR,4)) & xbar~=plqf(1,1) then // if function is left bounded &
xbar is not the bounded x value

indxL = 1; // search for solution in first part, set left index to 1

indxR = 2; // set right index to 2

[bound] = true_bound_check(plqf,indxL,indxR,plql,xbar,indxbar,partFlag); // find the solutions if


function is the one with intersection

if length(bound)==0 & indxbar==3 then // if solution is not in the first part


and indxbar is 3

indxL=2; // check for solution in 3rd function, set left index to


2

indxR =3; // set right index to 3

[bound] = true_bound_check(plqf,indxL,indxR,plql,xbar,indxbar,partFlag); // find solutions

end

else
if argn(2)>7 then // if optional value(lower bound) is present

[bound] = true_bound_check(plqf,indxL,indxR,plql,xbar,indxbar,partFlag,varargin(1)); // find


solutions

else

[bound] = true_bound_check(plqf,indxL,indxR,plql,xbar,indxbar,partFlag); // Checking


whether the final left and right indices contain root(s), if they do make FoundPLQ True

end

end

endfunction

//Specific for this Algorithm only

function [boundValue] = true_bound_check(plqf,indx_L,indx_R,PLQL,xbar,indxbar,partFlag,varargin)

// Checks whether the solution found is in the bounds provided by S_indxL and S_indxR

// plqf : Matrix, PLQ function

// indx_L : Int, current Left Index

// indx_R : Int, current Right Index

// PLQL : vector, affine function defined as y-> x_bar*y + (eps-f(x_bar))

// xbar : float, point at which approximate subdifferentials are required to be computed

// indxbar : int, index of the function where xbar belongs

// partFlag : char, Flag to determine left or right part

// trueBoundFlag : Boolean, Flag to confirm the solution exists in [S_indxL,S_indxR]. starts with
assumption that it is; returns False if it doesn't

// boundValue : vector, returns bound(s)) if one/both exists, else an empty matrix

// S_indxL : Float, subdifferential value at indx_L

// S_indxR : Float, subdifferential value at indx_R

solrs = []; // variable to store the solutions

if indx_R > size(plqf,1) then // if indx_R > last index


a = plqf(indx_L,2); // use index from last function to compute x^2
coefficient

else // else

a = plqf(indx_R,2); // compute x^2 coefficient of the current


function from the plq function

end

boundValue = []; // bound values intialized as an empty vector

if indx_L < 1 then // if current left index is less the 1 implies first
part of the conjugate function

[boundValue] = plq_ff_sol(plqf,PLQL,xbar,indxbar,partFlag); // Compute


solution from first function

if length(boundValue)==0 then // implies no solution in this part or


solution could be in extended linear region

lsol = plq_extd_sol(plqf,indx_R,PLQL,xbar,indxbar,partFlag,%F); // compute


solution in linearly extended region

boundValue = lsol;

//trueBoundFlag = %F; // set BoundFlag to false to compute


solutions in adjacent functions

end

return; // return

end

if indx_R >= size(plqf,1) then // if the current right index is greater or


equal to the last index implies last part of the conjugate function

if argn(2)> 7 then

[boundValue] = plq_lf_sol(plqf,PLQL,xbar,indxbar,partFlag,varargin(1)); //
compute solution from last function

else

[boundValue] = plq_lf_sol(plqf,PLQL,xbar,indxbar,partFlag,%F);

end

if length(boundValue)==0 then // implies no solution in last part or


solution could be in extended linear region
lsol = plq_extd_sol(plqf,indx_R-1,PLQL,xbar,indxbar,partFlag,%F); // compute
solution in current index and current index+1's linearly extended region

boundValue = lsol;

//trueBoundFlag = %F; // set BoundFlag to false to compute


solutions in adjacent functions

end

return; // return to function call

end

[SindxL,SindxR] = plq_sval_calc(plqf,indx_L,indx_R,a,xbar,indxbar,partFlag);

Sroots = roots_plq_plql(plqf(indx_R,2),plqf(indx_R,3),plqf(indx_R,4),PLQL(3),PLQL(4),indx_R,plqf);
// Calculate solution(s); intersection point(s) between for plqf and plql function

if ~isreal(Sroots) then

lsol = plq_extd_sol(plqf,indx_R,PLQL,xbar,indxbar,partFlag,%F); // compute


solution in current index and current index+1's linearly extended region

boundValue = [boundValue,lsol]; // push solution in boundValue vector

if length(boundValue)==0 then

boundValue = plq_extd_sol(plqf,indx_R-1,PLQL,xbar,indxbar,partFlag,%F);

end

return; // return

end

boundValue = plq_rf(SindxL,SindxR,Sroots); // Compare and find Feasible roots

solrs = boundValue; // Store the roots in Solrs

if (length(boundValue)~=1) then // If length of boundValue<2 and the


adjacent function is also quadratic check if there is any solution with plq_extd_sol()

boundValue = plq_extd_sol(plqf,indx_R,PLQL,xbar,indxbar,partFlag,%F); //
compute solution in current index and current index+1's linearly extended region

if length(boundValue)~=1 then // No solution find till now


boundValue = plq_extd_sol(plqf,indx_R-1,PLQL,xbar,indxbar,partFlag,%F);
// push lsol as a solution

end

end

if length(boundValue)~=1 & length(solrs)==2 then

boundValue = solrs(2);

end

endfunction

// Generalized

function [varargout] = plq_plot_gp(xL,xU,gphNum,graphTitle,varargin)

// This function plots any number of plq functions and points on a single graph and returns
handles to each plot; preferred order of inputs is plqf,points while output is exactly in the reverse
order;

// If input order is mixed the output of the function still remains the same (All the points in reverse
order>All the Plq functions), Think of it as forming a stack with PLQ functions first and then point of
top of that.

// xL : Float, Lower limit of x-axis

// xU : Float, Upper limit of x-axis

// gphNum : Int, The graphic figure window to plot on

// graphTitle : String, A String

// varargin : Variable Inputs, Variable number of plq functions and points as input (preferred
oder is plqfs, points)

// varargout : Variable outputs, Variable number of outputs(handles to plots)(depends upon


number of plqf and points); Order is points, PLQ functions, reverse as that of input

if argn(2) < 5 then // Throw error if number of agruments are zero


cerror("insufficient Inputs.....");

end

clf(gphNum);

plotingPoints = []; // Data structure(Matrix) to save points in (as


rows)

for i=1:length(varargin) // Loop to go through each input

inputValue = varargin(i);

if size(inputValue,2) == 4 then // if number of columns in the input is 4 =>


It is PLQ function

plq_plotMultiple(xL,xU,inputValue); // Plot PLQ functions using


plq_plotMultiple

end

if size(inputValue,2) == 2 then // if number of columns are 2 => it is a


point

plotingPoints = [plotingPoints;inputValue]; // Save all the points in a matrix to


plot them after the PLQ functions have been plotted

end

end

for i=1:size(plotingPoints,1) // Iterate through all the points to be plot

plot(plotingPoints(i,1),plotingPoints(i,2)); // plot the points

end

title(graphTitle); // Give title to the graph

figHandle = gca(); // Obtain handle for the current figure

varargout = list(); // intialize the varargout(Number of outputs) as


an empty list

//Points Handle(Stack)

for i=1:size(plotingPoints,1) // Iterate through the number of plotted


points

varargout(i) = figHandle.children(i).children; // Using the datastucture of returned


figHandle assign the point handles to the output list just in the reverse order as they have inputted

end
for j=i+1:length(varargin) // PLQ Function Handles are from i+1 to total
number of inputs in the returned data structure from the gca() function

varargout(j) = figHandle.children(j).children; // Using the datastucture of returned


figHandle assign the plot handles to the output list just in the reverse order as they have inputted

end

endfunction

// Generalized

function point_plot_prop(pointHandle,markSize,markColor)

// This functions alters the size and color of points plotted on a graph for better visualization

// pointHandle : Function Handle, Handle to the point plotted on the graph

// markSize : Int, desired size of the point

// markColor : Int, desired color of the point (integer)

pointHandle.mark_mode = "on";

pointHandle.mark_size = markSize;

pointHandle.mark_foreground = markColor;

endfunction

//Generalized

function plq_plot_prop(gphHandle,gphThickness,gphColor)

// This functions alters the thickness and color of plots on a graph for better visualization

// gphHandle : Function Handle, Handle to the function's plot on the graph

// gphThickness : Int, desired thickness of the plot

// gphColor : Int, desired color of the plot (integer)

gphHandle.thickness = gphThickness;
gphHandle.foreground = gphColor;

endfunction

//Generalized

function [Flft_Sindx, S_indx] = point_lft_calc(plqfunc,indx,varargin)

// Calculation of subdifferential and legendre-fenchel transform at a point

// plqfunc : Matrix, Piece-wise linear quadratic function

// indx : Int, The index determining the row of plq function

// S_indx : Float, Subdiferential value calculated at x

// Flft_Sindx : Float, The value of legendre-fechel transform at S_indx

if argn(2) < 3 then

x = plqfunc(indx,1); // Upper bound of plqfunc, calculate at this


point if x is not specified

else

x = varargin(1) ; // Specific point to on a plq function to calculate


conjugate's value upon

end

a = plqfunc(indx,2); // plqfunc - a*x^2 + b*x + c, hence a

b = plqfunc(indx,3); // b

c = plqfunc(indx,4); // and c

S_indx = 2*a*x + b; // differential value at x

Fx = a*(x)^2 + b*x + c; // value of plq function at x

Flft_Sindx = S_indx*x - Fx; // conjugate value calculated as fStar ->


<S_indx,x> - F(x)

endfunction
// Generalized for solution between a function and line

function[root] = roots_plq_plql(a,b,c,d,e,indx,plqf)

// The function outputs the roots for the intersection of function(a*x^2 + b*x + c; Quadratic, linear
or point accordingly) with a line

// a : Float, plqf(xindex,2) , xindex is a demo variable pointing to the index corresponding to the
PLQ function containing x

// b : Float, plqf(xindex,3)

// c : Float, plqf(xindex,4)

// x : Float, plqf(xindex,1)

// d : Float, xbar

// e : Float, epsilon - F(xbar)

// root : Float, the solution(s)

root = []; // intialising root as empty vector

if a > 0 then // if a>0 implies function is convex and is quadratic


hence two roots

t1 = (2*b + (4*a*d)); // division of formula of roots for quadratic


equation in tqo terms t1 and t2

t2 = ((b^2) - (4*a*c) - (4*a*e));

root(1) = (t1 - sqrt((t1^2)-4*t2))/2; // root(1) is for the addition

root(2) = (t1 + sqrt((t1^2)-4*t2))/2; // root(2) is for the subtraction

end

x = plqf(indx,1);

if a==0 then // a==0 implies the function is Linear

if (x==d) then // if x==d implies x = xbar implies x is a breakeven


point

if isinf(plqf($,4)) then // if it is right bounded

if indx+1 == size(plqf,1) then // if indx is last index-1

root(1) = %inf; // then root is +inf

end
elseif isinf(plqf(1,4)) then // if it is left bounded

if indx-1 == 0 then // if indx is 1

root(1) = -%inf; // root is -inf

end

else // else if it is not at the end points

root(1) = b; // root(1) is the slope of the line

end

else // else if it is not a breakpoint

if isinf(c) then

root = [];

else

root(1) = (e + b*x + c)/(x - d); // compute root(1)

end

end

if indx > 1 & indx < size(plqf,1) then // if not at first part of conjugate function
implies solution can be at just left breakpoint

xminus = plqf(indx-1,1); // set xminus as the upper bound of just left


function in primal domain

if ((xminus-d)~=0) then

root(2) = (e + b*xminus + c) / (xminus-d); // calculate second root's value

end

end

end

endfunction

// Generalized

function[ind_L,ind_R,fv] = binary_search_cmp(indxL,indxR,indxM,cmpval1,cmpval2)
// cmpval1 and cmpval2 are two floating values to be compared upon which decision of the
indices depend

// indxL : Int, Current iteration's left most index

// indxR : Int, Current iteration's right most index

// indxM : Int, Current iteration's Mid index

// cmpval1 : Float, comparison value1 whose value depends upon the previous iteration's centre
index

// cmpval2 : Float, comparison value2, a fixed value whose interval is required

// ind_L : int, Updated left index

// ind_R : int, Updated right index

// fv : Bool, True if cmpval1 and cmpval2 are equal, otherwise false

ind_L = indxL; // Initialize left output's index

ind_R = indxR; // Initialize Right output's index

fv = %F; // set found Value as False

if cmpval1 < cmpval2 then // if value 1 is less then val 2

ind_L = indxM; // set left index to mid index

end

if cmpval1 > cmpval2 then // if value 1 is greater than val 2

ind_R = indxM; // set right index to mid index

end

if isEqual(cmpval1,cmpval2) then // if value 1 is equal to value 2

fv = %T; // set found valule flag to True

end

endfunction

//Specific for this Algorithm only

function plot_Modgphs(xvec,gphNum,gphTitle,plqf,ind_L,ind_R,ind_M)
[rightPoint,midPoint,leftPoint,upperBounds]=plq_plot_gp(xvec(1),xvec($-
1),gphNum,gphTitle,plqf,[xvec(ind_L),plq_eval(plqf,xvec(ind_L))],[xvec(ind_M),plq_eval(plqf,xvec(ind
_M))],[xvec(ind_R),plq_eval(plqf,xvec(ind_R))]);

point_plot_prop(midPoint,10,9); // To modify midpoint's thickness and


foreground as 10 and 9(Navy Blue)

point_plot_prop(rightPoint,10,6); // To modify rightpoint's thickness and


foreground as 10 and 6(Pink)

point_plot_prop(leftPoint,10,5); // To modify leftpoint's thickness and


foreground as 10 and 5(red)

plq_plot_prop(upperBounds,2,12); // To modify graph's thickness and


foreground as 2 and 12(sky blue)

endfunction

function [ssol] = plq_ff_sol(plqf,plql,xbar,indxbar,partFlag,varargin)

// Function to find solutions in the first function of plqf

// plqf : Matrix, Piece-wise Linear Quadratic Function

// plql : vector, plql line in accordance with PLQ data structure

// xbar : float, point at which approximate subdifferentials are required to be computed

// indxbar : int, index of the function where xbar belongs

// partFlag : char, Flag to determine left or right part

// varargin : Optional inputs; expceted Boolean, False if called from true_bound_check, else true

// ssol : vector, Solution set vector

ssol = []; // variable to store the bound values

if (plqf(1,2)==0) then // if linear

if isinf(plqf(1,4)) then // if bounded

SindxL = -%inf; // set left differential to -%inf

[fconjR,SindxR] = point_lft_calc(plqf,2,plqf(1,1)); // set right differential to the value


of 2nd function at point plqf(1,1)
else // if not bounded

[fconjL,SindxL] = point_lft_calc(plqf,1); // calculate left differential

[fconjR,SindxR] = point_lft_calc(plqf,2,plqf(1,1)); // compute right differential from


2nd function at first functions bound

end

else // when quadratic

SindxL = -%inf; // set SindxL as infinite

[fconjR,SindxR] = point_lft_calc(plqf,1); // compute SindxR

end

Sroots = roots_plq_plql(plqf(1,2),plqf(1,3),plqf(1,4),plql(3),plql(4),1,plqf); // compute roots


between plql and plqf

if ~isreal(Sroots) then // if roots are complex

ssol = plq_extd_sol(plqf,1,plql,xbar,indxbar,partFlag); // find solutionn in extended


linear region

if length(ssol)==0 then // if no solution exists in linear region

ssol = SindxL; // set solution to left differential value

end

return; // return the solution

end

ssol = plq_rf(SindxL,SindxR,Sroots); // if not complex roots, compare and find


feasible roots

Lsr = plql(3)*SindxR + plql(4); // compute plql value at the breakpoint

if fconjR > Lsr then //compare it with conjugate value at breakpoint,


if conjugate's value is greater then both solutions exists on this side of the graph only

if length(ssol)==1 then // if onw solution is in this function

ssol = [SindxL,ssol]; // push left differential value in the solution set

end

end
if length(ssol)==0 then // if number of solutions are zero

ssol = SindxL; // include the left differential

end

endfunction

function [ssol] = plq_lf_sol(plqf,plql,xbar,indxbar,partFlag,varargin)

// Function to find solutions in the last function of plqf

// plqf : Matrix, Piece-wise Linear Quadratic Function

// plql : vector, plql line in accordance with PLQ data structure

// xbar : float, point at which approximate subdifferentials are required to be computed

// indxbar : int, index of the function where xbar belongs

// partFlag : char, Flag to determine left or right part

// varargin : optional input; expected Boolean, False if called from true_bound_check, else true

// ssol : vector, Solution set vector

ssol = []; // variable to store solutions

endx = size(plqf,1); // number of pieces in plqf

if (plqf($,2)==0) then // if linear

if isinf(plqf($,4)) then // if right bounded

SindxR = %inf; // set SindxR to %inf

if partFlag=='R' & endx==indxbar then // if it is right part of algorithm and


index of xbar is last index

[fconjL,SindxL] = point_lft_calc(plqf,endx,xbar); // compute SindxL at xbar

else // else
[fconjL,SindxL] = point_lft_calc(plqf,endx-1); // compute SindxL from last-1 index

end

else //else if unbounded

if partFlag=='L' & endx==indxbar then // if it is left part of algorithm and


index of xbar is last index

[fconjR,SindxR] = point_lft_calc(plqf,endx,xbar); // comoute SindxR at xbar

else // else

[fconjR,SindxR] = point_lft_calc(plqf,endx,plqf(endx-1,1)); // compute SindxR at plqf($-


1,1) with last function

end

if partFlag=='R' & endx==indxbar then // if it's right part and last index ==
index of xbar

[fconjL,SindxL] = point_lft_calc(plqf,endx,xbar); // compute SindxL at xbar

else // else

[fconjL,SindxL] = point_lft_calc(plqf,endx-1); // compute SindxL at last-1 function

end

end

else // else if quadratic

if partFlag=='L' & endx==indxbar // if it's left part and indxbar == last index

[fconjR,SindxR] = point_lft_calc(plqf,endx,xbar); // compute SindxR at xbar

else // else

SindxR = %inf; // set S_indxR as infinite

end

if partFlag=='R' & endx==indxbar then // if it's right side and indxbar==endx

[fconjL,SindxL] = point_lft_calc(plqf,endx,xbar); // compute SindxL at xbar

else //else

[fconjL,SindxL] = point_lft_calc(plqf,endx,plqf(endx-1,1)); // compute SindxL at plqf($-1,1)

end

end

if isinf(plqf($,4)) then // if bounded


Sroots = roots_plq_plql(plqf($-1,2),plqf($-1,3),plqf($-1,4),plql(3),plql(4),endx-1,plqf); //
compute solution between last-1 function and plql

else // else

Sroots = roots_plq_plql(plqf($,2),plqf($,3),plqf($,4),plql(3),plql(4),endx-1,plqf); // compute


solution between last function and plql, endx-1 so that it is x is finite value

end

if ~isreal(Sroots) then // if roots are complex

//mprintf("\n\ncomplex roots\n\n");

lsol = plq_extd_sol(plqf,endx-1,PLQL,xbar,indxbar,partFlag); // compute solution in last


index-1 and last index's linearly extended region

ssol = [lsol]; // push solution in boundValue vector

return; // return the solution

end

ssol = plq_rf(SindxL,SindxR,Sroots); // if roots are real, find feasible roots

if length(ssol)~=1 then //& partFlag=='L' then // if number ao roots are not 1(0 or
2)

ssol = plq_extd_sol(plqf,endx-1,plql,xbar,indxbar,partFlag); // compute solution in just


left's extended linear region

end

if partFlag=='R' then // if it's right flag

if length(ssol)==0 | ((ssol-varargin(1))<=1E-6) then // if number of solutions is still


zero or ssol is equal to left bound

ssol = [SindxR]; // set solution to SindxR

end

else // else if it is left part

if length(ssol)==0 then // number of solutions is zero

ssol = [SindxR]; // set ssol to SindxR

end

end
endfunction

function[S_indxL,S_indxR] = plq_sval_calc(plqf,indx_L,indx_R,a,xbar,indxbar,partFlag)

// Function to compute lower(left) and upper(right) differential value for a function

// plqf : Matrix, Piecewise linear Quadratic Function

// indx_L : int, indx_R-1

// indx_R : int, index corresponding to the function in PLQF Structure

// a : float, plqf(indx_R,1)

// xbar : float, point at which approximate subdifferentials are required to be computed

// indxbar : int, index of the function where xbar belongs

// partFlag : char, Flag to determine left or right part

if (a==0) then // if function is linear

if isinf(plqf(indx_L,4)) then // if it is bounded on left side,

S_indxL = -%inf; // set S_indxL to -inf

else // else

if partFlag=='R' & indxbar==indx_R then

[Flft_L,S_indxL]= point_lft_calc(plqf,indx_R,xbar); // calculate S_indxl from just left


function at the breakpoint of the two

else

[Flft_L,S_indxL]= point_lft_calc(plqf,indx_L); // calculate S_indxl from just left


function at the breakpoint of the two

end

end

if isinf(plqf(indx_R,4)) then // if the function is right bounded

S_indxR = %inf; // set S_indxR to +inf

else // else
if partFlag=='L' & indxbar==indx_R then

[Flft_R,S_indxR]= point_lft_calc(plqf,indx_R,xbar);

else

[Flft_R,S_indxR]= point_lft_calc(plqf,indx_R+1,plqf(indx_R,1)); // calculate S_indxR from


just right function at the breakpoint

end

end

else

if partFlag=='R' & indxbar==indx_R then

[Flft_L,S_indxL]= point_lft_calc(plqf,indx_R,xbar); // calculate S_indxl from just left


function at the breakpoint of the two

else

[Flft_L,S_indxL]= point_lft_calc(plqf,indx_R,plqf(indx_L,1)); // else the function is


Quadratic, hence calculate S_indxl from the current function but at left break point

end

if partFlag=='L' & indxbar==indx_R then

[Flft_R,S_indxR]= point_lft_calc(plqf,indx_R,xbar);

else

[Flft_R,S_indxR]= point_lft_calc(plqf,indx_R); // else the function is Quadratic,


hence calculate S_indxR from the current function but at right breakpoint

end

end

endfunction

function[ssol] = plq_rf(SindxL,SindxR,Sroots)

// Function to find if roots lie between lower and upper sudifferentials

// SindxL : Float, Left Differential value for the function

// SindxR : Float, Right Differential value of the function


// Sroots : vector, Solution between the corresponding function and plql

// ssol : vector, Solutions which lies between SindxL and SindxR

ssol = [];

// mprintf("\nS_indL = %f\n",SindxL) // For printing the corresponding value


on the console

// mprintf("S_root1 = %f\n",Sroots(1)) // For printing the corresponding


value on the console

// if length(Sroots)>1 then

// mprintf("S_root2 = %f\n",Sroots(2)) // For printing the corresponding


value on the console

// end

// mprintf("S_indR = %f\n\n",SindxR) // For printing the corresponding value


on the console

if (SindxL<=Sroots(1)) & (Sroots(1)<SindxR) then // if first root lies between left and
right differential values

ssol = [ssol,Sroots(1)]; // push first root to solution

end

if length(Sroots) > 1 then // if number of roots is 2

if (SindxL<=Sroots(2)) &(Sroots(2)<SindxR) then // if the second root lies between


left and right differential values

ssol = [ssol,Sroots(2)]; // push second root into the solution

end

end

endfunction

function lsol = plq_extd_sol(plqf,indx,plql,xbar,indxbar,pf,varargin)


// Function to find solutions in the extended linear part(in conjugate domain) between two
adjacent Quadratic functions(in primal domain)

// plqf : Matrix, Pice wise linear quadratic function

// indx : int, index at which extended value needs to be calculated

// plql : vector, plql line for computing solutions(intersection points) between plql and plqf

// xbar : floating point value, point at which subdifferentials are needed to be computed

lsol = []; // solution set vector initialized to empty vector

[Fcindxval,SindxLval] = point_lft_calc(plqf,indx); // compute conjugate and


differential values to compute the linearly extended region

if pf=='L' & indx==indxbar then // if it's left part and indx==indxbar

[FcindxR,SindxR] = point_lft_calc(plqf,indx,xbar); // compute root at xbar

else // else

if indx+1==size(plqf,1) & isinf(plqf(indx+1,4)) then // if it is in the last but 1 part and


it's right bounded

SindxR = %inf; // set SindxR to %inf

else //else

[FcindxR,SindxR] = point_lft_calc(plqf,indx+1,plqf(indx,1)); //compute right differential


and conjugate value at index indx+1 but at point plqf(indx,1)

end

end

if pf=='R' & indx==indxbar then // if it's right part and indx==indxbar

[Fcindx,SindxL] = point_lft_calc(plqf,indx,xbar); // compute SindxL at xbar

else // else

if indx-1==1 & isinf(plqf(indx-1,4)) then // if left bounded and index==2

SindxL = -%inf; // set SindxL to -%inf

else // else

[Fcindx,SindxL] = point_lft_calc(plqf,indx); // compute left differential and


conjugate value at index indx

end
end

b = plqf(indx,1); // set b=plqf(indx,1)

c = Fcindxval - (b*SindxLval); // compute intercept's value of the


extended linear line

d = plql(3); // set d = plql(3){xbar}

e = plql(4); // set e = plql(4){eps-F(xbar)}

if b==d then // Solution on breakpoint -> taken care by other


roots_plq_plql

return; // return

end

sol = (e-c)/(b-d); // compute solution

if SindxL<= sol & sol <=SindxR then // if solution exists between the left and
right diferential values

lsol = sol; // set lsol to solution

end

endfunction

function lsol = plq_fextd_sol(plqf,indx,plql,xbar,indxbar,pf,varargin)

// Function to find solutions in the extended linear part(in conjugate domain) between two
adjacent Quadratic functions(in primal domain)

// plqf : Matrix, Pice wise linear quadratic function

// indx : int, index at which extended value needs to be calculated

// plql : vector, plql line for computing solutions(intersection points) between plql and plqf

// xbar : floating point value, point at which subdifferentials are needed to be computed
lsol = []; // solution set vector initialized to empty vector

if pf=='L' & indx==indxbar then

[FcindxR,SindxR] = point_lft_calc(plqf,indx,xbar);

else

[FcindxR,SindxR] = point_lft_calc(plqf,indx,plqf(indx-1,1));// compute right differential


and conjugate value at index indx+1 but at point plqf(indx,1)

end

if pf=='R' & indx==indxbar then

[Fcindx,SindxL] = point_lft_calc(plqf,indx,xbar);

else

SindxL = -%inf;

end

[Fcindxval,SindxLval] = point_lft_calc(plqf,indx,plqf(indx-1,1));

b = plqf(1,1); // set b=plqf(indx,1)

c = Fcindxval - (b*SindxLval); // compute intercept's value of the


extended linear line

d = plql(3); // set d = plql(3){xbar}

e = plql(4); // set e = plql(4){eps-F(xbar)}

if b==d then // Solution on breakpoint -> taken care by other


roots_plq_plql

return; // return

end

sol = (e-c)/(b-d);

if SindxL<= sol & sol <=SindxR then


lsol = sol;

end

endfunction

You might also like