Implementasi Jaringan Syaraf Tiruan MLP Dengan Algoritma Belajar Propagasi Balik

Jaringan Syaraf Tiruan — Multi Layer Perceptron

JST_MLP_latih.m

%===========================================================================
% Program pelatihan propagasi balik untuk melatih MLP
% Variable yang dapat diupdate
%	1. JHneuron
%	2. LR (Learning Rate)
%	3. Epoch
%	4. MaxMSE
%===========================================================================

clc
clear

P = ...
	[3 3 2;	% P1
	 3 2 2; % P2
	 3 2 1; % P3
	 3 1 1; % P4
	 2 3 2; % P5
	 2 2 2; % P6
	 2 2 1; % P7
	 2 1 1; % P8
	 1 3 2; % P9
	 1 2 1; % P10
	 1 1 2];% P11

T = ...
	[1;
	 1;
 	 1;
	 0;
	 1;
	 1;
 	 1;
	 0;
	 1;
	 0;
	 1];

JumPola  = length(P(:,1));	% Jumlah semua pola latih (11)
DimPola  = length(P(1,:));	% Dimensi pola latih (3)
JOneuron = length(T(1,:));	% Jumlah neurons pada Output layer (1)

JHneuron = 5;			% Jumlah neurons pada Hidden layer
LR       = 0.1;			% Learning Rate
Epoch	 = 5000;		% Maksimum iterasi
MaxMSE	 = 10^-5;		% Maksimum MSE

%--------------------------------------------------------------------------
% Bangkitkan Weights antara Input layer dan Hidden layer secara acak
% dalam interval -1 sampai +1. Simpan sebagai W1.
%--------------------------------------------------------------------------
W1 = [];
for ii=1:JHneuron,
	W1 = [W1 ; (rand(1,Dimpola)*2-1)];
end
W1 = W1';

%--------------------------------------------------------------------------
% Bangkitkan Weights antara Hidden layer dan Output layer secara acak
% dalam interval -1 sampai +1. Simpan sebagai W2.
%--------------------------------------------------------------------------
W2 = [];
for jj=1:JOneuron,
	W2 = [W2 ; (rand(1,JHneuron)*2-1)];
end
W2 = W2';

MSEepoch = MaxMSE + 1;	% Mean Square Error untuk 1 epoch
MSE 	 = [];		% List MSE untuk seluruh epoch
ee	 = 1;		% Index Epoch

While (ee <= Epoch) & (MSEepoch > MaxMSE)
	MSEepoch = 0;
	for pp=1:JumPola,
		CP = P(pp,:);	% Current Pattern
		CT = T(pp,:);	% Current Target 

		%-----------------------------------------------------------
		% Perhitungan Maju untuk mendapatkan Output, Error, dan MSE
		%-----------------------------------------------------------
		A1=[];
		for ii=1:JHneuron,
			v  = CP*W1(:,ii);
			A1 = [A1 1/(1+exp(-v))];
		end
		A2=[];
		for jj=1:JOneuron,
			v  = A1*W2(:,jj);
			A2 = [A2 1/(1+exp(-v))];
		end
		Error = CT - A2;

		for kk=1:length(Error),
			MSEepoch = MSEepoch + Error(kk)^2;
		end
		%-----------------------------------------------------------
		% Perhitungan Mundur untuk meng-update W1 dan W2
		%-----------------------------------------------------------
		for kk=1:JOneuron,
			D2(kk) = A2(kk) * (1-A2(kk)) * Error(kk);
		end
		dW2 = [];
		for jj=1:JHneuron,
			for kk=1:JOneuron,
				delta2(kk) = LR * D2(kk) * A1(jj);
			end
			dW2 = [dW2 ; delta2];
		end
		for jj=1:JHneuron,
			D1(jj) = A1 * (1-A1)' * D2 * W2(jj,:)';
		end
		dW1 = [];
		for ii=1:DimPola,
			for jj=1:JHneuron,
				delta1(jj) = LR * D1(jj) * CP(ii);
			end
			dW1 = [dW1 ; delta1];
		end
		W1 = W1 + dW1;	% W1 baru
		W2 = W2 + dW2;	% W2 baru
	end
	MSE = [MSE (MSEepoch/JumPola)];
	ee  = ee + 1;
end

plot(MSE);
xlabel('Epoch')
ylabel('MSE')

save TResult.mat W1 W2 MSE JHneuron JOneuron LR

