Generated reference › API — ICoreBlocks/ICoreMath
kind: generated#api#icoreblocks-icoremath

API — ICoreBlocks/ICoreMath

The public contract of 3 header(s) under src/ICoreBlocks/ICoreMath — 3 class/struct definition(s), 29 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.

ICoreExpressionEvaluator.h#

src/ICoreBlocks/ICoreMath/ICoreExpressionEvaluator.h

ICoreValue#

ICoreExpressionEvaluator.h:23 · struct · 13 declaration(s)

A console value: a matrix (scalars are 1x1 matrices), a polynomial, a transfer function, a state-space model, or a recorded time series.

struct ICoreValue {
public:
    // Str exists only so a quoted string literal can be carried through the
    // parser as a function argument (e.g. gradient("expr", x0)) -- it has no
    // arithmetic operators defined on it, unlike the other kinds.
    //
    // TimeSeries likewise has no arithmetic: it is a container to be opened with
    // .time() / .values(), not a term to compute with.
    //
    // Complex is a SEPARATE kind rather than a flag on the matrix, because
    // MATLAB's own rule is about the value and not about the storage:
    // `isreal(complex(3, 0))` is false while `isreal(1i * 1i)` is true, so a
    // result narrows back to Matrix exactly when no element has a non-zero
    // imaginary part -- everywhere except complex(), which forces the kind.
    // `narrow()` below is the ONE place that rule is applied (C0.2, C5.47).
    //
    // Handle is MATLAB's function_handle (C2.8). Its VALUE is its own source
    // text -- `@(x) x.^2`, `@sin` -- which is what func2str answers and what
    // crosses the bridge, since MATLAB and the console spell a handle
    // identically. The two capture vectors beside it are the other half of
    // MATLAB's rule and are NOT part of the text: an anonymous function
    // captures every free name BY VALUE at the moment it is made, so
    // `a = 2; f = @(x) a*x; a = 5; f(3)` is 6 and not 15.
    //
    // Zpk is MATLAB's zero/pole/gain model (the toolbox board's T1.3,
    // T0.2 (5), X3), and it is a SEPARATE kind rather than a transfer
    // function printed differently for the reason T0.2 rejected exactly that:
    // MATLAB's zpk arithmetic answers a zpk, so `zpk([1], [2 3], 4) * 2` has
    // to still hand `zpkdata` back the roots that went in. The factored form
    // is the value; the transfer function is derived on demand
    // (ICoreZpk::toTransferFunction), and every reading a model answers goes
    // through that one path so a zpk cannot disagree with the tf it is.
    //
    // Fit is the Curve Fitting Toolbox's model and fitted model -- MATLAB's
    // `fittype` and `cfit` (the toolbox board's T0.8, T8.1, X3). ONE
    // kind for MATLAB's two classes, because MATLAB's own accessors do not
    // distinguish them: `coeffnames`, `formula`, `type`, `category`,
    // `numcoeffs`, `indepnames` and `dependnames` all answer for either, and
    // what a `cfit` adds is the DATA behind it -- coefficient values, the
    // residual statistics and the QR factor `confint` and `predint` read.
    // `ICoreCurveFit::isFitted()` is the difference.
    //
    // Sym is MATLAB's symbolic value (the toolbox board's T0.5 (A),
    // T4, X3): an expression carried AS an expression, over the console's own
    // tree in ICoreSymbolic. It is a kind rather than a string of text for
    // the reason every other kind here is one -- `diff(f)` has to differentiate
    // the expression, not re-parse a spelling of it -- and it holds a MATRIX
    // of expressions (1 x 1 for the ordinary case) because `jacobian` answers
    // a matrix and `factor` a row, and a second kind for that would be two
    // kinds for one thing.
    // Record is MATLAB's scalar struct, as much of one as T0.6 (A) admits: an
    // ORDERED, NAMED list of numeric fields read by `.name` and nothing else
    // (the toolbox board's T0.6, T1.17, T5.14, X3). It is a kind rather
    // than a struct kind precisely because of what it CANNOT do -- no field
    // assignment, no nesting, no non-double field -- which is what lets
    // `stepinfo`, `gof`, `output` and `lambda` answer something without
    // reopening the struct question C0.3 declined.
    //
    // ⚠ A record REMEMBERS the fields it refuses to hold, not just the ones it
    // holds (ICoreRecord::withhold). MATLAB's solver records carry `algorithm`
    // and `message` as character fields and fmincon's `bestfeasible` as a
    // nested struct; dropping those silently would answer "no such field" for
    // a name MATLAB does answer, which reads as a defect rather than as a
    // boundary. See ICoreRecord.h.
    enum class Kind { Matrix, Polynomial, Tf, Ss, Str, TimeSeries, Complex, Handle, Zpk, Fit, Sym, Record };

