Skip to content
This repository was archived by the owner on Nov 23, 2018. It is now read-only.
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions printer.go → recorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package optimize

import (
"encoding/json"
"fmt"
"io"
"math"
Expand Down Expand Up @@ -104,3 +105,72 @@ func (p *Printer) Record(loc *Location, op Operation, stats *Stats) error {
p.lastValue = time.Now()
return nil
}

// Full Recorder records all of the evaluations that occur during an optimization
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a justification why this should be in optimize? The functionality seems quite specific to fit general needs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems specific? In what way? It seems like a natural counterpart to Printer. Printer prints to a writer to track optimization, this saves the optimization run to json for retrospection

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about what is being recorded and into what format. I can imagine that either will easily not fit the needs and the user will write it's own recorder.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FullRecorder

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your point about things being Ored and this not handling that properly. Do you have other suggestions for making it more general? It seems reasonable to me to provide some built-in way to store the history of the optimization for retrospection (in addition to the human-friendly printing we have now).

// run. If Operation is an Evaulation, FullRecorder records the x location and
// the corresponding field of Location. If Operation is a MajorIteration, or
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

field or fields

// PostIteration, FullRecorder records the full value of the Location struct.
// Otherwise, FullRecorder records the operation type.
type FullRecorder struct {
Writer io.Writer
}

func (f FullRecorder) Init() error {
return nil
}

func (f FullRecorder) Record(loc *Location, op Operation, stats *Stats) error {
r := RecordLocation{Op: op.String()}
switch {
case op.isEvaluation():
r.Loc.X = loc.X
switch op {
default:
panic("optimize: unknown evaluation operation")
case FuncEvaluation:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Evaluation operations can be ORed together which this switch does not take into account.

r.Loc.F = loc.F
case GradEvaluation:
r.Loc.Gradient = loc.Gradient
case HessEvaluation:
r.Loc.Hessian = loc.Hessian
}
case op == MajorIteration || op == PostIteration:
r.Loc = *loc
}
if op.isEvaluation() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A left-over before the above switch was introduced?


} else if op == MajorIteration {

}
b, err := json.MarshalIndent(r, "", "\t")
if err != nil {
return nil
}
_, err = f.Writer.Write(b)
return err
}

// Read reads the stream written to by FullRecorder, and returns the history of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

written to r ?

// the optimization run.
func (f FullRecorder) Read(r io.Reader) ([]RecordLocation, error) {
d := json.NewDecoder(r)
var records []RecordLocation
var err error
for {
var r RecordLocation
err = d.Decode(&r)
if err != nil {
break
}
records = append(records, r)
}
if err == io.EOF {
return records, nil
}
return records, err
}

type RecordLocation struct {
Op string
Loc Location
}