JST_MLP_uji.m

%==========================================================================
% Program Pengujian MLP
%==========================================================================

clc
clear

%--------------------------------------------------------------------------
% Load hasil pelatihan dari file TResult.mat
% TResult.mat berisi: W1, W2, MSE, JHneuron, JOneuron, LR
%--------------------------------------------------------------------------
load TResult.mat

TestSet = ...
	[3 3 1;
	 3 1 2;
	 2 3 1;
	 2 1 2;
	 1 3 1;
	 1 2 2;
	 1 1 1];

TestKelas = [0 1 0 1 0 1 0];

JumPola = length(TestSet(:,1));
JumBenar = 0;
for pp=1:JumPola,
	CP = TestSet(pp,:);
	A1 = [];
	for ii=1:JHneuron,
		v  = CP*W1(:,ii);
		A1 = [A1 1/(1+exp(-v))];
	end
	A2 = [];
	for jj=1:JOneuron,
		v  = A1*W2(:,jj);
		A2 = [A2 1/(1+exp(-v))];
	end

	%----------------------------------------
	% Pemetaan A2 menjadi kelas keputusan
	% Jika A2 < 0.5 maka Kelas = 0
	%----------------------------------------
	for jj=1:JOneuron,
		if A2(jj) < 0.5,
			Kelas = 0;
		else
			Kelas = 1;
		end
	end

	if Kelas==TestKelas(pp),
		JumBenar = JumBenar + 1;
	end
end

display(['Akurasi JST = ' num2str(JumBenar/JumPola)]);

Terdapat empat parameter JST yang sangat penting dan sensitif pada proses pelatihan, yaitu: jumlah neuron pada hidden layer, learning rate, jumlah iterasi, dan batasan error.

Sampai saat ini, belum ada formula khusus yang bisa menemukan jumlah neuron pada hidden layer yang optimal. Suatu formula yang bisa digunakan untuk memperkirakan jumlah neuron pada hidden layer adalah

di mana Nh adalah jumlah neuron pada hidden layerNi jumlah node pada input layer (jumlah variabel pola masukan), dan No adalah jumlah neuron pada output layer. Pada kasus di atas, Ni = 3 dan N0 = 1. Oleh karena itu 
(pembulatan ke atas). Tetapi, hasil dari formula di atas hanya bersifat perkiraan. Jumlah neuron

pada hidden layer yang optimal bisa lebih atau kurang dari hasil perhitungan tersebut.

Parameter learning rate sangat mempengaruhi proses pelatihan. Learning rate yang terlalu besar (misalkan 0,9) akan mengakibatkan MSE menurun tajam pada awal iterasi, tetapi akan mengakibatkan MSE menjadi berosilasi atau naik turun tidak terkendali. Sebaliknya, learning rate yang terlalu kecil (misalkan 0,0001) akan mengakibatkan MSE menurun sangat pelan.

Berikut adalah hasil translete dari matlab ke C dari program di atas dengan compiler CodeVisionAVR. Masih banyak bagian yang belum rapi, tapi program ini sudah diuji di Proteus dengan input yang langsung dimasukan ke program dan output berupa indikator LED.

latih_ann.c

/*****************************************************
Chip type               : ATmega128
Program type            : Application
AVR Core Clock frequency: 16.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 1024
*****************************************************/

#include <mega128.h>
#include <stdlib.h>
#include <math.h>

// Declare your global variables here
unsigned int P[4][10] = {{0,  1,  2,  3,  4,  5,  6,  7,  8,  9},
                         {1,  2,  3,  4,  5,  6,  7,  8,  9, 10},
                         {8,  8,  9,  2,  4,  6,  4,  8,  8,  3},  
                         {8, 96, 45,  2,  4, 46, 85,  1,  8, 10}};
float T[4][1] = {{  1},
                 {  1},
                 {  0},
                 {  0},};

unsigned int JumPola = 4;
unsigned int DimPola = 10;
unsigned int JOneuron = 1;

unsigned int JHneuron = 10;
float LR = 0.1;
unsigned int Epoch = 3000;
float MaxMSE = 0.00001;
float MSEepoch;
unsigned int ee;
float MSE;

float W1[10][10];
float buff_W1_W2[10][10];
float v;
float W2[10][10];   
unsigned int CP[10];
unsigned char CT[4][1];
float A1[1][10];
float A2[1][1];
float Error[1];
float D2[1];
float dW2[10][1];
float delta2[1];
float buff_A1_x_1_min_A1[10][1];
float D1[10];
float delta1[10];
float dW1[10][10];

