from sklearn.datasets import load_iris, load_wine, load_digits, load_digits
import sklearn
import numpy as np
import matplotlib.pyplot as plt
import sys
import operator
from sklearn.model_selection import train_test_split

class model:
        def __init__(self, lr=0.01):
                self.lr = lr

        def sigmoid_predict(self,X,W,i):
                G = []
                #print('x=',X)
                #print('W=',W)
                        
                for c in range(len(W)):
                        if len(X) == len(W[c]):
                                G.append(1/(1+np.exp(-np.dot(X,W[c]))))
                        else:
                                print("!!!!!!!ERROR!!!!!!!! ",len(X),'*',len(W[c]),":",i," array size is not same")
                                return [0,0,0,0,0,0,0,0,0,0]
#print('ggGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG',G)
                return G
        def sigmoid_XW(self,X,W):
#print(np.dot(X,W))
                return (1/(1+np.exp(-(0.01* np.dot(X,W)))))

        def loss_function(self,G,Y):
                loss = 0
                loss = (1-G[Y])
                return loss
        
        def accuracy(self,X,Y,W):
                count = 0
                for i in range(len(X)):
                        G = self.sigmoid_predict(X[i],W,i)
                        pre_index = max(enumerate(G),key=operator.itemgetter(1))
                        if pre_index[0] == Y[i]:
                                count += 1
                return count
        def train1(self,X,Y,W):
                loss = 0
#                print("Length X = ",len(X))
                for i in range(len(X)):
                        G = self.sigmoid_predict(X[i],W,i)
                        argcmaxG = max(enumerate(G),key=operator.itemgetter(1))
                        if argcmaxG[0] != Y[i]:
                                loss += self.loss_function(G,Y[i])
                                for c in range(len(W)):
                                        if Y[i] == c:
                                                Fxwc=self.sigmoid_XW(X[i],W[c])
                                                for f in range(len(X[i])):
                                                        W[c][f] = W[c][f] - (self.lr * (-1) * (G[c]) * (1-G[c])* X[i][f])
                return W,(loss*1000)

        def train2(self,X,Y,W):
                loss = 0
                for i in range(len(X)):
                        G = self.sigmoid_predict(X[i],W,i)
                        loss += self.loss_function(G,Y[i])
                        for c in range(len(W)):
                                if Y[i] == c:
                                        fxwc = self.sigmoid_XW(X[i],W[c])
                                        for f in range(len(X[i])):
                                                W[c][f] = W[c][f] - (self.lr * (-1)* (G[Y[i]])*(1-G[Y[i]]) * X[i][f])
                return W, (loss*1000)


        def custom_split_datasets(datasets):
                testRate = int(len(datasets.data) / 10)
                for i in len(datasets.data[x]):
                        pass

def main():
        epoch = int(sys.argv[1])
        ml = model(lr=0.001)

        
        datasets = load_digits()
        #X = sklearn.model_selection.train_test_split(datasets.data)
        #Y = sklearn.model_selection.train_test_split(datasets.target)

        trainX, testX, trainY, testY = train_test_split(datasets.data,datasets.target,test_size=0.25)

        W_train1 = np.zeros((max(datasets.target)+1, len(trainX[0]))) + 0.07
        W_train2 = np.zeros((max(datasets.target)+1, len(trainX[0]))) + 0.07

#print(trainX,trainY,W_train1)
        for i in range(epoch):
                W_train1, LOSS  = ml.train1(trainX,trainY,W_train1)
                W_train2, LOSS2 = ml.train2(trainX,trainY,W_train2)

                train_Acc = ml.accuracy(trainX,trainY,W_train1)
                train_Acc2= ml.accuracy(trainX,trainY,W_train2)

                test_Acc  = ml.accuracy(testX,testY,W_train1)
                test_Acc2 = ml.accuracy(testX,testY,W_train2)
                print(i,'PER LOSS(delta model) = ', LOSS,'Train ACC = ',len(trainX),'/',train_Acc,'Test Acc = ',len(testX),'/',test_Acc)
                print(i,'PER LOSS(just  model) = ', LOSS2,'Train ACC = ',len(trainX),'/',train_Acc2,'Test Acc = ',len(testX),'/',test_Acc2)


                plt.figure(num="Model 1 LOSS")
                plt.scatter(i,LOSS,label='loss1',color='r', marker='o')
                plt.figure(num= "Model 1 Train Acc")
                plt.scatter(i,train_Acc,label='trainacc',color='r',marker='o')
                plt.figure(num="Model 1 Test Acc")
                plt.scatter(i,test_Acc,label='testacc',color='r',marker='s')
                plt.figure(num="Model 2 LOSS")
                plt.scatter(i,LOSS2,label='loss2',color='b',marker='o')
                plt.figure(num="Model 2 Train Acc")
                plt.scatter(i,train_Acc2,label='ttrainacc',color='b',marker='o')
                plt.figure(num="Model 2 Test Acc")
                plt.scatter(i,test_Acc2,label='testacc',color='b',marker='o')


            
        plt.show()

        f = open("multiway_model_1.txt",'w')
        f2 = opne("multiway_model_2.txt",'w')

        f.write(str(W_train1))
        f.write(str(W_train2))


if __name__ == "__main__":
        main()
