

//=====================================================
mwArray norepex(mwArray* pbestuewktmat,mwArray* pbestdist,mwArray anzahlelemente1,mwArray anzahlelemente2,mwArray signallaenge,mwArray wktstatus,mwArray whlstatus,mwArray whlspez,mwArray relmat,mwArray widmat)
{
mwArray bestreihe;

mwArray %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


//=====================================================
mwArray norepex(mwArray* pbestuewktmat,mwArray* pbestdist,mwArray anzahlelemente1,mwArray anzahlelemente2,mwArray signallaenge,mwArray 
{
mwArray bestreihe;
//          norepex(9,1,240,'n','x','n',[0.222 0.222 0.222 0.111 0.111 0.111],[0],'j')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     mwArray uewktmat;

     mwArray reihe;

     mwArray pbestuewktmat;

     mwArray bestdist;
global uewktmat reihe mtimes(bestreihe ,pbestuewktmat) bestdist

mwArray bestdiff;

mwArray distmat;

mwArray kriterium;

mwArray pbestdist;

mwArray punktzaehler;

mwArray sternzaehler;

mwArray bigpointzaehler;
bestdiff=100;bestreihe=empty();distmat=empty();kriterium=mtimes(20;,pbestdist)=1000;punktzaehler=1;sternzaehler=1;bigpointzaehler=0;

mwArray uematzaehler;
uematzaehler=1;

  mwArray <9;

     mwArray uewktoptstatus;
    uewktoptstatus="n" end

  mwArray <8;
    widmat=empty() end

   mwArray <7;
    relmat=empty() end

  mwArray <6;
    whlspez="n" end

  mwArray <5;
    whlstatus="0"end

  mwArray <4;
    wktstatus="j"end

  mwArray <3;
    signallaenge=empty();
    wktstatus=in)put("Gleichverteilte Wahrschein)lichkeiten)? (mrdivide(j,n))","s");
    whlstatus=input("Wiederholungen zulassen? (Anzahl bzw. "x" = beliebig)","s");
    whlspez=in)put("Beson)dere Wiederholun)gsoption)en)? (mrdivide(j,n))","s");
    uewktoptstatus=in)put("Übergan)gswahrschein)lichkeiten) optimieren)? (mrdivide(j,n))","s");
    kriterium=input("Abweichungssumme der absoluten Häufigkeiten?");

//Anzahl der Folgelemente (restanzahl) bestimmen
        while (1) {
    anzahlelemente1=input("anzahl verschiedener elemente in 1.Dimension?");

      mwArray anzahlelemente1>1;
    if (anzahlelemente1.ExtractScalar(1)>1) {
        break
    }
    else { 
        TRACE("Größer 1!!!");
    }
    }
    while (1) {
    anzahlelemente2=input("anzahl verschiedener elemente in 2.Dimension?");

      mwArray anzahlelemente2>0;
    if (anzahlelemente2.ExtractScalar(1)>0) {
        break
    }
    else { 
        TRACE("Größer 0!!!");
    }
    }
   
}
 

mwArray %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                                                                   mwArray 
                                    mwArray ohne;

                                    mwArray Wiederholung;

                                    mwArray gleichverteilt;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   mwArray |strcmp;
