Java 矩阵求逆算法在我的代码中不起作用

Java 矩阵求逆算法在我的代码中不起作用,java,matrix,matrix-multiplication,inverse,matrix-inverse,Java,Matrix,Matrix Multiplication,Inverse,Matrix Inverse,我和我的小组正在尝试创建一个桥梁模拟。为此,我们需要计算一个大矩阵的逆。所以我们得到了一个开源算法,在这个网站上测试后:http://www.arndt-bruenner.de/mathe/scripts/inversematrix.htm似乎工作正常。但当我们在程序中使用它时,它会返回奇怪的矩阵。问题似乎显而易见。它必须是未赋予函数权限的矩阵。所以我在函数中放了一些代码来打印到达那里的矩阵。这是绝对正确的,所以我们不知道问题出在哪里。然后我用一个非常大的矩阵再次测试了这个函数,而不是在我们的程

我和我的小组正在尝试创建一个桥梁模拟。为此,我们需要计算一个大矩阵的逆。所以我们得到了一个开源算法,在这个网站上测试后:
http://www.arndt-bruenner.de/mathe/scripts/inversematrix.htm
似乎工作正常。但当我们在程序中使用它时,它会返回奇怪的矩阵。问题似乎显而易见。它必须是未赋予函数权限的矩阵。所以我在函数中放了一些代码来打印到达那里的矩阵。这是绝对正确的,所以我们不知道问题出在哪里。然后我用一个非常大的矩阵再次测试了这个函数,而不是在我们的程序中,它再次正常工作,所以我感觉我们的程序和函数之间有一些奇怪的交互

函数的代码:

public static double[][] inverse_matrix(double[][]in){

    int st_vrs=in.length, st_stolp=in[0].length;
    double[][]out=new double[st_vrs][st_stolp];
    double[][]old=new double[st_vrs][st_stolp*2];
    double[][]neu=new double[st_vrs][st_stolp*2];


    for (int v=0;v<st_vrs;v++){//ones vector
        for (int s=0;s<st_stolp*2;s++){
            if (s-v==st_vrs) 
                old[v][s]=1;
            if(s<st_stolp)
                old[v][s]=in[v][s];
        }
    }
    //zeros below the diagonal
    for (int v=0;v<st_vrs;v++){
        for (int v1=0;v1<st_vrs;v1++){
            for (int s=0;s<st_stolp*2;s++){
                if (v==v1)
                    neu[v][s]=old[v][s]/old[v][v];
                else
                    neu[v1][s]=old[v1][s];
            }
        }
        old=prepisi(neu);       
        for (int v1=v+1;v1<st_vrs;v1++){
            for (int s=0;s<st_stolp*2;s++){
                neu[v1][s]=old[v1][s]-old[v][s]*old[v1][v];
            }
        }
        old=prepisi(neu);
    }
    //zeros above the diagonal
    for (int s=st_stolp-1;s>0;s--){
        for (int v=s-1;v>=0;v--){
            for (int s1=0;s1<st_stolp*2;s1++){
                neu[v][s1]=old[v][s1]-old[s][s1]*old[v][s];
            }
        }
        old=prepisi(neu);
    }
    for (int v=0;v<st_vrs;v++){//rigt part of matrix is invers
        for (int s=st_stolp;s<st_stolp*2;s++){
            out[v][s-st_stolp]=neu[v][s];
        }
    }
    return out;
}

