SunTaag  
Front Page
Tag | Location | Media | Guestbook | Admin   
 
'Algorithm'에 해당하는 글(3)
2018.07.26   Online Algorithm for Basic Statistical Formula
2018.07.25   Fast Fourier Transform의 이해
2018.07.25   Sunrise, Sunset Time Calculation Algorithm in Java


Online Algorithm for Basic Statistical Formula

는 자연수이고,

일 때,


산술 평균:

산술 분산:


이 때,

라면,

새로운 산술 평균:

즉, 새로운 입력 값이 하나 더 추가되면 기존의 평균값과 집합에 포함된 원소의 개수를 알아야한다.

새로운 산술 분산:

새로운 산술 분산에서는 기존 평균값, 기존 제곱의 평균값, 집합에 포함된 원소의 개수가 필요하다.



조금이라도 연산을 줄이려면 아래와 같이 평균이 아니라 합(Summation)을 알고 있으면 연산이 조금 더 편해진다.

수식적으로는 큰 차이가 없어 보이나

코드로 구현하면 메모리 효율을 극대화 할 수 있다.

아래 예제는 새로운 값이 들어올 때마다 실시간으로 평균과 표준 편차를 구한다.

N(원소의 개수), sum(합), ssum(제곱합)은 Global Variable

새로운 입력 x가 들어오면 N, sum, ssum 갱신

 N++;

 sum += x;

 ssum += x*x;

N, sum, ssum을 이용하여 평균과 분산 값 계산(갱신)

 Ex = sum/N;

 Vx = ssum/N - Ex*Ex;




'Algorithm' 카테고리의 다른 글

Fast Fourier Transform의 이해  (0) 2018.07.25
Sunrise, Sunset Time Calculation Algorithm in Java  (0) 2018.07.25


Fast Fourier Transform의 이해

01234567891011121314151617181920212223242526272829303132333435






Sunrise, Sunset Time Calculation Algorithm in Java

package SunshineCalculateForPhone;