if (strcmp(wktstatus,"j") && (strcmp(whlstatus,"0")||strcmp(whlstatus,"n"))) {
 
 

mwArray anzahlelemente;
anzahlelemente=mtimes(anzahlelemente1,anzahlelemente2);
if (anzahlelemente1.ExtractScalar(1)==1) {

    mwArray restanzahl;
    restanzahl=(anzahlelemente2-1);
}
 else if ( anzahlelemente2.ExtractScalar(1)==1) {
    restanzahl=(anzahlelemente1-1);  
}
else {
    restanzahl=mtimes((anzahlelemente1-1),(anzahlelemente2-1));
}
 
//signallaenge abfragen
if (isempty(signallaenge).ExtractScalar(1)) {
    TRACE(horzcat("signallaenge muss ein gemeinsames Vielfaches von ",num2str(restanzahl)," und ",num2str(anzahlelemente)," sein!"));
    while (1) {
	signallaenge=input("signallänge?");
        if (rem(signallaenge,anzahlelemente).ExtractScalar(1)==0   &&    rem(signallaenge,restanzahl).ExtractScalar(1)==0) {
   	        break
	    }
    	else {
            TRACE(horzcat("signallaenge muss ein gemeinsames Vielfaches von ",num2str(restanzahl)," und ",num2str(anzahlelemente)," sein!"));
        }
    }
}
//koordinaten umrechnen

mwArray zaehlmat;
zaehlmat=(linspace(1,anzahlelemente1,anzahlelemente1))';

 mwArray q;
for (int q=2;q.ExtractScalar(1)<=anzahlelemente2.ExtractScalar(1);q++) {
   zaehlmat=horzcat(zaehlmat,(linspace(1,anzahlelemente1),anzahlelemente1))+mtimes((q-1),anzahlelemente1))');
}
//Folgeelementmatrix bestimmen (pro Zeile alle möglichen Folgeelemente auf Zeilennummer)

    mwArray alternativen;
    alternativen=zeros(anzahlelemente,restanzahl);

     mwArray dings;
    for (int dings=1;dings.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);dings++) {

        mwArray altindices;

        mwArray zaehlmat>0;
        altindices=(find(zaehlmat.ExtractScalar(1)>0))';

          mwArray gleichespalte;

          mwArray altindices>anzahlelemente1;

          mwArray altindices<;
        gleichespalte=find(and(mtimes(altindices.ExtractScalar(1)>anzahlelemente1.ExtractScalar(1).ExtractScalar(1),floor)(zaehlmat(mrdivide(dings),(anzahlelemente1.ExtractScalar(1)+0.00001)),altindices.ExtractScalar(1)<=anzahlelemente1.ExtractScalar(1)+anzahlelemente1.ExtractScalar(1),floor)(zaehlmat(mrdivide(dings),(anzahlelemente1.ExtractScalar(1)+0.00001))));  

        mwArray gleichezeile;
        gleichezeile=find(rem(altindices,anzahlelemente1).ExtractScalar(1)==rem(zaehlmat(dings),anzahlelemente1));

        mwArray anzahlspaltindices;
        anzahlspaltindices=size(gleichespalte);

        mwArray anzahlzeilindices;
        anzahlzeilindices=size(gleichezeile);

        mwArray equalindices;
        equalindices=zeros(anzahlspaltindices(2),anzahlzeilindices(2));
      

         mwArray t;
        for (int t=1;t.ExtractScalar(1)<=anzahlspaltindices.ExtractScalar(1)(2;t++);t++) {
             equalindices(t,colon())=(gleichespalte(t).ExtractScalar(1)==gleichezeile.ExtractScalar(1));
        }

        mwArray equalspaltindices;

        mwArray equalzeilindices;
        equalspaltindices =find(&equalzeilindices, equalindices.ExtractScalar(1)==1);
        gleichespalte(equalspaltindices)=empty();

         mwArray anzahlelemente1~;

         mwArray anzahlelemente2~;
        if (and(anzahlelemente1.ExtractScalar(1)!=1,anzahlelemente2.ExtractScalar(1)!=1)) {
            altindices(horzcat(gleichespalte,gleichezeile))=empty();
        }
         else if ( anzahlelemente1.ExtractScalar(1)==1) {
            altindices(gleichespalte)=empty();
        }
         else if ( anzahlelemente2.ExtractScalar(1)==1) {
            altindices(gleichezeile)=empty();
        }

         mwArray bums;
        for (int bums=1;bums.ExtractScalar(1)<=restanzahl.ExtractScalar(1);bums++) {
      	    alternativen(dings,bums)=zaehlmat(altindices(bums));
        }
        alternativen(dings,colon())=alternativen(dings,colon());
    }
//optimierungsmatritzen erstellen   

mwArray sumvec;
sumvec=zeros(1,anzahlelemente);

mwArray negeyemat;
negeyemat=-eye(anzahlelemente)+ones(anzahlelemente);

mwArray idvec;
idvec=zeros(1,anzahlelemente);
if (anzahlelemente2.ExtractScalar(1)==1) {

    mwArray erwartungswert;
    erwartungswert=mrdivide(signallaenge,(mtimes((anzahlelemente1),(anzahlelemente1-1))));

    mwArray erwartungsmat;
    erwartungsmat=mtimes(ones(anzahlelemente),erwartungswert);

     mwArray a;
    for (int a=1;a.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);a++) {
        erwartungsmat(a,a)=0;
    }
}
else {
    erwartungswert=mrdivide(signallaenge,(mtimes(anzahlelemente,restanzahl)));
    erwartungsmat=zeros(anzahlelemente);
    for (int a=1;a.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);a++) {

         mwArray b;
        for (int b=1;b.ExtractScalar(1)<=restanzahl.ExtractScalar(1);b++) {
        erwartungsmat(a,alternativen(a,b))=erwartungswert;
        }
    }
}
   
