Generická matice

Funcer

Generická matice
« kdy: 12. 01. 2016, 15:21:13 »
Jde ve staticky typovaném jazyce implementovat matice s generickými prvky? Pokud ano, jak?
Např. v C++ bych mohl mít Matrix<double> nebo Matrix<Vector>, ale mně jde o to, aby v jedné matici mohly být prvky různých typů při zachování statické kontroly. Příkladem budiž třeba výpočet vektorového součinu pomocí determinantu (matice obsahuje vektory i skaláry a výsledkem je vektor).


Daniel Kozak

Re:Generická matice
« Odpověď #1 kdy: 12. 01. 2016, 15:44:19 »
Jde ve staticky typovaném jazyce implementovat matice s generickými prvky? Pokud ano, jak?
Např. v C++ bych mohl mít Matrix<double> nebo Matrix<Vector>, ale mně jde o to, aby v jedné matici mohly být prvky různých typů při zachování statické kontroly. Příkladem budiž třeba výpočet vektorového součinu pomocí determinantu (matice obsahuje vektory i skaláry a výsledkem je vektor).

Tak napada me jedine nejakej typ co by to zabalil, neco jako Variant v Decku:

http://dlang.org/phobos/std_variant.html

Pripadne vyuzit union, to by taky mohlo jit nejak slepit

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Generická matice
« Odpověď #2 kdy: 12. 01. 2016, 15:54:26 »
Jde ve staticky typovaném jazyce implementovat matice s generickými prvky? Pokud ano, jak?
Např. v C++ bych mohl mít Matrix<double> nebo Matrix<Vector>, ale mně jde o to, aby v jedné matici mohly být prvky různých typů při zachování statické kontroly. Příkladem budiž třeba výpočet vektorového součinu pomocí determinantu (matice obsahuje vektory i skaláry a výsledkem je vektor).

Tak napada me jedine nejakej typ co by to zabalil, neco jako Variant v Decku:

http://dlang.org/phobos/std_variant.html

Pripadne vyuzit union, to by taky mohlo jit nejak slepit
To by ale už nebylo staticky typované.

ADSADssdfasdfas

Re:Generická matice
« Odpověď #3 kdy: 12. 01. 2016, 16:17:50 »
pokud to je matice co muze mit i svoje prvky matice, tak bych za predpokladu, ze vnorene prvky matice uz budou normalni doubly,
Matice<Matice<double>>

kazdy prvek Matice je Matice<double>, v Matice<double> pak je ulozen jen double jako matice[1][1] nebo jina Matice. 

kukacka

Re:Generická matice
« Odpověď #4 kdy: 12. 01. 2016, 16:25:56 »
Napr. v jave by slo takoveho efektu (staticka kontrola na vice moznych typu) dosahnout pomoci priznakoveho interfacu.


Re:Generická matice
« Odpověď #5 kdy: 12. 01. 2016, 16:27:27 »
type Vec = Vector Double
type Member = Either Double Vec

a to, co chces je Matrix Member

Jen pak musis resit, zda se ti potkavaji lefty nebo righty... Typove bezpecne to je.

Jina otazka je, zda zrovna neco takoveho je idealni reprezentace pro numeriku.


Tomas__

Re:Generická matice
« Odpověď #6 kdy: 12. 01. 2016, 17:04:19 »
Matrix<std::pair<double, std::vector<double>*> matrix; // nebo nejakej auto pointer, nebo custom pair

if (matrix.get(x, y).second == NULL) //scalar
else //vector

mrazik

Re:Generická matice
« Odpověď #7 kdy: 12. 01. 2016, 19:19:56 »
Pokud jde o vektorový součin, řešil bych to čistěji - Matrix zobecnit na Tenzor, zavést Levi-Civitův pseudotenzor (permutační symbol) a dále pak počítat dle pravidel tenzorového počtu. Patrně podobně by šly řešit i jiné problémy.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Generická matice
« Odpověď #8 kdy: 12. 01. 2016, 21:29:45 »
Matrix<std::pair<double, std::vector<double>*> matrix; // nebo nejakej auto pointer, nebo custom pair

