Significant improvement when I use lsqnonlin function with wrong sized X

1.5k Views Asked by At

I was trying to solve a nonlinear least-square optimization problem using matlab function lsqnonlin with default algorithm trust-region-reflective. Let the optimization problem be "minimize sum(f(x).^2)", the correct length of vector x is 38.

When I use zeros(38,1) as initial value, I got the minimized sum(f(x).^2) which is about 0.01. But when I mistakenly use zeros(40,1) as initial value, the minimized sum(f(x).^2) is about 1e-9.

I was sure that the objective function can handle the wrong input without error, when the length of vector X is 40, the objective function just ignore X(20) and X(40). The optimized X(20) and X(40) are both zero as we guess.

The optimization problem is highly nonlinear, so it is common to get quite different results with different settings. But I just could not understand why adding two variables which has nothing to do with the objective function could change the result.

My Code

The entire code of f(x) is too long, so I only show part of it. I think it is enough to show that f(x) ignores X(20) and X(40).

The function declaration of f(x)

function E = errallpass2(X,L,G1,G2,M,N,varargin)

Acturally, f(x) is a combination of two functions, namely f(x)=[f1(x1);f2(x2)], where x=[x1;x2]. L is an integer to identify how long x1 is, which is set to 20 when using wrong sized X, 19 for correct one. G1, G2 are two functions which transform x1, x2 into more convenient form respectively.

The only part in f(x) using X

X1 = X(1:L);

X2 = X(L+1:end);

[C1,I1,J1] = G1(X1);

[C2,I2,J2] = G2(X2);

X, X1, X2 no longer appear in the rest of function errallpass2.

G1(x) and G2(X)

G1 and G2 are anonymous functions in the main program.

G1 = @(x) latc2tf2(I1,J1,mat2cell(x,ones(1,20),1),'Normalized',false);

G2 = @(x) latc2tf2(I2,J2,mat2cell(x,ones(1,20),1),'Normalized',false);

I1, J1, I2, J2 are row vectors with length 19.

I1 = [repmat([1 -1],1,9) 0];

J1 = [repmat([1 1],1,9) 1];

I2 = I1;

J2 = J1;

Function latc2tf2

function [C,Sy,Sx,N,M] = latc2tf2(I,J,R,varargin)

This function first find the length of I.

L = length(I);

Every time R is used, it is in a for loop from 1 to L, and only R{i} is used, where i is the loop index. So G1,G2 never use X1(20) and X2(20) since length(I1) = length(I2) = 19, which means f(x) never use X(20) and X(40).

Part of the main program

I1 = [repmat([1 -1],1,9) 0];

J1 = [repmat([1 1],1,9) 1];

I2 = I1;

J2 = J1;

M = [sum(I1) sum(I2)];

N = [sum(J1) sum(J2)+1];

L = 20; %19 for correct sized X

G1 = @(x) latc2tf2(I1,J1,mat2cell(x,ones(1,L),1),'Normalized',false);

G2 = @(x) latc2tf2(I2,J2,mat2cell(x,ones(1,L),1),'Normalized',false);

Xo = zeros(2*L,1);

options=optimset('Diagnostics','on','Display','iter','MaxFunEvals',1e6,'MaxIter',1e4,'TolX',1e-20,'TolFun',1e-10);

tic

X = lsqnonlin(@errallpass2,Xo,[],[],options,L,G1,G2,M,N,'MagErrType','SquaredMagnitude','MagWeight',1,'BandAssign',cat(3,P&HP&NSP,S&HP&NSP),'PhaseSupport',LP);

toc