public class SunshineCalculator {


final static double PHI = Math.PI;

final static double TWO_PHI = 2 * PHI;

final static double SUN_DIAMETER = 0.53;

final static double AIR_REF = (34.0 / 60.0);


private static int sunRise_hour;

private static int sunRise_minute;

private static int sunSet_hour;

private static int sunSet_minute;

private static double tmp_longitude;

private static int tmp_hour;

private static int tmp_minute;


// Get the days to J2000

// h is UT in decimal hours

// getJulianDay only works between 1901 to 2099

// 이 함수는 J2000 1월 1일 12시 DT를 기준으로 날수(Day Number)를 구합니다.

// 입력값은 년,월,일,시간(실수값)입니다.

private static double getJulianDay(int year, int month, int day) {

double temp = -7.0f * ((double) year + ((double) month + 9.0f) / 12.0f)

/ 4.0f + 275.0f * (double) month / 9.0f + (double) day;

// type casting necessary on PC DOS and TClite to avoid overflow

temp += (double) (year * 367);

return (temp - 730531.5f + 12.0f / 24.0f);

}


// the function below returns an angle in the range

// 0 to 2*pi

// 들어온 값을 항상 0~2pi 값안으로 normalize시킵니다.

private static double getRangeRadian(double x) {

double b = x / TWO_PHI;

double a = TWO_PHI * (b - (long) (b));

if (a < 0)

a = TWO_PHI + a;

return a;

}


// Calculating the hourangle

// 시간각을 계산합니다.

// lat:위도 declin:적위

private static double getHourAngle(double lat, double declin) {

double fo, dfo;

// Correction: different sign at S HS

dfo = PHI / 180.0 * (0.5 * SUN_DIAMETER + AIR_REF);

if (lat < 0.0)

dfo = -dfo;

fo = Math.tan(declin + dfo) * Math.tan(lat * PHI / 180.0);

if (fo > 0.99999)

fo = 1.0; // to avoid overflow //

fo = Math.asin(fo) + PHI / 2.0;

return fo;

}


// Find the ecliptic longitude of the Sun

// 태양의 황경을 구합니다.

private static double getSunLongitude(double days) {

double g;

// mean longitude of the Sun (태양의 평균 황경)

tmp_longitude = getRangeRadian(280.461 * PHI / 180.0 + .9856474 * PHI

/ 180.0 * days);

// mean anomaly of the Sun (태양의 평균근점이각)

g = getRangeRadian(357.528 * PHI / 180.0 + .9856003 * PHI / 180.0

* days);

// Ecliptic longitude of the Sun (태양의 황경계산)

return getRangeRadian(tmp_longitude + 1.915 * PHI / 180.0 * Math.sin(g)

+ .02 * PHI / 180.0 * Math.sin(2 * g));

}


private static void convertDtime2Rtime(double dHour) {

tmp_hour = (int) dHour;

tmp_minute = (int) ((dHour - (double) tmp_hour) * 60);

}


private static boolean detectCurrentInDayTime(int year, int month, int day,

int hour, int minute, double latitude, double longitude) {

double tzone;

double lambda, obliq;

double alpha, delta;

double LL, days;

double equation, ha, sunRiseTime, sunSetTime;

int dSunRiseT, dSunSetT, dNowT;


// 관측장소의 경도(단위 degree),위도(단위 degree),타임존(단위시간) 값을 입력받습니다.

/*

* year = 2011; month = 1; day = 1; latitude = 37.279198; //한국내 임의 위치의

* 위도 입력 longitude = 127.044032; //한국내 임의 위치의 경도 입력

*/

tzone = 9.0f; // 한국은 Time Zone이 +9 임


days = getJulianDay(year, month, day);

// 태양의 황경

lambda = getSunLongitude(days);

// Obliquity of the ecliptic (s황도기울기 계산)

obliq = 23.439 * PHI / 180.0 - .0000004 * PHI / 180.0 * days;

// Find the RA and DEC of the Sun (태양의 적경,적위 계산)

alpha = Math.atan2(Math.cos(obliq) * Math.sin(lambda),

Math.cos(lambda)); // 태양의 적경

delta = Math.asin(Math.sin(obliq) * Math.sin(lambda)); // 태양의 적위

// Find the Equation of Time in minutes

// Correction suggested by David Smith

// 균시차 계산

LL = tmp_longitude - alpha;

if (tmp_longitude < PHI)

LL += TWO_PHI;

equation = 1440.0 * (1.0 - LL / TWO_PHI);

ha = getHourAngle(latitude, delta);

sunRiseTime = 12.0 - 12.0 * ha / PHI + tzone - longitude / 15.0

+ equation / 60.0;

sunSetTime = 12.0 + 12.0 * ha / PHI + tzone - longitude / 15.0

+ equation / 60.0;


if (sunRiseTime > 24.0)

sunRiseTime -= 24.0;

if (sunSetTime > 24.0)

sunSetTime -= 24.0;


convertDtime2Rtime(sunRiseTime);

sunRise_hour = tmp_hour;

sunRise_minute = tmp_minute;

convertDtime2Rtime(sunSetTime);

sunSet_hour = tmp_hour;

sunSet_minute = tmp_minute;


// hour = 16; minute = 12; //임의의 Local Time을 설정하여 테스트

/*

* System.out.printf("Now Time: %d:%d\n",hour,minute);

* System.out.printf("Sunrise: %d:%d\n",sunRise_hour,sunRise_minute);

* System.out.printf("Sunrise: %d:%d\n",sunSet_hour,sunSet_minute);

*/

dNowT = hour * 60 + minute;

dSunRiseT = sunRise_hour * 60 + sunRise_minute;

dSunSetT = sunSet_hour * 60 + sunSet_minute;


if (dNowT <= dSunRiseT || dNowT >= dSunSetT) {

// System.out.printf("Night\n");

return false;

} else {

// System.out.printf("Day\n");

return true;

}

}


public static boolean detectSunshine(int year, int month, int day,

int hour, int minute, double latitude, double longitude,

double accuracy) {


if (accuracy > 50.0)

return false; // Indoor


// Outdoor, Check State of Sun in Input Time and Location

boolean isCIDT = false;

isCIDT = SunshineCalculator.detectCurrentInDayTime(year, month, day,

hour, minute, latitude, longitude);


return isCIDT;

}


public static void main(String[] args) {

int year = 2018;

int month = 7;

int day = 25;

int hour = 17;

int minute = 13;

double latitude = 37.279198;

double longitude = 127.044032;

double accuracy = 20.4718;

boolean isSun = false;


isSun = SunshineCalculator.detectSunshine(year, month, day, hour,

minute, latitude, longitude, accuracy);

System.out.println(isSun);

}


}



'Algorithm' 카테고리의 다른 글

Online Algorithm for Basic Statistical Formula  (0) 2018.07.26
Fast Fourier Transform의 이해  (0) 2018.07.25


BLOG main image
 Notice
 Category
분류 전체보기 (20)
Algorithm (3)
Signal Processing (0)
Programming (6)
Research (1)
Youtube (2)
ETC. (8)
 TAGS
 Calendar
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
 Recent Entries
 Recent Comments
 Archive
 Link Site
 Visitor Statistics
Total :
Today :
Yesterday :
rss