if (strcmp(uewktoptstatus,"n")) {
//Reihe mit choicemat und Folgematrix erstellen und anzahl prüfen bis anzahl gleichverteilt

mwArray intervall;
intervall=(mrdivide(signallaenge,restanzahl));

 mwArray <anzahlelemente;
while (sum(idvec).ExtractScalar(1)<anzahlelemente.ExtractScalar(1)) {
   

//choicemat erstellen (Reihe mit Nummer des Folgeelements (choicematwert ist Spaltenindex der Folgematrix)
        
         mwArray choicemat;
        choicemat=(randperm(signallaenge))'; 

         mwArray w;
        for (int w=1;w.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);w++) {

            mwArray indices;

            mwArray choicemat>intervall;

            mwArray choicemat<;
            indices=and(mtimes(choicemat.ExtractScalar(1)>intervall.ExtractScalar(1).ExtractScalar(1),(w-1),choicemat.ExtractScalar(1)<=intervall.ExtractScalar(1)+intervall.ExtractScalar(1),(w-1));
            choicemat(indices,1)=w;
        }
        

//anzahl der elemente in choicemat überprüfen
        
        mwArray choicematsumvec;
        choicematsumvec=zeros(1,restanzahl);

         mwArray n;
        for (int n=1;n.ExtractScalar(1)<=restanzahl.ExtractScalar(1);n++) {
            choicematsumvec(1,n.ExtractScalar(1))=sum(sum(choicemat.ExtractScalar(1)==n.ExtractScalar(1)));
        }
        

//reihe schreiben
                reihe=zeros(1,signallaenge);
        reihe(1,1)=choicemat(1,1);

         mwArray k;
        for (int k=2;k.ExtractScalar(1)<=signallaenge.ExtractScalar(1);k++) {
            reihe(1,k)=alternativen(reihe(1,k-1),choicemat(k,1));
        }

//anzahl überprüfen
                for (int n=1;n.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);n++) {
            sumvec(1,n.ExtractScalar(1))=sum(reihe.ExtractScalar(1)==n.ExtractScalar(1));
            idvec=(sumvec.ExtractScalar(1)(1,1).ExtractScalar(1)==sumvec.ExtractScalar(1));
        }
     
}
reihe=reihe';
//Uebergangswahrscheinlichkeiten

mwArray anzahlmat;
anzahlmat=zeros(signallaenge,anzahlelemente);

 mwArray u;
for (int u=1;u.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);u++) {
anzahlmat(colon(),u)=(u.ExtractScalar(1)==reihe.ExtractScalar(1)(colon(),1));
}	

mwArray anzahlvec;
anzahlvec=sum(anzahlmat);

mwArray equalvec;
equalvec=(anzahlvec.ExtractScalar(1)(1).ExtractScalar(1)==anzahlvec.ExtractScalar(1));
uewktmat=zeros(anzahlelemente);

 mwArray l;
