0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 classdef softMatchCorrelConstraint < softConstraint
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 properties
0095 stat
0096 comparison
0097 initStats
0098 swStats
0099 acceptsw
0100 rejectsw
0101 s1
0102 s2
0103 s1Col
0104 s2Col
0105 s1ColName
0106 s2ColName
0107 targVal
0108 sumx1sq
0109 sumx1
0110 n1
0111 sumx2sq
0112 sumx2
0113 n2
0114 sumx1x2
0115 swpsumx1sq
0116 swpsumx2sq
0117 swpsumx1
0118 swpsumx2
0119 swpsumx1x2
0120 cor
0121 swpcor
0122
0123 end
0124
0125
0126
0127 methods
0128
0129
0130 function obj = softMatchCorrelConstraint(varargin)
0131
0132
0133
0134 p = inputParser;
0135 p.addParamValue('fnc','null', ...
0136 @(fnc)any(strcmp({'matchCorrel'},fnc)));
0137 p.KeepUnmatched = true;
0138 p.parse(varargin{:});
0139
0140 if any(strcmp(p.Results.fnc,'matchCorrel'))
0141
0142 obj = constructSoftMatchCorrelConstraint(obj,varargin);
0143 else
0144 error(['Could not create a soft constraint with <fnc>: ', ...
0145 p.Results.fnc]);
0146 end
0147
0148 obj.cost = NaN;
0149 obj.swCost = NaN;
0150
0151
0152 verbosePrint('Soft matchCorrel Constraint has been created', ...
0153 'softMatchCorrelConstraint_Constructor_endObjCreation');
0154
0155 end
0156
0157
0158
0159 function cost = initCost(obj)
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173 obj = obj.initStats();
0174 cost = obj.comparison(obj.targVal,obj.cor);
0175
0176 obj.swpcor = NaN;
0177 obj.swpsumx1sq = NaN;
0178 obj.swpsumx2sq = NaN;
0179 obj.swpsumx1 = NaN;
0180 obj.swpsumx2 = NaN;
0181 obj.swpsumx1x2 = NaN;
0182
0183 obj.cost = cost;
0184 obj.swCost = NaN;
0185 end
0186
0187
0188 function swCost = swapCost(obj,targSample,targSampleIndex, feederdf,feederdfIndex)
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200 if (obj.s1 ~= targSample && obj.s2 ~= targSample ...
0201 && obj.s1 ~= feederdf && obj.s2 ~= feederdf)
0202 error('swCost called, but no sample part of this cost function');
0203 end
0204
0205
0206
0207 obj.swStats(targSample,targSampleIndex, feederdf,feederdfIndex);
0208
0209
0210 swCost = obj.comparison(obj.targVal,obj.swpcor);
0211 obj.swCost = swCost;
0212
0213 end
0214
0215
0216 function obj = initCorrel(obj)
0217
0218
0219
0220 obj.sumx1sq = sum((obj.s1.zdata{obj.s1Col}).^2);
0221 obj.sumx1 = sum((obj.s1.zdata{obj.s1Col}));
0222 obj.n1 = length(obj.s1.zdata{obj.s1Col});
0223
0224 obj.sumx2sq = sum((obj.s2.zdata{obj.s2Col}).^2);
0225 obj.sumx2 = sum((obj.s2.zdata{obj.s2Col}));
0226 obj.n2 = length(obj.s2.zdata{obj.s2Col});
0227
0228 obj.sumx1x2 = (obj.s1.zdata{obj.s1Col})' * (obj.s2.zdata{obj.s2Col});
0229
0230 ssx1 = obj.sumx1sq - ((obj.sumx1)^2)/obj.n1;
0231 ssx2 = obj.sumx2sq - ((obj.sumx2)^2)/obj.n2;
0232
0233 spx1x2 = obj.sumx1x2 - obj.sumx1*obj.sumx2/obj.n1;
0234
0235
0236 if(ssx1 == 0 && ssx2 == 0)
0237 obj.cor = 1;
0238 elseif(ssx1 == 0 || ssx2 == 0)
0239 obj.cor = 0;
0240 else
0241 obj.cor = spx1x2/(sqrt(ssx1)*sqrt(ssx2));
0242 end
0243
0244 obj.swpcor = NaN;
0245 obj.swpsumx1sq = NaN;
0246 obj.swpsumx2sq = NaN;
0247 obj.swpsumx1 = NaN;
0248 obj.swpsumx2 = NaN;
0249 obj.swpsumx1x2 = NaN;
0250 end
0251
0252
0253
0254 function swCorrel(obj,targSample,targSampleIndex, feederdf,feederdfIndex)
0255
0256 obj.swpsumx1sq = obj.sumx1sq;
0257 obj.swpsumx2sq = obj.sumx2sq;
0258 obj.swpsumx1 = obj.sumx1;
0259 obj.swpsumx2 = obj.sumx2;
0260 obj.swpsumx1x2 = obj.sumx1x2;
0261
0262
0263
0264
0265
0266 if targSample == obj.s1
0267
0268 obj.swpsumx1sq = obj.swpsumx1sq - (targSample.zdata{obj.s1Col}(targSampleIndex))^2;
0269 obj.swpsumx1 = obj.swpsumx1 - (targSample.zdata{obj.s1Col}(targSampleIndex));
0270 obj.swpsumx1sq = obj.swpsumx1sq + (feederdf.zdata{obj.s1Col}(feederdfIndex))^2;
0271 obj.swpsumx1 = obj.swpsumx1 + (feederdf.zdata{obj.s1Col}(feederdfIndex));
0272 end
0273
0274 if targSample == obj.s2
0275 obj.swpsumx2sq = obj.swpsumx2sq - (targSample.zdata{obj.s2Col}(targSampleIndex))^2;
0276 obj.swpsumx2 = obj.swpsumx2 - (targSample.zdata{obj.s2Col}(targSampleIndex));
0277 obj.swpsumx2sq = obj.swpsumx2sq + (feederdf.zdata{obj.s2Col}(feederdfIndex))^2;
0278 obj.swpsumx2 = obj.swpsumx2 + (feederdf.zdata{obj.s2Col}(feederdfIndex));
0279 end
0280
0281
0282 if feederdf == obj.s1
0283 obj.swpsumx1sq = obj.swpsumx1sq - (feederdf.zdata{obj.s1Col}(feederdfIndex))^2;
0284 obj.swpsumx1 = obj.swpsumx1 - (feederdf.zdata{obj.s1Col}(feederdfIndex));
0285 obj.swpsumx1sq = obj.swpsumx1sq + (targSample.zdata{obj.s1Col}(targSampleIndex))^2;
0286 obj.swpsumx1 = obj.swpsumx1 + (targSample.zdata{obj.s1Col}(targSampleIndex));
0287 end
0288
0289 if feederdf == obj.s2
0290 obj.swpsumx2sq = obj.swpsumx2sq - (feederdf.zdata{obj.s2Col}(feederdfIndex))^2;
0291 obj.swpsumx2 = obj.swpsumx2 - (feederdf.zdata{obj.s2Col}(feederdfIndex));
0292 obj.swpsumx2sq = obj.swpsumx2sq + (targSample.zdata{obj.s2Col}(targSampleIndex))^2;
0293 obj.swpsumx2 = obj.swpsumx2 + (targSample.zdata{obj.s2Col}(targSampleIndex));
0294 end
0295
0296
0297
0298 if targSample == obj.s1 && targSample ~= obj.s2
0299 obj.swpsumx1x2 = obj.swpsumx1x2 - (targSample.zdata{obj.s1Col}(targSampleIndex)) * obj.s2.zdata{obj.s2Col}(targSampleIndex);
0300 obj.swpsumx1x2 = obj.swpsumx1x2 + (feederdf.zdata{obj.s1Col}(feederdfIndex)) * obj.s2.zdata{obj.s2Col}(targSampleIndex);
0301 elseif targSample == obj.s2 && targSample ~= obj.s1
0302 obj.swpsumx1x2 = obj.swpsumx1x2 - (targSample.zdata{obj.s2Col}(targSampleIndex)) * obj.s1.zdata{obj.s1Col}(targSampleIndex);
0303 obj.swpsumx1x2 = obj.swpsumx1x2 + (feederdf.zdata{obj.s2Col}(feederdfIndex)) * obj.s1.zdata{obj.s1Col}(targSampleIndex);
0304 elseif targSample == obj.s1 && targSample == obj.s2
0305 obj.swpsumx1x2 = obj.swpsumx1x2 - (obj.s1.zdata{obj.s1Col}(targSampleIndex)) * obj.s2.zdata{obj.s2Col}(targSampleIndex);
0306 obj.swpsumx1x2 = obj.swpsumx1x2 + (feederdf.zdata{obj.s1Col}(feederdfIndex)) * feederdf.zdata{obj.s2Col}(feederdfIndex);
0307 end
0308
0309
0310 if feederdf == obj.s1 && feederdf ~= obj.s2
0311 obj.swpsumx1x2 = obj.swpsumx1x2 - (feederdf.zdata{obj.s1Col}(feederdfIndex)) * obj.s2.zdata{obj.s2Col}(feederdfIndex);
0312 obj.swpsumx1x2 = obj.swpsumx1x2 + (targSample.zdata{obj.s1Col}(targSampleIndex)) * obj.s2.zdata{obj.s2Col}(feederdfIndex);
0313 elseif feederdf == obj.s2 && feederdf ~= obj.s1
0314 obj.swpsumx1x2 = obj.swpsumx1x2 - (feederdf.zdata{obj.s2Col}(feederdfIndex)) * obj.s1.zdata{obj.s1Col}(feederdfIndex);
0315 obj.swpsumx1x2 = obj.swpsumx1x2 + (targSample.zdata{obj.s2Col}(targSampleIndex)) * obj.s1.zdata{obj.s1Col}(feederdfIndex);
0316 elseif feederdf == obj.s1 && feederdf == obj.s2
0317 obj.swpsumx1x2 = obj.swpsumx1x2 - (obj.s1.zdata{obj.s1Col}(feederdfIndex)) * obj.s2.zdata{obj.s2Col}(feederdfIndex);
0318 obj.swpsumx1x2 = obj.swpsumx1x2 + (targSample.zdata{obj.s1Col}(targSampleIndex)) * targSample.zdata{obj.s2Col}(targSampleIndex);
0319 end
0320
0321 if((targSample ~= feederdf) && ...
0322 (targSample == obj.s1 || targSample == obj.s2) && ...
0323 (feederdf == obj.s1 || feederdf == obj.s2) && ...
0324 targSampleIndex == feederdfIndex && ...
0325 obj.s1Col == obj.s2Col)
0326 obj.swpsumx1x2 = obj.sumx1x2;
0327 end
0328
0329
0330 if((targSample ~= feederdf) && ...
0331 (targSample == obj.s1 || targSample == obj.s2) && ...
0332 (feederdf == obj.s1 || feederdf == obj.s2) && ...
0333 targSampleIndex == feederdfIndex && ...
0334 obj.s1Col ~= obj.s2Col)
0335
0336 obj.swpsumx1x2 = obj.sumx1x2 - obj.s1.zdata{obj.s1Col}(targSampleIndex) * obj.s2.zdata{obj.s2Col}(feederdfIndex) + ...
0337 obj.s2.zdata{obj.s1Col}(feederdfIndex) * obj.s1.zdata{obj.s2Col}(targSampleIndex);
0338 end
0339
0340
0341 swpssx1 = obj.swpsumx1sq - ((obj.swpsumx1)^2)/obj.n1;
0342 swpssx2 = obj.swpsumx2sq - ((obj.swpsumx2)^2)/obj.n2;
0343
0344 swpspx1x2 = obj.swpsumx1x2 - obj.swpsumx1*obj.swpsumx2/obj.n1;
0345
0346
0347 if(swpssx1 == 0 && swpssx2 == 0)
0348 obj.swpcor = 1;
0349 elseif(swpssx1 == 0 || swpssx2 == 0)
0350 obj.swpcor = 0;
0351 else
0352 obj.swpcor = swpspx1x2/(sqrt(swpssx1)*sqrt(swpssx2));
0353 end
0354
0355
0356 end
0357
0358
0359
0360
0361 function cost = matchCorrel(obj,x1,x2)
0362
0363 cost = ((abs(x2-x1)/2)^obj.exp)*obj.weight;
0364
0365 end
0366
0367
0368
0369 function cost = acceptSwap(obj)
0370
0371 obj.acceptsw();
0372 cost = acceptSwap@genericConstraint(obj);
0373 end
0374
0375
0376 function cost = rejectSwap(obj)
0377
0378 obj.rejectsw();
0379 cost = rejectSwap@genericConstraint(obj);
0380 end
0381
0382
0383 function acceptSwapCorrel(obj)
0384
0385
0386
0387 if(isnan(obj.swpcor))
0388
0389 else
0390 obj.sumx1sq = obj.swpsumx1sq;
0391 obj.sumx2sq = obj.swpsumx2sq;
0392 obj.sumx1 = obj.swpsumx1;
0393 obj.sumx2 = obj.swpsumx2;
0394 obj.sumx1x2 = obj.swpsumx1x2;
0395 obj.cor = obj.swpcor;
0396
0397
0398 obj.rejectSwapCorrel();
0399
0400 end
0401 end
0402
0403
0404 function rejectSwapCorrel(obj)
0405
0406 obj.swpcor = NaN;
0407 obj.swpsumx1sq = NaN;
0408 obj.swpsumx2sq = NaN;
0409 obj.swpsumx1 = NaN;
0410 obj.swpsumx2 = NaN;
0411 obj.swpsumx1x2 = NaN;
0412 end
0413
0414
0415 function obj = constructSoftMatchCorrelConstraint(obj,varargin)
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444 p = softMatchCorrelConstraint.parseMatchCorrelConstructorArgs(varargin{:});
0445
0446 if(p.Results.sosObj.containsSample(p.Results.sample1) == false)
0447 error('Cannot create soft distance constraint: sos Object does not contain the sample1');
0448 end
0449
0450 if(p.Results.sosObj.containsSample(p.Results.sample2) == false)
0451 error('Cannot create soft distance constraint: sos Object does not contain sample2');
0452 end
0453
0454
0455 col1 = p.Results.sample1.colName2colNum(p.Results.s1ColName);
0456 if(col1 == -1)
0457 error('Specified column name not found in sample1');
0458 end
0459
0460 if(strcmp(p.Results.sample1.format{col1},'%f') == 0)
0461 error('Specified column is not of numeric (%f) format, so cannot use as soft constraint');
0462 end
0463
0464 col2 = p.Results.sample2.colName2colNum(p.Results.s2ColName);
0465 if(col2 == -1)
0466 error('Specified column name not found in sample');
0467 end
0468
0469 if(strcmp(p.Results.sample2.format{col2},'%f') == 0)
0470 error('Specified column is not of numeric (%f) format, so cannot use as soft constraint; 2nd sample');
0471 end
0472
0473
0474
0475
0476
0477
0478 if length(p.Results.sample1.n) ~= length(p.Results.sample2.n)
0479 error('Sample sizes must be equal if using paired matching');
0480 end
0481
0482
0483
0484
0485
0486 obj.initStats = @obj.initCorrel;
0487 obj.swStats = @obj.swCorrel;
0488 obj.acceptsw = @obj.acceptSwapCorrel;
0489 obj.rejectsw = @obj.rejectSwapCorrel;
0490
0491
0492
0493 if(strcmp(p.Results.fnc,'matchCorrel'))
0494 obj.comparison = @obj.matchCorrel;
0495 else
0496 error('function not yet supported');
0497 end
0498
0499
0500 obj.sosObj = p.Results.sosObj;
0501 obj.constraintType = p.Results.constraintType;
0502 obj.fnc = p.Results.fnc;
0503
0504
0505 obj.weight = p.Results.weight;
0506 obj.exp = p.Results.exponent;
0507
0508 if(p.Results.targVal < -1 || p.Results.targVal > 1 || isnan(p.Results.targVal))
0509 error('Target correlation value must be a number -1 <= targ <= 1');
0510 end
0511
0512 obj.targVal = p.Results.targVal;
0513
0514 obj.s1 = p.Results.sample1;
0515 obj.s2 = p.Results.sample2;
0516 obj.s1Col = col1;
0517 obj.s2Col = col2;
0518 obj.s1ColName = p.Results.s1ColName;
0519 obj.s2ColName = p.Results.s2ColName;
0520
0521
0522 obj.label = [obj.constraintType,'_',obj.fnc,'_',...
0523 obj.targVal,'_',...
0524 obj.s1.name,'_',obj.s1ColName,'_',...
0525 obj.s2.name,'_',obj.s2ColName,'_',...
0526 'p','1','_w',...
0527 num2str(obj.weight),'_e',num2str(obj.exp)];
0528 if any(strcmp(p.UsingDefaults,'name'))
0529 obj.name = obj.label;
0530 else
0531 obj.name = p.Results.name;
0532 end
0533 end
0534
0535
0536 end
0537
0538 methods (Static)
0539
0540 function p = softMatchCorrelConstraintInputParserMatchCorrel()
0541
0542
0543
0544
0545 p = inputParser;
0546
0547
0548
0549
0550
0551
0552 p.addParamValue('sosObj','null',@(sosObj)strcmp(class(sosObj),'sos'));
0553 p.addParamValue('constraintType', 'null', ...
0554 @(constraintType)any(strcmp({'soft'},constraintType)));
0555 p.addParamValue('fnc','null', ...
0556 @(fnc)any(strcmp({'matchCorrel'},fnc)));
0557 p.addParamValue('sample1','null',@(sample1)strcmp(class(sample1),'sample'));
0558 p.addParamValue('sample2','null',@(sample2)strcmp(class(sample2),'sample'));
0559 p.addParamValue('s1ColName','',@(s1ColName)ischar(s1ColName));
0560 p.addParamValue('s2ColName','',@(s2ColName)ischar(s2ColName));
0561 p.addParamValue('targVal',NaN,@(targVal)isnumeric(targVal));
0562 p.addParamValue('exponent',2,@(exponent)isnumeric(exponent));
0563 p.addParamValue('weight',1,@(weight)isnumeric(weight));
0564 p.addParamValue('name','noname',@(name)ischar(name));
0565
0566 end
0567
0568
0569 end
0570
0571 methods (Static, Access = private)
0572
0573
0574 function p = parseMatchCorrelConstructorArgs(varargin)
0575
0576
0577
0578
0579 varargin = varargin{1};
0580 p = softMatchCorrelConstraint.softMatchCorrelConstraintInputParserMatchCorrel();
0581 p.parse(varargin{:});
0582 end
0583
0584 end
0585
0586
0587 end