    Kind                  kind = Kind::Matrix;
    ICoreMatrix           matrix;
    ICoreComplexMatrix    complexMatrix;
    ICorePolynomial       poly;
    ICoreTransferFunction tf;
    ICoreStateSpace       ss;
    ICoreZpk              zpk;
    ICoreCurveFit         curveFit;
    ICoreSymbolic         symbolic;
    ICoreRecord           record;
    std::string           str;
    ICoreTimeSeries       series;

    // Handle only, and parallel: captureNames[k] was worth captureValues[k]
    // when the handle was made. Two vectors rather than one of pairs because
    // std::vector is the one container the standard lets hold an INCOMPLETE
    // type, and ICoreValue is incomplete inside its own definition -- a
    // std::pair of it is not allowed here, and a captured value is an
    // ordinary ICoreValue (a captured handle captures its own captures).
    std::vector<std::string> captureNames;
    std::vector<ICoreValue>  captureValues;

    // The six named constructors. Bodies in the .cpp, per the header surface
    // rule -- they were one-liners, and one-liners are not an exemption.
    static ICoreValue ofMatrix(const ICoreMatrix& m);
    static ICoreValue ofPoly(const ICorePolynomial& p);
    static ICoreValue ofTf(const ICoreTransferFunction& t);
    static ICoreValue ofSs(const ICoreStateSpace& s);
    static ICoreValue ofZpk(const ICoreZpk& z);
    static ICoreValue ofFit(const ICoreCurveFit& f);
    static ICoreValue ofSym(const ICoreSymbolic& s);
    static ICoreValue ofRecord(const ICoreRecord& r);
    static ICoreValue ofStr(const std::string& s);
    static ICoreValue ofSeries(const ICoreTimeSeries& s);
    // ofComplex() NARROWS: a complex matrix with no imaginary part anywhere
    // comes back as a Matrix, which is what makes `1i * 1i` answer a real -1
    // the way MATLAB's does. ofComplexForced() is the exception complex()
    // needs -- and it is the only caller that should ever want it.
    static ICoreValue ofComplex(const ICoreComplexMatrix& z);
    static ICoreValue ofComplexForced(const ICoreComplexMatrix& z);
    // The handle's source text, with no captures; the caller adds them. There
    // is no narrowing twin: a handle is never anything else.
    static ICoreValue ofHandle(const std::string& text);
};
};

ICoreExpressionEvaluator#

ICoreExpressionEvaluator.h:136 · class · nested Result, MultiResult, FunctionInfo · 3 declaration(s)

Evaluates expressions over matrices, polynomials, transfer functions and state-space models, with operator precedence, parentheses, and functions.

class ICoreExpressionEvaluator {
public:
    using VariableResolver = std::function<bool(const std::string& name, ICoreValue& out)>;

    struct Result {
        bool        ok = false;
        ICoreValue  value;
        std::string error;   // "No error" when ok
    };

    static Result evaluate(const std::string& expression, const VariableResolver& resolver);

    // MULTIPLE RETURN VALUES (the core-MATLAB board, C1.12 / decision C0.5).
    // `[a, b] = f(x)` is a STATEMENT, never a sub-expression, so this is a
    // second entry point rather than a mode of evaluate(): it parses one call
    // and asks it for `nargout` values. A function that has no such form
    // refuses by name rather than answering fewer values than were asked for,
    // because a statement that quietly filled only the first target would be
    // the one answer that cannot be right.
    struct MultiResult {
        bool                    ok = false;
        std::vector<ICoreValue> values;   // exactly nargout of them when ok
        std::string             error;    // "No error" when ok
    };
    static MultiResult evaluateMulti(const std::string& expression,
                                     const VariableResolver& resolver,
                                     size_t nargout);