for (int l=1;l.ExtractScalar(1)<=(signallaenge-1;l++);l++) {

    mwArray m;
   for (int m=1;m.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);m++) {
      for (int n=1;n.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);n++) {
         if (and(anzahlmat(l,m).ExtractScalar(1)==1,anzahlmat(l,m).ExtractScalar(1)==anzahlmat(l+1,n))) {
            uewktmat(m,n)=uewktmat(m,n)+1;
         }
      }
   }
}
}
 else if ( strcmp(uewktoptstatus,"j")) {

     mwArray pbestdist>kriterium;
while ( ,pbestdist.ExtractScalar(1)>kriterium.ExtractScalar(1))   ) {
    
//Reihe mit choicemat und Folgematrix erstellen und anzahl prüfen bis anzahl gleichverteilt
intervall=(mrdivide(signallaenge,restanzahl));
while (sum(idvec).ExtractScalar(1)<anzahlelemente.ExtractScalar(1)) {
   

//choicemat erstellen (Reihe mit Nummer des Folgeelements (choicematwert ist Spaltenindex der Folgematrix)
                choicemat=(randperm(signallaenge))'; 
        for (int w=1;w.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);w++) {
                indices=and(mtimes(choicemat.ExtractScalar(1)>intervall.ExtractScalar(1).ExtractScalar(1),(w-1),choicemat.ExtractScalar(1)<=intervall.ExtractScalar(1)+intervall.ExtractScalar(1),(w-1));
                choicemat(indices,1)=w;
        }
         

//anzahl der elemente in choicemat überprüfen
                choicematsumvec=zeros(1,restanzahl);
        for (int n=1;n.ExtractScalar(1)<=restanzahl.ExtractScalar(1);n++) {
            choicematsumvec(1,n.ExtractScalar(1))=sum(sum(choicemat.ExtractScalar(1)==n.ExtractScalar(1)));
        }
        

//reihe schreiben
                reihe=zeros(1,signallaenge);
        reihe(1,1)=choicemat(1,1);
        for (int k=2;k.ExtractScalar(1)<=signallaenge.ExtractScalar(1);k++) {
            reihe(1,k)=alternativen(reihe(1,k-1),choicemat(k,1));
        }

//anzahl überprüfen
                for (int n=1;n.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);n++) {
            sumvec(1,n.ExtractScalar(1))=sum(reihe.ExtractScalar(1)==n.ExtractScalar(1));
            idvec=(sumvec.ExtractScalar(1)(1,1).ExtractScalar(1)==sumvec.ExtractScalar(1));
        }
     
}
idvec=0;
reihe=reihe';
//Uebergangswahrscheinlichkeiten
anzahlmat=zeros(signallaenge,anzahlelemente);
for (int u=1;u.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);u++) {
anzahlmat(colon(),u)=(u.ExtractScalar(1)==reihe.ExtractScalar(1)(colon(),1));
}	
anzahlvec=sum(anzahlmat);
equalvec=(anzahlvec.ExtractScalar(1)(1).ExtractScalar(1)==anzahlvec.ExtractScalar(1));
uewktmat=zeros(anzahlelemente);
for (int l=1;l.ExtractScalar(1)<=(signallaenge-1;l++);l++) {
   for (int m=1;m.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);m++) {
      for (int n=1;n.ExtractScalar(1)<=anzahlelemente.ExtractScalar(1);n++) {
         if (and(anzahlmat(l,m).ExtractScalar(1)==1,anzahlmat(l,m).ExtractScalar(1)==anzahlmat(l+1,n))) {
            uewktmat(m,n)=uewktmat(m,n)+1;
         }
      }
   }
}
distmat=uewktmat-erwartungsmat;

mwArray dist;
dist=sum(sum(abs(distmat)));

 mwArray dist<;
if (mtimes(dist.ExtractScalar(1)<,pbestdist.ExtractScalar(1))) {
    ,pbestdist)=dist
    bestreihe=reihe;
    ,pbestuewktmat)=uewktmat
}
fprintf("*");
sternzaehler=sternzaehler+1;

 mwArray sternzaehler>20;
if (sternzaehler.ExtractScalar(1)>20) {
