Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Funcer 12. 01. 2016, 15:21:13

Název: Generická matice
Přispěvatel: Funcer 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).
Název: Re:Generická matice
Přispěvatel: Daniel Kozak 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
Název: Re:Generická matice
Přispěvatel: zboj 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é.
Název: Re:Generická matice
Přispěvatel: ADSADssdfasdfas 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. 
Název: Re:Generická matice
Přispěvatel: kukacka 12. 01. 2016, 16:25:56
Napr. v jave by slo takoveho efektu (staticka kontrola na vice moznych typu) dosahnout pomoci priznakoveho interfacu.
Název: Re:Generická matice
Přispěvatel: Ondra Satai Nekola 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.

Název: Re:Generická matice
Přispěvatel: Tomas__ 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
Název: Re:Generická matice
Přispěvatel: mrazik 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.
Název: Re:Generická matice
Přispěvatel: zboj 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.
Název: Re:Generická matice
Přispěvatel: zboj 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.
Název: Re:Generická matice
Přispěvatel: zboj 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.
Název: Re:Generická matice
Přispěvatel: gamer 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.
Název: Re:Generická matice
Přispěvatel: zboj 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 :)
Název: Re:Generická matice
Přispěvatel: helenka z rise divu 15. 01. 2016, 01:19:14
Prvne si ji transponuj a potom generalizuj na -1 bazi.
Název: Re:Generická matice
Přispěvatel: Tomas__ 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.