if (matrix.get(x, y).second == NULL) //scalar
else //vector
Tak tohle je hodně blbej nápad.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Generická matice
« Odpověď #9 kdy: 12. 01. 2016, 21:31:20 »
Pokud jde o vektorový součin, řešil bych to čistěji - Matrix zobecnit na Tenzor, zavést Levi-Civitův pseudotenzor (permutační symbol) a dále pak počítat dle pravidel tenzorového počtu. Patrně podobně by šly řešit i jiné problémy.
Na to se nikdo neptal.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Generická matice
« Odpověď #10 kdy: 12. 01. 2016, 21:33:41 »
Jde ve staticky typovaném jazyce implementovat matice s generickými prvky? Pokud ano, jak?
Např. v C++ bych mohl mít Matrix<double> nebo Matrix<Vector>, ale mně jde o to, aby v jedné matici mohly být prvky různých typů při zachování statické kontroly. Příkladem budiž třeba výpočet vektorového součinu pomocí determinantu (matice obsahuje vektory i skaláry a výsledkem je vektor).
Ono to je "abuse of notation", ale samozřejmě to jde, stačí mít protokol MatrixElementType a k němu potřebné operace. Potom v čase překladu lze generovat specializovaný kód.

gamer

Re:Generická matice
« Odpověď #11 kdy: 13. 01. 2016, 05:09:09 »
Nejvíc se tomu co chceš blíží asi boost::variant:

http://www.boost.org/doc/libs/1_60_0/doc/html/variant.html

boost::apply_visitor je compile time type safe, boost::get má runtime check.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Generická matice
« Odpověď #12 kdy: 15. 01. 2016, 00:24:42 »
Jde ve staticky typovaném jazyce implementovat matice s generickými prvky? Pokud ano, jak?
Např. v C++ bych mohl mít Matrix<double> nebo Matrix<Vector>, ale mně jde o to, aby v jedné matici mohly být prvky různých typů při zachování statické kontroly. Příkladem budiž třeba výpočet vektorového součinu pomocí determinantu (matice obsahuje vektory i skaláry a výsledkem je vektor).

Let's take any language, say, Swift (pun intended) :)

Kód: [Vybrat]
protocol MatrixElementType {
    func +(x:MatrixElementType, y:MatrixElementType) -> MatrixElementType
    func *(x:MatrixElementType, y:MatrixElementType) -> MatrixElementType
}

extension Double : MatrixElementType {}

struct Vector : MatrixElementType {
    let data:[Double]
    var dimension:Int { return data.count }
}

struct Matrix {
    let data:[MatrixElementType]
    let dimension:Int
    init(data:[MatrixElementType]) { self.data = data; dimension = Math.sqrt(data.count) }
    subscript(index:(row:Int,column:Int)) -> MatrixElementType {
        get { return data[index.row * dimension + index.column] }
    }
    func firstMinor(row row:Int, column:Int) -> MatrixElementType {
        ...
    }
    var determinant:MatrixElementType {
        if dimension == 1 { return data[0] }
        else {
            ...
        }
    }
}

let m = Matrix(data: [ Vector(data: [ 1, 0, 0 ]), Vector(data: [ 0, 1, 0 ]), Vector(data: [ 0, 0, 1 ]), 2, 0, 0, 0, 2, 0 ])
print(m)
print(m.determinant)

Po přepsání tento kód funguje v každém jazyce s šablonami a přetěžováním operátorů, jen vypadá hnusněji. To zadání by bylo hezký příklad ke zkoušce :)

helenka z rise divu

Re:Generická matice
« Odpověď #13 kdy: 15. 01. 2016, 01:19:14 »
Prvne si ji transponuj a potom generalizuj na -1 bazi.

Tomas__

Re:Generická matice
« Odpověď #14 kdy: 15. 01. 2016, 08:32:26 »
Matrix<std::pair<double, std::vector<double>*> matrix; // nebo nejakej auto pointer, nebo custom pair

if (matrix.get(x, y).second == NULL) //scalar
else //vector
Tak tohle je hodně blbej nápad.
Slo o princip ten pair je takovej "variant". Spis mi jde o to, ze variant (ala union) je lepsi nez "any" a nez dedicnost. Nejak si to obecne nedokazu predstavit. Operator * vzdy musi vedet co je na obou stranach, takze stejne skoncis u spousty ifu. Krom toho by bylo potreba virtualni tridy/metory, ktere optimalizator neumi inlinovat a trosku to pak templatam podrazi nohy.