unsigned int ii,zz,pp,jj,kk,yy;                  

void main(void)
{  
//%=================================================================
//%bangkitkan weight antara input layer dan hidden layer secara acak
//%dalam interval -1 sampai +1. simpan sebagai w1
//%=================================================================
//W1 = [];
//for ii = 1:JHneuron,
for(ii=0;ii<JHneuron;ii++){
    //W1 = [W1 ; (rand(1,DimPola)*2-1)];
    for(zz=0;zz<JHneuron;zz++){
        W1[ii][zz] = (((rand()/32767)*2)-1);
    };
//end
};
//W1 = W1';
for(ii=0;ii<JHneuron;ii++){
    for(zz=0;zz<JHneuron;zz++){
        buff_W1_W2[ii][zz] = W1[ii][zz];
    };
};    
for(ii=0;ii<JHneuron;ii++){
    for(zz=0;zz<JHneuron;zz++){
        W1[ii][zz] = buff_W1_W2[zz][ii];
    };
};
//%=================================================================
//%bangkitkan weight antara hidden layer dan output layer secara acak
//%dalam interval -1 sampai +1. simpan sebagai w2
//%=================================================================
//W2 = [];
//for jj = 1:JOneuron,
for(ii=0;ii<JOneuron;ii++){
    //W2 = [W2 ; (rand(1,JHneuron)*2-1)];
    for(zz=0;zz<JHneuron;zz++){
        W2[ii][zz] = (((rand()/32767)*2)-1);
    };
//end
};
//clear buff
for(ii=0;ii<JHneuron;ii++){
    for(zz=0;zz<JHneuron;zz++){
        buff_W1_W2[ii][zz] = 0;
    };
};
//W2 = W2';
for(ii=0;ii<JHneuron;ii++){
    for(zz=0;zz<JHneuron;zz++){
        buff_W1_W2[ii][zz] = W2[ii][zz];
    };
};    
for(ii=0;ii<JHneuron;ii++){
    for(zz=0;zz<JHneuron;zz++){
        W2[ii][zz] = buff_W1_W2[zz][ii];
    };
};

//MSEepoch = MaxMSE + 1; %mean square error untuk 1 epoch
MSEepoch = MaxMSE + 1;
//MSE      = [];         %list MSE untuk seluruh epoch
//ee       = 1;          % index epoch
ee = 1;

//while (ee <= Epoch) & (MSEepoch > MaxMSE)
while((ee <= Epoch) & (MSEepoch > MaxMSE)){
    //MSEepoch = 0;                       
    MSEepoch = 0;
    //for pp=1:JumPola,
    for(pp = 0;pp < JumPola;pp++){
        //CP = P(pp,:);%current pattern
        for(zz = 0; zz < DimPola;zz++){
            CP[zz] = P[pp][zz];
        };
        //CT = T(pp,:);%current target
        for(zz = 0; zz < JOneuron;zz++){
            CT[zz][0] = T[pp][zz];
        };
        //%=========================================================
        //%perhitungan maju untuk mendapatkan output, error, dan MSE
        //%=========================================================
        //A1 = [];
        //for ii=1:JHneuron,  
        for(ii = 0;ii < JHneuron;ii++){
            //v = CP*W1(:,ii);
            for(zz = 0;zz < DimPola;zz++){
                v += CP[zz]*W1[zz][ii];
            };
            //A1= [A1 1/(1+exp(-v))];
            A1[0][ii] = 1/(1+exp(-v));
        //end                      
        };
        //A2 = [];
        //for jj=1:JOneuron,
        for(jj = 0;jj < JOneuron;jj++){
            //v = A1*W2(:,jj);         
            for(zz = 0;zz < DimPola;zz++){
                v += A1[0][zz]*W1[zz][jj];
            };
            //A2= [A2 1/(1+exp(-v))];  
            A2[0][jj] = 1/(1+exp(-v));
        //end      
        };

        //Error = CT - A2;  
        Error[JOneuron] = CT[pp][0] - A2[0][pp];

        //for kk=1:length(Error),
        for(kk = 0;kk < JOneuron;kk++){
            //MSEepoch = MSEepoch + Error(kk)^2;    
            MSEepoch += (Error[kk] * Error[kk]);
        //end   
        };
        //%========================================================
        //%perhitungan mundur untuk mengupdate W1 dan W2
        //%========================================================
        //for kk=1:JOneuron,
        for(kk = 0;kk < JOneuron;kk++){
            //D2(kk) = A2(kk) * (1-A2(kk)) * Error(kk);
            D2[kk] = A2[0][kk] * (1 - A2[0][kk]) * Error[kk];  
        //end
        };
        //dW2 = [];
        //for jj=1:JHneuron,
        for(jj = 0;jj < JHneuron;jj++){
            //for kk=1:JOneuron,       
            for(kk = 0;kk < JOneuron;kk++){
                //delta2(kk) = LR * D2(kk) * A1(jj);  
                delta2[kk] = LR * D2[kk] * A1[0][jj];
            //end                        
            };
            //dW2 = [dW2 ; delta2];   
            dW2[jj][0] = delta2[kk];
        //end          
        };
        //for jj=1:JHneuron,  
        for(jj = 0;jj < JHneuron;jj++){
            //D1(jj) = A1 * (1 - A1)' * D2 * W2(jj,:)';   
            for(zz = 0;zz < JHneuron;zz++){
                buff_A1_x_1_min_A1[zz][0] = A1[0][zz] * (1 - A1[0][zz]);   
            }
            D1[jj] = buff_A1_x_1_min_A1[zz][0] * D2[0] * W2[jj][0];
        //end                                                      
        };
        //dW1 = [];
        //for ii=1:DimPola,    
        for(ii = 0;ii < DimPola;ii++){
            //for jj=1:JHneuron,      
            for(jj = 0;jj < JHneuron;jj++){
                //delta1(jj) = LR * D1(jj) * CP(ii);
                delta1[jj] = LR * D1[jj] * CP[ii];
            //end
            };
            //dW1 = [dW1 ; delta1];  
            for(zz = 0;zz < JHneuron;zz++){
                dW1[ii][zz] = delta1[zz];
            };
        //end
        };
        //W1 = W1 + dW1; %W1 baru
        for(zz = 0;zz < DimPola;zz++){
            for(yy = 0;yy < JHneuron;yy++){
                W1[zz][yy] = W1[zz][yy] + dW1[zz][yy];
            };
        };
        //W2 = W2 + dW2; %W2 baru  
        for(zz = 0;zz < DimPola;zz++){
            for(yy = 0;yy < JOneuron;yy++){
                W2[zz][yy] = W2[zz][yy] + dW2[zz][yy];
            };
        };
    //end
    };
    //MSE = [MSE (MSEepoch/JumPola)];
    MSE = MSEepoch/JumPola;
    //ee  = ee + 1;
    ee++;
//end
};
}