    // Indexed assignment and deletion (the core-MATLAB row C1.11), for the
    // statement layer: it has already split `name(subscripts) = rhs`, and this
    // reads the subscripts with the same parser `A(...)` uses on the right-hand
    // side, so `end`, ranges and masks mean one thing in the language.
    //
    //   assignIndexed  answers the WHOLE new value of the name -- MATLAB's
    //                  growth included, so `y(3) = 5` on an undefined y (an
    //                  empty `target`) answers [0 0 5].
    //   deleteIndexed  is `A(...) = []`, which is not an assignment of a value
    //                  but a removal; the console has no empty matrix (C3.9),
    //                  so a deletion that empties its target is refused.
    static Result assignIndexed(const ICoreValue& target, const std::string& subscripts,
                                const ICoreValue& value, const VariableResolver& resolver);
    static Result deleteIndexed(const ICoreValue& target, const std::string& subscripts,
                                const VariableResolver& resolver);

    // A CALL THIS EVALUATOR DOES NOT IMPLEMENT — a function the console's own
    // language defines rather than this module (the core-MATLAB row C2.7,
    // and C2.8's handles after it). A script-defined function has a body made
    // of console STATEMENTS, which is the statement interpreter's business
    // (ICoreCoder, L6); this module is L4 and may not name it, so the call is
    // injected downward instead. Installed once at startup, consulted only
    // after every built-in has declined, so nothing here can be shadowed.
    //
    //   name     the function being called
    //   args     already-evaluated arguments
    //   nargout  how many values the CALLER asked for (1 for an expression)
    //   results  exactly nargout values when the call returns true and `error`
    //            is empty
    //   error    non-empty when the call was recognised and FAILED
    //
    // Returns false when the name is not one of these at all, which is what
    // lets "unknown function" stay the last word.
    using ExternalCall = std::function<bool(const std::string& name,
                                            const std::vector<ICoreValue>& args,
                                            size_t nargout,
                                            std::vector<ICoreValue>& results,
                                            std::string& error)>;
    static void setExternalCall(ExternalCall call);

    // Built-in functions — single source of truth for help/glossary and completion.
    struct FunctionInfo {
        std::string name;
        std::string signature;
        std::string description;
    };
    static std::vector<FunctionInfo> functions();
};
};

ICoreVariable.h#

src/ICoreBlocks/ICoreMath/ICoreVariable.h

Declared, defined in the .cpp: the residue below is a unique_ptr to an Impl this header cannot see, and only the .cpp can destroy one.

ICoreVariable#

ICoreVariable.h:7 · class · pImpl · 13 declaration(s)

class ICoreVariable {
public:
    explicit ICoreVariable(const std::string& initName, const std::string& initValue);

    void setName(const std::string& newName);
    virtual std::string setValue(const std::string& newValue);

    void assignType();

    std::string getName() const;
    std::string getValue() const;
    std::string getType() const;

    ICoreMatrix getAssociatedSyntraMatrix() const;

    std::pair<bool, long long> getCastedValueAsInteger() const;
    std::pair<bool, double> getCastedValueAsDouble() const;
    std::pair<bool, std::pair<std::vector<std::string>, std::string> > getCastedValueAsOptions() const;

    void resetToInitialState_BaseSyntraVariable(const std::string& initName, const std::string& initValue);

    // Declared, defined in the .cpp: the residue below is a unique_ptr to an
    // Impl this header cannot see, and only the .cpp can destroy one.
    virtual ~ICoreVariable();

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

eigen_pch.h#

src/ICoreBlocks/ICoreMath/eigen_pch.h

eigen_pch.h -- ICoreMath's Eigen umbrella.

The linear-algebra backbone behind ICoreMatrix and the numerics stack. Heavy to parse, which is why it is gathered here rather than repeated header by header at each use site.

This file used to be section 2 of the SDK-root src/ICoreBlocks/pch.h, which the ICoreBlocks target force-included into EVERY translation unit -- so all of src/ parsed Eigen whether it named a single Eigen type or not. In fact only ICoreMath does: the census finds Eigen tokens in nine files, every one of them under src/ICoreBlocks/ICoreMath/. That is MODULE_LAYERING.md M8's "Eigen moves into per-module PCHs" step, taken for the Eigen half; the std + ICoreEssentials half of the old pch.h is now delivered by ICoreEssentials/pch.h, which the ICoreBlocks target precompiles.

Declares no class of its own — see the file.