static double[][] prepisi(double[][]in){
    double[][]out=new double[in.length][in[0].length];
    for(int v=0;v<in.length;v++){
        for (int s=0;s<in[0].length;s++){
            out[v][s]=in[v][s];
        }
    }
    return out;
}
公共静态双[][]逆矩阵(双[][]英寸){
int st_vrs=in.length,st_stolp=in[0]。长度;
double[]out=新的double[st_vrs][st_stolp];
双倍[][]旧=新双倍[st_vrs][st_stolp*2];
double[]neu=新的double[st_vrs][st_stolp*2];

对于(int v=0;vcan你能提供一个SSCCE吗?同样,不相关,但代码效率很低。尝试使用完整的矩阵库,例如,并编写100次算法!它有阿拉伯词根,而不是希腊词根…@zmo:事实上,“al-gibr”一书的作者是波斯词根,来自一个宗教团体(和城市?),名称类似于Khoresm,在波斯。@user3696463:请仔细检查您的任务是否真的需要矩阵求逆。在几乎所有情况下,所需要的是用该矩阵求解线性系统,对于这一点,像PLU或QR这样的矩阵分解就完全足够了。
  public class SimulationFenster extends JFrame{


int fe_anzahl;
double brueckenlaenge;
double hoehe;
double breite;
double flaeche;
double material;
double[][] kraftvektor;
double[][] steifigkeitsmatrix;
double[][] gesamtsteifigkeitsmatrix;
double[][] ergebnisvektor;

double fe_laengepixel;
double fe_laengereal;

JButton einstellungen;
JButton zurueck;
Zeichnen zeich;

double[] xKoordinaten;
double[] yKoordinaten;
Schnittpunkt[] punkte;

double scale;
Icon hintergrund=new ImageIcon(getClass().getResource("hintergrund.png"));

public SimulationFenster(int fe_anzahl,double brueckenlaenge,double breite,double hoehe,double material,double[][] kvektor){
    fe_anzahl++;
    this.fe_anzahl=fe_anzahl;
    this.brueckenlaenge=brueckenlaenge;
    this.hoehe=hoehe;
    this.breite=breite;
    this.material=material;
    this.kraftvektor=kvektor;
    this.flaeche=hoehe*breite;

    xKoordinaten=new double[this.fe_anzahl];
    yKoordinaten=new double[this.fe_anzahl];

    punkte=new Schnittpunkt[fe_anzahl];
    for(int i=0;i<fe_anzahl;i++){
        punkte[i]=new Schnittpunkt();
    }
    fe_laengepixel=410.0/(fe_anzahl-1);

    fe_laengereal=brueckenlaenge/(fe_anzahl-1);
    scale=1.0;

    double E=material;
    double A=breite*hoehe;
    double I=breite*Math.pow(hoehe, 3)/12;
    double L=fe_laengereal;
    steifigkeitsmatrix=new double[][]{
            { E*A/L,                     0,                   0,-E*A/L,                    0,                   0},
            {      0, 12*E*I/Math.pow(L,3),-6*E*I/Math.pow(L,2),     0,-12*E*I/Math.pow(L,3),-6*E*I/Math.pow(L,2)},
            {      0, -6*E*I/Math.pow(L,2),             4*E*I/L,     0,  6*E*I/Math.pow(L,2),             2*E*I/L},
            {-E*A/L,                     0,                   0, E*A/L,                    0,                   0},
            {      0,-12*E*I/Math.pow(L,3), 6*E*I/Math.pow(L,2),     0, 12*E*I/Math.pow(L,3), 6*E*I/Math.pow(L,2)},
            {      0, -6*E*I/Math.pow(L,2),             2*E*I/L,     0,  6*E*I/Math.pow(L,2),             4*E*I/L}};
    gesamtsteifigkeitsmatrix=new double[3*fe_anzahl][3*fe_anzahl];
    for(int i=0;i<fe_anzahl-1;i++){
        for(int j=3*i;j<3*i+6;j++){
            for(int k=3*i;k<3*i+6;k++){
                gesamtsteifigkeitsmatrix[j][k]=gesamtsteifigkeitsmatrix[j][k]+steifigkeitsmatrix[j%6][k%6];
            }
        }
    }

    gesamtsteifigkeitsmatrix=streichen(gesamtsteifigkeitsmatrix,0);//FEHLER vermutet
    gesamtsteifigkeitsmatrix=streichen(gesamtsteifigkeitsmatrix,0);//FEHLER vermutet
    gesamtsteifigkeitsmatrix=streichen(gesamtsteifigkeitsmatrix,gesamtsteifigkeitsmatrix.length-2);//FEHLER vermutet
    gesamtsteifigkeitsmatrix=streichen(gesamtsteifigkeitsmatrix,gesamtsteifigkeitsmatrix.length-2);//FEHLER vermutet
    kraftvektor=streichen(kraftvektor,0);//FEHLER vermutet
    kraftvektor=streichen(kraftvektor,0);//FEHLER vermutet
    kraftvektor=streichen(kraftvektor,kraftvektor.length-2);//FEHLER vermutet
    kraftvektor=streichen(kraftvektor,kraftvektor.length-2);//FEHLER vermutet



    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    setSize(500,500);
    setLocationRelativeTo(null);
    setTitle("Brückensimulation");
    setResizable(false);
    setVisible(true);
    setLayout(null);
    addWindowListener(new WindowHandler());
    addMouseMotionListener(new MouseHandler());
    addMouseListener(new MouseHandler());

    zeich=new Zeichnen();
    zeich.setBounds(0, 0, 500, 500);
    add(zeich);

    einstellungen=new JButton("Einstellungen ändern");
    einstellungen.addActionListener(new ButtonHandler());
    einstellungen.setBounds(40,437,190,30);
    add(einstellungen);

    zurueck=new JButton("Zurück");
    zurueck.addActionListener(new ButtonHandler());
    zurueck.setBounds(260,437,190,30);
    add(zurueck);


}
double[][] streichen(double[][] m,int linie){
    double[][] t;
    if(m.length==1){
        t=new double[m.length][m[0].length-1];
    }else if(m[0].length==1){
        t=new double[m.length-1][m[0].length];
    }else{
        t=new double[m.length-1][m[0].length-1];
    }

    for(int i=0;i<m.length;i++){
        for(int j=0;j<m[0].length;j++){
            if(i!=linie&&j!=linie){
                int a=i,b=j;
                if(i>linie){
                    a=i-1;
                }
                if(j>linie){
                    b=j-1;
                }
                t[a][b]=m[i][j];
            }
        }
    }
    return t;
}

private class Zeichnen extends JLabel{
    /**
     * 
     */
    private static final long serialVersionUID = -138735436009377046L;
    @Override
    protected void paintComponent(Graphics g){
        Graphics2D graphics=(Graphics2D)g;
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        hintergrund.paintIcon(this,graphics,-200,-50);

        ergebnisvektor=Hauptprogramm.multiplyMatrices(Hauptprogramm.inverse_matrix(gesamtsteifigkeitsmatrix),kraftvektor);//FEHLER vermutet

        for(int i=1;i<kraftvektor.length/3+1;i++){
            punkte[i].setGewicht(ergebnisvektor[3*i-1][0]);
        }
        for(int i=0;i<fe_anzahl;i++){
            xKoordinaten[i]=fe_laengepixel*i+40;
            yKoordinaten[i]=punkte[i].getGewicht()*scale+200;
        }
        rescale();
        for(int i=0;i<fe_anzahl;i++){ 
            if(i>=1){                   
                graphics.drawLine((int)xKoordinaten[i-1],(int)yKoordinaten[i-1],(int)xKoordinaten[i],(int)yKoordinaten[i]);
            }
        }
        for(int i=0;i<fe_anzahl;i++){
            if(i==0||i==fe_anzahl-1){
                graphics.setColor(Color.GRAY);
            }else{
                graphics.setColor(Color.BLACK);
            }
            graphics.fillOval((int)xKoordinaten[i]-5,(int)yKoordinaten[i]-5,10,10);
        }
        graphics.setColor(Color.BLACK);

        graphics.drawLine(0, 430, 500, 430);//Trennlinie

        graphics.drawLine(450-(int)fe_laengepixel, 415, 450, 415);//Maßstab x
        graphics.fillRect(450-(int)fe_laengepixel, 410, 2, 10);
        graphics.fillRect(450, 410, 2, 10);
        graphics.drawString(new Double(Math.round(fe_laengereal*1000)/1000.0).toString()+"m",450-(int)fe_laengepixel+10 , 410);

        graphics.drawLine(475, 200, 475, 410);//Maßstab y
        graphics.fillRect(470, 200, 10, 2);
        graphics.fillRect(470, 410, 10, 2);
        double k=Double.MIN_VALUE;
        for(double i:yKoordinaten){
            if(i>k){
                k=i;
            }
        }
        k-=200;
        graphics.drawString(new Double(Math.round(k/scale*1000)/1000.0).toString()+"m",430 ,345);
    }
    public Point getPolylinePoint(int i){
        return new Point((int)xKoordinaten[i]+2,(int)yKoordinaten[i]+26);
    }
    void rescale(){
        double k=Double.MIN_VALUE;
        for(double i:yKoordinaten){
            if(i>k){
                k=i;
            }
        }
        k-=200;
        for(int i=0;i<yKoordinaten.length;i++){
            if(k!=0){
                scale=200/k;
                yKoordinaten[i]=(int)((yKoordinaten[i]-200)*scale+200);
            }
        }
    }

}
private class ButtonHandler implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource()==einstellungen){
            new EinstellungenDialog(SimulationFenster.this);
        }else if( e.getSource()==zurueck){
            SimulationFenster.this.dispose();
            new MenuFenster();
        }
    }

}
private class WindowHandler implements WindowListener{