test_ann.c

/*****************************************************
Chip type           : ATmega128
Program type        : Application
Clock frequency     : 16.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 1024
*****************************************************/

#include <mega128.h>
#include <math.h>

// Declare your global variables here
unsigned int TesSet[8]={23,24,25,26,27,28,29,30};
unsigned int CP[8];
unsigned int JHneuron = 8;
float v=0;
#define kelas PORTD.0

float W1[8][8]={{-0.5436, 3.8131,-2.0942, 5.5744,-0.2889,-1.2805,-2.9973,-0.4719},
                {-0.5400, 2.5768,-0.1297, 2.3796,-0.2162,-1.0229,-1.1098, 0.2465},
                { 0.1184,-0.4468, 0.6708, 1.2405,-0.5845, 0.1500,-1.0362,-0.8866},
                {-0.7803, 0.6688, 0.7684, 1.0272, 0.5367,-0.2415,-1.3290,-0.2518},
                {-0.0755,-1.7030, 0.6663,-1.6317, 0.6187,-0.3961, 0.9027, 0.2113},
                { 1.0212,-1.9523, 0.1720,-2.6066, 0.0614, 0.1280, 1.7961, 0.3288},
                { 0.6470,-1.6387, 0.1937,-2.5914,-0.0646, 0.3553, 0.0972, 0.3129},
                { 0.4651,-1.3959,-0.1673,-3.6910, 1.0975, 0.2295, 0.8755,-0.9508}};  

float W2[8]=    {0.8706,
                -2.4592,
                 1.2231,
                -2.6395,
                 0.3586,
                 0.4804,
                 1.9120,
                -0.0382};  
float A2;
float A1[8];

