def setup_objective(obj, free_variables, on_step=None, disp=True, make_dense=False):
    '''
    obj here can be a list of ch objects or a dict of label: ch objects. Either way, the ch
    objects will be merged into one objective using a ChInputsStacked. The labels are just used
    for printing out values per objective with each iteration. If make_dense is True, the
    resulting object with return a desne Jacobian
    '''
    # Validate free variables
    num_unique_ids = len(np.unique(np.array([id(freevar) for freevar in free_variables])))
    if num_unique_ids != len(free_variables):
        raise Exception('The "free_variables" param contains duplicate variables.')
    # Extract labels
    labels = {}
    if isinstance(obj, list) or isinstance(obj, tuple):
        obj = ch.concatenate([f.ravel() for f in obj])
    elif isinstance(obj, dict):
        labels = obj
        obj = ch.concatenate([f.ravel() for f in list(obj.values())])
    # build objective
    x = np.concatenate([freevar.r.ravel() for freevar in free_variables])
    obj = ChInputsStacked(obj=obj, free_variables=free_variables, x=x, make_dense=make_dense)
    # build callback
    def callback():
        if on_step is not None:
            on_step(obj)
        if disp:
            report_line = ['%.2e' % (np.sum(obj.r**2),)]
            for label, objective in sorted(list(labels.items()), key=lambda x: x[0]):
                report_line.append('%s: %.2e' % (label, np.sum(objective.r**2)))
            report_line = " | ".join(report_line) + '\n'
            sys.stderr.write(report_line)
    return obj, callback
def setup_objective ( obj , free_variables , on_step = None , disp = True , make_dense = False ) : num_unique_ids = len ( np . unique ( np . array ( [ id ( freevar ) for freevar in free_variables ] ) ) ) if num_unique_ids != len ( free_variables ) : raise Exception ( 'The "free_variables" param contains duplicate variables.' ) labels = { } if isinstance ( obj , list ) or isinstance ( obj , tuple ) : obj = ch . concatenate ( [ f . ravel ( ) for f in obj ] ) elif isinstance ( obj , dict ) : labels = obj obj = ch . concatenate ( [ f . ravel ( ) for f in list ( obj . values ( ) ) ] ) x = np . concatenate ( [ freevar . r . ravel ( ) for freevar in free_variables ] ) obj = ChInputsStacked ( obj = obj , free_variables = free_variables , x = x , make_dense = make_dense ) def callback ( ) : if on_step is not None : on_step ( obj ) if disp : report_line = [ '%.2e' % ( np . sum ( obj . r ** 2 ) , ) ] for label , objective in sorted ( list ( labels . items ( ) ) , key = lambda x : x [ 0 ] ) : report_line . append ( '%s: %.2e' % ( label , np . sum ( objective . r ** 2 ) ) ) report_line = " | " . join ( report_line ) + '\n' sys . stderr . write ( report_line ) return obj , callback
obj here can be a list of ch objects or a dict of label: ch objects. Either way, the ch
    objects will be merged into one objective using a ChInputsStacked. The labels are just used
    for printing out values per objective with each iteration. If make_dense is True, the
    resulting object with return a desne Jacobian