끝에 클래스 정의 사용 방법 나는 JSL 클래스 인스턴스가 복사하기 어렵다는 흥미로운 점을 암시했습니다. X가 인스턴스를 참조하는 경우 Y=X는 Y와 X를 모두 만듭니다. 나타내다 ~로 같은 사례. 사용자 정의 함수에 인스턴스를 전달할 때도 같은 일이 발생합니다. 함수의 값은 다음과 같습니다. ~ 아니다 인스턴스 사본 그것 참조 ~로 같은 사례. 따라서 함수 내에서 인스턴스를 변경하면 호출자에 대해서도 변경됩니다. 함수에 행렬을 전달하고 함수에서 수정한 적이 있다면 호출자의 복사 업데이트하려면 JSL이 값으로 사용자 함수에 인수를 전달한다는 것을 알고 있습니다.
JMP passes arguments by making copies, but...JMP passes arguments by making copies, but...JMP passes arguments by making copies, but...JMP passes arguments by making copies, but...JMP는 사본을 만들어 논쟁을 통과시키지만...
행렬이 복사되었으므로 함수 내부의 행렬에 대한 변경 사항은 원본이 아닌 복사본에 적용됩니다. 큰 검은색 참조 점도 복사되지만 참조하는 개체는 복사되지 않습니다. 이것은 초심자 JAVA 프로그래머가 이 그림을 본 적이 없기 때문에 많은 골칫거리를 야기합니다. 함수 내에서 변수에 대해 두 가지 매우 다른 작업을 수행할 수 있습니다. ㅏ .
- a:set(42)와 같은 메서드를 호출할 수 있습니다.
- a=42와 같이 값을 할당할 수 있습니다.
(1)의 경우 아가일 객체의 값은 3에서 42까지입니다. 이것은 아마도 당신이 의미하는 것입니다. (2)의 경우 옆에 있는 큰 검은 점을 덮어씁니다. ㅏ 42. 아마 그럴 의도가 아니었을 겁니다.
다음 코드는 다른 개체에 대한 참조를 유지하는 개체를 사용합니다. 모든 개체에는 next() 메서드가 있으므로 개체를 흥미로운 방식으로 구성할 수 있습니다. next() 메서드는 일련의 값에서 다음 값을 생성합니다. 일부 개체는 상수를 나타내며 항상 동일한 다음 값을 생성합니다. 추가 개체와 같은 다른 개체에는 두 개의 다른 개체(+ 연산자의 왼쪽과 오른쪽)가 있습니다. Add:next()는 left:next()와 right:next()를 호출하고 두 답변을 추가합니다.
전체 JSL이 첨부되어 있습니다. 여기 사진이 인터리브되어 있습니다. 가장 간단한 클래스부터 시작하겠습니다.
// number/matrix wrapper class
Define Class(
"vwrap",
m_v = .; // holds the number or matrix
_init_ = Method( {v},
If( Type( v ) == "Class",
Throw( "vwrap is for number or matrix, not class " || Char( v << getname ) )
);
m_v = v;
);
set = Method( {v},
If( Type( v ) == "Class",
Throw( "vwrap is for number or matrix, not class " || Char( v << getname ) )
);
m_v = v;
);
next = Method( {},
m_v; // return
);
);Vwrap은 클래스의 이름이며 숫자 또는 행렬 값을 래핑합니다. 인식하지 못하는 값을 거부하는 setter와 시퀀스의 다음 값을 반환하는 next()라는 getter가 있습니다. NewObject(Vwrap(42))를 작성하는 것이 조금 추하기 때문에 Vwraps를 만드는 도우미 함수도 만들어 봅시다.
// helper function v(...) converts a scalar or matrix to a vwrap, or returns an instance unchanged
v = Function( {x},
If( Type( x ) == "Class",
If( !(x << Contains( "next" )),
Throw( "v expects number, matrix, or one of the classes it supports, not class " || (x << getname) )
);
x; // x supports a next function, it is probably OK
, // else
If( !Is Number( x ) & !Is Matrix( x ),
Throw( "v expects number or matrix, not " || Type( x ) )
);
New Object( vwrap( x ) ); // wrap the number or matrix
)
);v(...) 는 종종 클래스 인스턴스, 때로는 스칼라 또는 행렬과 함께 많이 호출되며 클래스 인스턴스를 가져오면 변경되지 않은 상태로 반환해야 합니다. 혼합될 수 있는 다른 클래스가 있는 경우를 대비하여 동시에 클래스에 next()가 있는지 확인할 수도 있습니다.
다음으로 크게 상용구 기능을 사용하여 그래프를 만듭니다.
// global function gr(...) makes a graph
gr = Function( {Xvar, Yvar, title, n},
{Xs, Ys, dt}, // locals
Yvar = v( Yvar );
Xvar = v( Xvar );
Ys = J( n, 1, Yvar:next() );
Xs = J( n, 1, Xvar:next() );
dt = As Table( Ys || Xs, <<INVISIBLE></INVISIBLE>X 및 Y 매개변수에 대한 v() 호출을 볼 수 있습니다. 래핑될 간단한 숫자이거나 next() 메서드가 있는 다른 클래스일 수 있습니다. 그런 다음 J() 함수는 N 값의 행렬을 만들고 보이지 않는 테이블을 만들고 더 이상 필요하지 않을 때 숨겨진 테이블을 닫는 약간의 마법으로 Graph Builder를 실행합니다. 해 보자.
gr( 13, 42, "Value 13,42", 1 );
A single point, at x=13, y=42A single point, at x=13, y=42A single point, at x=13, y=42A single point, at x=13, y=42단일 점, x=13, y=42
잠시만요, 나아질 겁니다... next()에 대한 연속 호출에서 0,1,2,3,...을 반환하는 카운터 클래스를 만들어 봅시다.
// counter class
Define Class(
"counter",
m_rate = .; // non zero increment
m_pos = empty(); // internal position
_init_ = Method( {rate},
m_rate = v( rate );
);
next = Method( {},
rate = m_rate:next();
// see peek() comment in "sin" class
If( Is Empty( m_pos ),
result = 0 * rate; // get scalar or matrix dimension on first call
m_pos = rate; // for next time
, // else
result = m_pos; // from last tim
m_pos += rate; // for next time
);
result; // return
);
);_init_ 메서드는 카운터가 증가하는 속도를 결정하는 속도를 사용합니다. 비율은 상수(일반적으로 1)이거나 다른 클래스 인스턴스일 수 있습니다. 다음은 카운터를 만드는 도우미 함수와 첫 번째 그래프입니다.
// global function to make a counter
ctr = Function( {rate = 1},
New Object( counter( rate ) )
);
gr( ctr(), ctr() , "count up A (equal steps)", 5 );두 개의 별도 카운터 인스턴스가 X축과 Y축에 대해 gr(...)에 전달되었음을 알 수 있습니다.
Two counters, running in parallel, for five steps starting at zero.Two counters, running in parallel, for five steps starting at zero.Two counters, running in parallel, for five steps starting at zero.Two counters, running in parallel, for five steps starting at zero.0에서 시작하는 5단계에 대해 병렬로 실행되는 두 개의 카운터.
이제 다른 것을 위해 카운터의 속도를 다른 카운터로 만들어 보겠습니다.
// this variation begins to show the power of composition
gr( ctr(), ctr( ctr() ), "count up B (first step is 0)", 5 );
The first step is zero because the rate counter's first result is zero.The first step is zero because the rate counter's first result is zero.The first step is zero because the rate counter's first result is zero.The first step is zero because the rate counter's first result is zero.속도 카운터의 첫 번째 결과가 0이므로 첫 번째 단계는 0입니다.
이 그래프의 Y축은 두 카운터의 기능 구성을 사용하고 있습니다. sin() 클래스를 추가하자.
// sin() wrapper class
Define Class(
"sin",
m_rate = .; // 0<STEP><PI. m_amp=".;"> Sin( m_pos += m_rate:next() ) // return
);
);</PI.></STEP>
Sin은 상수 또는 다른 클래스 인스턴스에 의해 결정되는 주파수 및 진폭에서 무한 사인파를 생성합니다. 또한 내부 위치를 유지합니다. 의견에서 더 많은 생각이 필요할 수 있음을 알 수 있지만 이 데모에서는 작동합니다. 다음은 단일 주기 파형입니다.
gr( ctr(), New Object( Sin( 2 * Pi() / 100, 3 ) ), "sin()", 101 );
Single cycle of sine waveSingle cycle of sine waveSingle cycle of sine waveSingle cycle of sine wave사인파의 단일 주기
다른 카운터가 증가하는 카운터와 유사하게 사인파는 가변 주파수를 가질 수 있습니다.
gr( ctr(), New Object( Sin( New Object( Sin( .0002, 1 ) ), 3 ) ), "variable frequency", 1000 );
Ramping up the frequency using the first bit of another sine waveRamping up the frequency using the first bit of another sine waveRamping up the frequency using the first bit of another sine waveRamping up the frequency using the first bit of another sine wave다른 사인파의 첫 번째 비트를 사용하여 주파수 증가
그리고 두 개의 서로 다른 주파수 사인파를 서로에 대해 플로팅할 수 있습니다.
gr( New Object( Sin( 4 * Pi() / 99, 3 ) ), New Object( Sin( 6 * Pi() / 99, 3 ) ), "2X3 sin()", 100 );
Simple integer ratios make nice patternsSimple integer ratios make nice patternsSimple integer ratios make nice patternsSimple integer ratios make nice patterns간단한 정수 비율로 멋진 패턴 만들기
또 다른 클래스 및 도우미 기능; 클래스는 하나 이상의 다른 클래스를 함께 추가하고 오프셋 도우미는 상수...또는 다른 함수를 추가합니다. 아마...테스트되지 않았을 것입니다.
// add class
Define Class(
"add",
m_a = {};
//m_b = .;
_init_ = Method( {a, b = Empty()},
If( Is Empty( b ),
For( i = 1, i <= N Items( a ), i += 1,
Insert Into( m_a, v( a[i] ) )
),
m_a[1] = v( a );
m_a[2] = v( b );
)
);
next = Method( {},
result = m_a[1]:next();
For( i = 2, i <= N Items( m_a ), i += 1,
result = result + m_a[i]:next()
);
result;
);
);
// helper function uses add to offset another value by off
offset = function({off,x},
newobject(add(off,x))
);오프셋 도우미를 사용하면 초기 0 단계가 있는 초기 그래프 중 하나를 초기 단계 1로 재작업할 수 있습니다.
// compared to a previous example, this one increments earlier
gr( ctr(), ctr( offset(1,ctr( 1 )) ), "count up C (first step is 1)", 5 );
Now all the steps are one bigger than before.Now all the steps are one bigger than before.Now all the steps are one bigger than before.Now all the steps are one bigger than before.이제 모든 단계가 이전보다 하나 더 커졌습니다.
// building a square wave by summing odd harmonics
n = 100;
basefreq = 2 * Pi() / n;
freq1 = New Object( Sin( 1 * basefreq, 1 / 1 ) );
freq2 = New Object( Sin( 3 * basefreq, 1 / 3 ) );
freq3 = New Object( Sin( 5 * basefreq, 1 / 5 ) );
freq4 = New Object( Sin( 7 * basefreq, 1 / 7 ) );
sum = New Object( Add( {freq1, freq2, freq3, freq4} ) );
gr( ctr(), sum, "4 Odd Harmonics", n + 1 );
Summing odd harmonics at reduced amplitude approximates a square wave.Summing odd harmonics at reduced amplitude approximates a square wave.Summing odd harmonics at reduced amplitude approximates a square wave.Summing odd harmonics at reduced amplitude approximates a square wave.감소된 진폭에서 홀수 고조파를 합하면 구형파에 가깝습니다.
// same square wave, a lot more odd harmonics
n = 200;
basefreq = 2 * Pi() / n;
freqs = {};
For( i = 1, i <= 23, i += 2,
Insert Into( freqs, New Object( Sin( i * basefreq, 1 / i ) ) )
);
gr( ctr(), New Object( Add( freqs ) ), "12 Odd Harmonics", n + 1 );
More harmonics help square it upMore harmonics help square it upMore harmonics help square it upMore harmonics help square it up더 많은 고조파가 균형을 잡는 데 도움이 됩니다.
// multiply class
Define Class(
"multiply",
m_a = {};
_init_ = Method( {a, b = Empty()},
If( Is Empty( b ),
For( i = 1, i <= N Items( a ), i += 1,
Insert Into( m_a, v( a[i] ) )
),
m_a[1] = v( a );
m_a[2] = v( b );
)
);
next = Method( {},
result = m_a[1]:next();
For( i = 2, i <= N Items( m_a ), i += 1,
result = result :*</img> m_a[i]:next()
);
result;
);
);
// multiply two waveforms
n = 1000;
freq1 = New Object( Sin( .1, 1 ) );
freq2 = New Object( Sin( 2 * Pi() / n, 1 ) );
prod = New Object( Multiply( freq1, freq2 ) );
gr( ctr(), prod, "multiply", n + 1 );
Multiply two frequencies; the lower frequency creates the envelope.Multiply two frequencies; the lower frequency creates the envelope.Multiply two frequencies; the lower frequency creates the envelope.Multiply two frequencies; the lower frequency creates the envelope.두 주파수를 곱하십시오. 더 낮은 주파수는 포락선을 생성합니다.
// similar, but control amplitude of freq1 using another sin wave
n = 1000;
freq2 = New Object( Sin( 2 * Pi() / n, 1 ) ); // lo freq
freq1 = New Object( Sin( .1, freq2 ) ); // hi freq, control amplitude with freq2
gr( ctr(), freq1, "amp is sin", n + 1 );
Alternatively, control the amplitude of the higher frequency using the lower frequency.Alternatively, control the amplitude of the higher frequency using the lower frequency.Alternatively, control the amplitude of the higher frequency using the lower frequency.Alternatively, control the amplitude of the higher frequency using the lower frequency.또는 낮은 주파수를 사용하여 높은 주파수의 진폭을 제어합니다.
마지막으로 홀수 고조파 주파수 행렬을 포함하는 vwrap을 만들고 행렬을 스칼라로 합산하는 새 클래스를 만듭니다.
// try a matrix...use v(...) to make a vwrap to hold the matrix
n = 200;
mat = v( ((1 :: 49 :: 2) * (2 * Pi() / n)) );
// add the sin wrapper. sinmat:next() returns a row vector of 5 sin values
sinmat = New Object( Sin( mat, 1 / (1 :: 49 :: 2) ) );
// matrixSum assumes the argument class is returning a matrix and returns the scalar sum
Define Class(
"matrixSum",
m_mat = .;
_init_ = Method( {mat},
m_mat = v( mat )
);
next = Method( {},
Sum( m_mat:next() )
);
);
gr( ctr(), New Object( matrixSum( sinmat ) ), "25 Odd Harmonics", n + 1 );
It will take a lot more harmonics to really reduce the over-shoot and the ripples.It will take a lot more harmonics to really reduce the over-shoot and the ripples.It will take a lot more harmonics to really reduce the over-shoot and the ripples.It will take a lot more harmonics to really reduce the over-shoot and the ripples.오버슈트와 잔물결을 실제로 줄이려면 훨씬 더 많은 고조파가 필요합니다.
좋은 문서: https://www.jmp.com/support/help/en/15.1/index.shtml#page/jmp/classes.shtml