    @Override
    public void windowActivated(WindowEvent e) {}

    @Override
    public void windowClosed(WindowEvent e) {}

    @Override
    public void windowClosing(WindowEvent e) {
        SimulationFenster.this.dispose();
        new MenuFenster();
    }

    @Override
    public void windowDeactivated(WindowEvent e) {}

    @Override
    public void windowDeiconified(WindowEvent e) {}

    @Override
    public void windowIconified(WindowEvent e) {}

    @Override
    public void windowOpened(WindowEvent e) {}

}
private class MouseHandler implements MouseInputListener{
    //MouseMotionListener
    @Override
    public void mouseDragged(MouseEvent e) {}

    @Override
    public void mouseMoved(MouseEvent e) {
        boolean anyif=false;    
        for(int i=1;i<fe_anzahl-1;i++){
            if(e.getPoint().distance(zeich.getPolylinePoint(i))<5){
                setCursor(new Cursor(Cursor.HAND_CURSOR));
                anyif=true;
            }
        }
        if(!anyif){
            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
        }
    }
    //MouseListener
    @Override
    public void mouseClicked(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}

    @Override
    public void mousePressed(MouseEvent e) {
        for(int i=1;i<fe_anzahl-1;i++){
            if(e.getPoint().distance(zeich.getPolylinePoint(i))<5){
                new FiniteElementeDialog(SimulationFenster.this,i,kraftvektor);
                repaint();
                break;
            }
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {}
}