void main(void)
{
// Declare your local variables here
unsigned int i,j;
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0xFF;

// Port E initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTE=0x00;
DDRE=0x00;

// Port F initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTF=0x00;
DDRF=0x00;

// Port G initialization
// Func4=In Func3=In Func2=In Func1=In Func0=In
// State4=T State3=T State2=T State1=T State0=T
PORTG=0x00;
DDRG=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer 3 Stopped
// Mode: Normal top=FFFFh
// Noise Canceler: Off
// Input Capture on Falling Edge
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
// Timer 3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR3A=0x00;
TCCR3B=0x00;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// INT3: Off
// INT4: Off
// INT5: Off
// INT6: Off
// INT7: Off
EICRA=0x00;
EICRB=0x00;
EIMSK=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
ETIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

while (1)
      {
      // Place your code here
        //%========================================================
        //%load hasil pelatihan dari file TResult.mat
        //%Tresult.mat berisi : W1, W2, MSE, JHneuron, JOneuron, LR
        //%========================================================
        //load UTSTResultMesinChar.mat

        //W1
        //W2
        //JHneuron
        //JOneuron
        //LR

        //TestSet = ...
        //[8 6 4 7 9 7 9 0]; %P1      
        //TestKelas = [1];
        //JumPola = length(TestSet(:,1));
        //JumBenar = 0;
        //for pp=1:JumPola,
                //CP = TestSet(pp,:)
                for(i=0;i<8;i++)
                {
                        CP[i]=TesSet[i];
                }  
                //A1 = [];
                //for ii=1:JHneuron,
                for(i=0;i<JHneuron;i++)
                {
                        //v = CP*W1(:,ii);
                        for(j=0;j<8;j++)
                        {
                                v = v + (float)CP[j]*W1[j][i];
                        }
                        //A1= [A1 1/(1+exp(-v))];
                        A1[i] = 1/(1+exp(-v));
                //end   
                }
                //A2 = [];
                //for jj=1:JOneuron,    
                v=0;
                        //v = A1*W2(:,jj);
                        for(j=0;j<8;j++)
                        {
                                v = v + (float)CP[j]*W2[j];
                        }
                        //A2= [A2 1/(1+exp(-v))];
                        A2 = 1/(1+exp(-v));
                //end    

                //%===================================================
                //%pemetaan A2 menjadi kelas keputusan
                //%jika A2 < 0.5 maka kelas = 0
                //%===================================================
                //for jj=1:JOneuron,
                //if A2(jj) < 0.5,  
                if(A2 < 0.5)
                {
                        //Kelas = 0;
                        kelas = 0;
                }
                //else
                else    
                {
                        //Kelas = 1;  
                        kelas = 1;
                //end               
                }
        //end

        //if Kelas == 1
        //JumBenar = JumBenar + 1;
        //end
        //end
        //display(['akurasi JST = ' num2str((JumBenar*100)/JumPola)]);  
      };
}

________________________________

Sumber : 

Suyanto. 2007.“Artificial Intelegent; Searching, Reasoning, Planing, and Learning”. Penerbit Informatika. Bandung

4 Responses to Implementasi Jaringan Syaraf Tiruan MLP Dengan Algoritma Belajar Propagasi Balik

  1. ahmad arif says:

    mas aq mau nanya jika aq hanya menggunakan 2 buah input neuron, 3 hidden neuron dan 3 output neuron dimana 3 output itu mrpk kp,ki,dan kd, proses learningnya di cvavr gmn mas? trus apa aja yang harus dipersiapkan sebelum learning mas datanya

    • wangready says:

      sya jg masih awam sama JST, setau saya program yg saya buat outputnya berupa logic 0 atau 1, kalau ada tiga konstanta dan tiap konstanta 8bit maka ada 24 output…kalau sistem learningnya sya pake sample positif dan negatif yg jumlahnya sama, kalau PID sya jg bingung gimana cara mencari samplenya, atau mungkin bisa berdasarkan uji coba dan pengalaman user atau data eksperimen… (sok tau mode on)🙂

  2. latief says:

    gan, mau tanya, statement yang While (ee MaxMSE) kok pas mau di run di matlab gak bisa ya?

    • wangready says:

      gk bisanya gmana gan? errornya apa? klo gk ditrace aja gan siapa tahu ada salah ketik atau ketik ulang manual, saya juga dulu pernah gitu gara2 salah karakternya…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s