Giter Site home page Giter Site logo

Flags feature discussion / request about linalg HOT 4 OPEN

KCErb avatar KCErb commented on June 8, 2024
Flags feature discussion / request

from linalg.

Comments (4)

konovod avatar konovod commented on June 8, 2024
  1. With current design you can do
require "linalg"

m = LA::GMat[[3, -2],[4, -1]]
vals, vecs = m.eigs

res = vecs.inv * m * vecs
res.detect(MatrixFlags::UpperTriangular | MatrixFlags::LowerTriangular)

This checks only flags you passed and returns true if all flags are set. Well, it's still more verbose than your suggestion because of Enum syntax in Crystal. It's not named detect? because yes, it does not only returns result but also caches it in a matrix.
detect checks all flags and this can be slow (PositiveDefinite involves decomposition and Orthogonal involves multiplication). (I've no idea whether it is important though, maybe it doesn't matter).

That said, I agree that your idea is better - detect could be useful in chained expressions, and if someone cares about speed he can pass required flags.

  1. This looks very nice!
    We still can't forward all methods (using forward_missing_to) because there are some helpers, but it's not a problem to specify methods manually.

from linalg.

KCErb avatar KCErb commented on June 8, 2024

I hadn't thought of the performance cost for some of those flag checks, that's a very good point.

In my specific use case all I really care about is the diagonal? method, perhaps the better solution is to give Mat a diagonal? method which checks for the flag, and in its absence runs a detect.

That sort of pattern is probably extensible to other flags.

As for detect? being mutating, the side effect is completely harmless right? If a matrix possesses the property in question, there can't be any harm in that being noted in the flags. So it seems acceptable to me. Though I imagine for my use case, where I was only calling detect because I wanted the side effects, the more idiomatic would be detect!.

Given all of that, I think I'd personally like

mat.detect!(flags = LA::MatrixFlags::All) for modifying the matrix, this returns the matrix.

mat.diagonal? for specifically checking and setting one flag

and

mat.detect?(flag : LA::MatrixFlags) for checking for a flag, setting it if available, and returning a boolean.

What do you think? Too much?

from linalg.

konovod avatar konovod commented on June 8, 2024

Checking and detecting won't work in current state, because only "positive" result is cached. That is: if detect sees that matrix is diagonal, it sets the "diagonal" flag (and further operations will take it into account). But there is no "non-diagonal" flag, so for a non-diagonal matrix it will check diagonality with every call of diagonal?. Perhaps the system should be modified to include negative results though - mat.diagonal? without it is just misleading (flags.diagonal? can return false on diagonal matrix if we forgot to call detect).

As for detect! vs detect - there is also assume!(flag) - unsafe method, for setting a flag without check (when you know that it is present and don't want to waste time to check). So i decided to name detect without ! for a contrast.

So to summarize: currently present detect should be renamed to detect?, detect (or detect!) should return a matrix for chaining, and mat.diagonal? is very nice, but requires changing flags system, so it will take some time.

from linalg.

KCErb avatar KCErb commented on June 8, 2024

I'd be fine with not having a "negative flag". It makes sense to me that each call of diagonal? would have to actually look through the matrix for entries if the flag is not already there. In general, I'd expect any flag operation to have to actually introspect on the matrix because you only have two states "I'm sure the matrix has this property" and "I'm not sure". I like the simplicity.

The more complex situation is a 3 state matrix for each flag "definitely yes, definitely no, unsure". But then I don't feel like enum's are the right pattern, or they could be, but you'd have a new set of flags for each property.

The only way we could have a two state "definitely yes, definitely no" would be if we were actually calculating all flags on every operation which is obviously not a great idea.

So I agree with most of what you said, but don't see the need to rework flags ... but that's just my two cents :)

from linalg.

Related Issues (13)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.