メインコンテンツ

addCustomMetric

R2026b

Add custom metric to merit function

Since R2026b

    Description

    Add-On Required: This feature requires the Optical Design and Simulation Library for Image Processing Toolbox add-on.

    meritFcn = addCustomMetric(meritFcn,fcnHandle) adds a custom metric defined by fcnHandle to the merit function meritFcn.

    meritFcn = addCustomMetric(meritFcn,fcnHandle,arg1,...,argN) passes the additional input arguments arg1,...,argN to the custom metric function after the optical system and target arguments.

    meritFcn = addCustomMetric(___,Name=Value) specifies additional options using one or more name-value arguments.

    example

    Examples

    collapse all

    Import an optical system into the workspace.

    opsys = zmximport("PhotographicLens.zmx");

    Create an empty optical merit function.

    meritFcn = opticalMeritFunction;

    Add a custom metric function that returns only the residual score. The custom function maxDistortionMetric is defined at the end of this example.

    meritFcn = addCustomMetric(meritFcn,@maxDistortionMetric,Target=2.0,Name="Max Distortion (%)")
    meritFcn = 
      opticalMeritFunction with properties:
    
             Metrics: [1×1 optics.metric.CustomMetric]
             Weights: 1
        MetricsTable: [1×3 table]
    
    

    Evaluate the merit function for the optical system.

    [score,rawMetricValues] = evaluate(meritFcn,opsys)
    score = 
    1.8706
    
    rawMetricValues = 
    1.8706
    

    Custom Function

    The maxDistortionMetric custom function measures the strongest lens distortion across the field, and computes how far it is from the desired target. If the target value is 0, the function returns the greatest distortion magnitude. Otherwise, it returns a normalized nonnegative score indicating how much that distortion exceeds the target.

    function score = maxDistortionMetric(opsys,target)
        distResult = lensDistortion(opsys);
        maxDist = max(abs(distResult.Distortion),[],"all");
        if target(1) == 0
            score = maxDist;
        else
            score = max(0,(maxDist-target(1))/target(1));
        end
    end

    Import an optical system into the workspace.

    opsys = zmximport("PhotographicLens.zmx");

    Create an empty optical merit function.

    meritFcn = opticalMeritFunction;

    Add a custom metric function that returns the residual and raw score. The custom function chromaticMetric is defined at the end of this example.

    meritFcn = addCustomMetric(meritFcn,@chromaticMetric,Target=[0.001 0.005],Name="Lateral Chromatic Aberration")
    meritFcn = 
      opticalMeritFunction with properties:
    
             Metrics: [1×1 optics.metric.CustomMetric]
             Weights: 1
        MetricsTable: [1×3 table]
    
    

    Evaluate the merit function for the optical system.

    [score,rawMetricValues] = evaluate(meritFcn,opsys)
    score = 
    1.3402
    
    rawMetricValues = 
    0.0117
    

    Custom Function

    The chromaticMetric custom function measures the strongest lateral chromatic aberration across the field, and penalizes deviations outside a desired limit or range. The function computes the maximum lateral chromatic aberration of the optical system as the raw metric value, and compares this value to a target range to compute the residual score. If the target is a single value, it returns a normalized score of how much the raw metric exceeds that value (0, if within the limit). If the target is a range, the score is 0 if the metric lies within the range. Otherwise, the function returns a normalized score of how far the metric is from the nearest boundary.

    function [residualScore, metricValue] = chromaticMetric(opsys,target)
        caResult = chromaticAberration(opsys);
        % metricValue: the physically meaningful quantity (lateral chromatic aberration)
        metricValue = max(abs(caResult.Lateral.Aberration),[],"all");
        % residualScore: unitless penalty relative to target
        if target(1)==target(2)
            if target(1) == 0
                residualScore = metricValue;
            else
                residualScore = max(0,(metricValue-target(1))/target(1));
            end
        else
            if metricValue >= target(1) && metricValue <= target(2)
                residualScore = 0;
            else
                diffs = abs(target - metricValue);
                [~,idx] = min(diffs);
                residualScore = abs(metricValue-target(idx))/target(idx);
            end
        end
    end

    Input Arguments

    collapse all

    Merit function to which to add the custom metric, specified as an opticalMeritFunction object.

    Custom metric function, specified as a function handle. The function must accept at least two input arguments: an opticalSystem object and a target value. The function can return one or two outputs. With one output, the value serves as both the residual score and raw metric. With two outputs, the first is the residual score and the second is the raw metric value.

    You must compute the residual score relative to the target value using these options.

    • If the target value is 0, the residual score must be the same as the raw metric value.

    • If the target value is a scalar and the desirable value is less than the target value, any raw metric value less than or equal to the target value must have a residual score of 0. Other raw metric values must have a residual score equal to abs((rawValue-target)/target).

    • If the target value is a scalar and the desirable value is greater than the target value, any raw metric value greater than or equal to the target value must have a residual score of 0.

    • If the target value is a range, any raw metric value within the range must have a residual score of 0. Other raw metric values must have a residual score equal to abs((rawValue-targetBoundary)/targetBoundary), which targetBoundary is the closest boundary of the target range.

    You can write the custom function in this format.

    function [residualScore,rawMetricValue] = myCustomFunction(opsys,target,arg1,...,argN)
        % add any supporting code here
        
        % define raw metric value
        rawMetricValue = ...
    
        % compute residual score relative to target
        if all(target==0)
            % no target specified: return raw metric value as residual score
            residualScore = rawMetricValue;
        elseif isequal(target(1),target(2))
            % scalar target value: compute normalized deviation
            residualScore = (rawMetricValue-target(1))/target(1);
            residualScore = abs(residualScore);
        else
            % range target: zero penalty if within range else penalize based on distance to nearest bound
            if rawMetricValue>=target(1) && rawMetricValue<=target(2)
                residualScore = 0;
            else
                getDiff = abs(target-rawMetricValue);
                [~,idx] = min(getDiff);
                residualScore = abs(rawMetricValue-target(idx))/target(idx);
            end
        end
    end
    

    Data Types: function_handle

    Additional input arguments for the custom metric function, specified as a comma-separated list. The types of the inputs depend on the function fcnHandle. These arguments are inputs to fcnHandle after the optical system and target arguments.

    Name-Value Arguments

    collapse all

    Specify optional pairs of arguments as Name1=Value1,...,NameN=ValueN, where Name is the argument name and Value is the corresponding value. Name-value arguments must appear after other arguments, but the order of the pairs does not matter.

    Example: addCustomMetric(meritFcn,@myMetric,Target=0.5) specifies a target metric value of 0.5.

    Target metric value, specified as a nonnegative scalar or a 1-by-2 nonnegative vector. If you specify this argument as a scalar, the object considers the target metric as the upper or lower bound, depending on the function. If you specify this argument as a 1-by-2 vector, the object considers the first element the lower bound and the second element the upper bound.

    Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    Metric weight in the overall merit function, specified as a positive scalar. The opticalMeritFunction object normalizes all weights to sum to 1 when computing the combined merit score.

    Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    Metric name, specified as a string scalar or character vector.

    Data Types: char | string

    Output Arguments

    collapse all

    Updated merit function, returned as an opticalMeritFunction object with the custom metric appended.

    Version History

    Introduced in R2026b